前言

评论系统作为现代互联网应用的核心功能之一,直接影响着用户互动体验和内容生态建设。通过合理的评论系统架构设计和数据模型,能够构建一个高效、稳定、可扩展的评论系统,确保系统的稳定运行。本文从评论系统架构设计到数据模型,从基础实现到企业级应用,系统梳理评论系统设计的完整解决方案。

一、评论系统架构设计

1.1 评论系统整体架构

1.2 评论系统核心模块架构

二、评论系统数据模型设计

2.1 核心数据模型

2.1.1 评论实体模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/**
* 评论实体
*/
@Entity
@Table(name = "comments")
public class Comment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "content_id", nullable = false)
private Long contentId;

@Column(name = "user_id", nullable = false)
private Long userId;

@Column(name = "parent_id")
private Long parentId;

@Column(name = "content", nullable = false, length = 2000)
private String content;

@Column(name = "status", nullable = false)
@Enumerated(EnumType.STRING)
private CommentStatus status;

@Column(name = "like_count", nullable = false)
private Integer likeCount = 0;

@Column(name = "reply_count", nullable = false)
private Integer replyCount = 0;

@Column(name = "report_count", nullable = false)
private Integer reportCount = 0;

@Column(name = "is_deleted", nullable = false)
private Boolean isDeleted = false;

@Column(name = "created_time", nullable = false)
private LocalDateTime createdTime;

@Column(name = "updated_time", nullable = false)
private LocalDateTime updatedTime;

@Column(name = "ip_address")
private String ipAddress;

@Column(name = "user_agent")
private String userAgent;

// 构造函数
public Comment() {
this.createdTime = LocalDateTime.now();
this.updatedTime = LocalDateTime.now();
}

// Getter和Setter方法
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Long getContentId() {
return contentId;
}

public void setContentId(Long contentId) {
this.contentId = contentId;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}

public Long getParentId() {
return parentId;
}

public void setParentId(Long parentId) {
this.parentId = parentId;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public CommentStatus getStatus() {
return status;
}

public void setStatus(CommentStatus status) {
this.status = status;
}

public Integer getLikeCount() {
return likeCount;
}

public void setLikeCount(Integer likeCount) {
this.likeCount = likeCount;
}

public Integer getReplyCount() {
return replyCount;
}

public void setReplyCount(Integer replyCount) {
this.replyCount = replyCount;
}

public Integer getReportCount() {
return reportCount;
}

public void setReportCount(Integer reportCount) {
this.reportCount = reportCount;
}

public Boolean getIsDeleted() {
return isDeleted;
}

public void setIsDeleted(Boolean isDeleted) {
this.isDeleted = isDeleted;
}

public LocalDateTime getCreatedTime() {
return createdTime;
}

public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime;
}

public LocalDateTime getUpdatedTime() {
return updatedTime;
}

public void setUpdatedTime(LocalDateTime updatedTime) {
this.updatedTime = updatedTime;
}

public String getIpAddress() {
return ipAddress;
}

public void setIpAddress(String ipAddress) {
this.ipAddress = ipAddress;
}

public String getUserAgent() {
return userAgent;
}

public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
}

2.1.2 评论状态枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 评论状态枚举
*/
public enum CommentStatus {
PENDING("待审核"),
APPROVED("已通过"),
REJECTED("已拒绝"),
DELETED("已删除"),
HIDDEN("已隐藏");

private final String description;

CommentStatus(String description) {
this.description = description;
}

public String getDescription() {
return description;
}
}

2.1.3 评论点赞模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* 评论点赞实体
*/
@Entity
@Table(name = "comment_likes")
public class CommentLike {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "comment_id", nullable = false)
private Long commentId;

@Column(name = "user_id", nullable = false)
private Long userId;

@Column(name = "is_liked", nullable = false)
private Boolean isLiked = true;

@Column(name = "created_time", nullable = false)
private LocalDateTime createdTime;

@Column(name = "updated_time", nullable = false)
private LocalDateTime updatedTime;

// 构造函数
public CommentLike() {
this.createdTime = LocalDateTime.now();
this.updatedTime = LocalDateTime.now();
}

// Getter和Setter方法
public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public Long getCommentId() {
return commentId;
}

public void setCommentId(Long commentId) {
this.commentId = commentId;
}

public Long getUserId() {
return userId;
}

public void setUserId(Long userId) {
this.userId = userId;
}

public Boolean getIsLiked() {
return isLiked;
}

public void setIsLiked(Boolean isLiked) {
this.isLiked = isLiked;
}

public LocalDateTime getCreatedTime() {
return createdTime;
}

public void setCreatedTime(LocalDateTime createdTime) {
this.createdTime = createdTime;
}

public LocalDateTime getUpdatedTime() {
return updatedTime;
}

public void setUpdatedTime(LocalDateTime updatedTime) {
this.updatedTime = updatedTime;
}
}

2.2 评论系统服务层设计

2.2.1 评论服务接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/**
* 评论服务接口
*/
public interface CommentService {

/**
* 发布评论
*/
CommentResult publishComment(CommentRequest request);

/**
* 查询评论列表
*/
CommentListResult getCommentList(CommentListRequest request);

/**
* 查询评论详情
*/
CommentDetailResult getCommentDetail(Long commentId);

/**
* 删除评论
*/
CommentResult deleteComment(Long commentId, Long userId);

/**
* 点赞评论
*/
CommentResult likeComment(Long commentId, Long userId);

/**
* 取消点赞
*/
CommentResult unlikeComment(Long commentId, Long userId);

/**
* 举报评论
*/
CommentResult reportComment(Long commentId, Long userId, String reason);

/**
* 审核评论
*/
CommentResult auditComment(Long commentId, CommentStatus status, String reason);

/**
* 获取评论统计
*/
CommentStatisticsResult getCommentStatistics(Long contentId);
}

2.2.2 评论服务实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
/**
* 评论服务实现
*/
@Service
@Transactional
public class CommentServiceImpl implements CommentService {

@Autowired
private CommentRepository commentRepository;

@Autowired
private CommentLikeRepository commentLikeRepository;

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private RabbitTemplate rabbitTemplate;

@Autowired
private UserService userService;

@Autowired
private ContentService contentService;

private final String COMMENT_CACHE_PREFIX = "comment:";
private final String COMMENT_LIKE_CACHE_PREFIX = "comment_like:";
private final long COMMENT_CACHE_EXPIRE = 1800; // 30分钟

/**
* 发布评论
*/
@Override
public CommentResult publishComment(CommentRequest request) {
try {
// 1. 验证请求参数
validateCommentRequest(request);

// 2. 检查用户权限
checkUserPermission(request.getUserId());

// 3. 检查内容是否存在
checkContentExists(request.getContentId());

// 4. 创建评论实体
Comment comment = createCommentEntity(request);

// 5. 保存评论
comment = commentRepository.save(comment);

// 6. 更新缓存
updateCommentCache(comment);

// 7. 发送异步通知
sendCommentNotification(comment);

// 8. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setCommentId(comment.getId());
result.setMessage("评论发布成功");

return result;

} catch (Exception e) {
log.error("发布评论失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("评论发布失败: " + e.getMessage());
return result;
}
}

/**
* 验证评论请求
*/
private void validateCommentRequest(CommentRequest request) {
if (request.getContentId() == null) {
throw new IllegalArgumentException("内容ID不能为空");
}

if (request.getUserId() == null) {
throw new IllegalArgumentException("用户ID不能为空");
}

if (request.getContent() == null || request.getContent().trim().isEmpty()) {
throw new IllegalArgumentException("评论内容不能为空");
}

if (request.getContent().length() > 2000) {
throw new IllegalArgumentException("评论内容不能超过2000字符");
}
}

/**
* 检查用户权限
*/
private void checkUserPermission(Long userId) {
try {
UserInfo userInfo = userService.getUserInfo(userId);
if (userInfo == null) {
throw new IllegalArgumentException("用户不存在");
}

if (userInfo.getStatus() != UserStatus.ACTIVE) {
throw new IllegalArgumentException("用户状态异常");
}

} catch (Exception e) {
log.error("检查用户权限失败", e);
throw new IllegalArgumentException("用户权限验证失败");
}
}

/**
* 检查内容是否存在
*/
private void checkContentExists(Long contentId) {
try {
ContentInfo contentInfo = contentService.getContentInfo(contentId);
if (contentInfo == null) {
throw new IllegalArgumentException("内容不存在");
}

if (contentInfo.getStatus() != ContentStatus.PUBLISHED) {
throw new IllegalArgumentException("内容状态异常");
}

} catch (Exception e) {
log.error("检查内容是否存在失败", e);
throw new IllegalArgumentException("内容验证失败");
}
}

/**
* 创建评论实体
*/
private Comment createCommentEntity(CommentRequest request) {
Comment comment = new Comment();
comment.setContentId(request.getContentId());
comment.setUserId(request.getUserId());
comment.setParentId(request.getParentId());
comment.setContent(request.getContent());
comment.setStatus(CommentStatus.PENDING);
comment.setIpAddress(request.getIpAddress());
comment.setUserAgent(request.getUserAgent());

return comment;
}

/**
* 更新评论缓存
*/
private void updateCommentCache(Comment comment) {
try {
String cacheKey = COMMENT_CACHE_PREFIX + comment.getId();
redisTemplate.opsForValue().set(cacheKey, comment, Duration.ofSeconds(COMMENT_CACHE_EXPIRE));

} catch (Exception e) {
log.error("更新评论缓存失败", e);
}
}

/**
* 发送评论通知
*/
private void sendCommentNotification(Comment comment) {
try {
CommentNotificationEvent event = new CommentNotificationEvent();
event.setCommentId(comment.getId());
event.setContentId(comment.getContentId());
event.setUserId(comment.getUserId());
event.setEventType("COMMENT_PUBLISHED");
event.setTimestamp(new Date());

rabbitTemplate.convertAndSend("comment.notification.queue", event);

} catch (Exception e) {
log.error("发送评论通知失败", e);
}
}

/**
* 查询评论列表
*/
@Override
public CommentListResult getCommentList(CommentListRequest request) {
try {
// 1. 验证请求参数
validateCommentListRequest(request);

// 2. 从缓存获取
String cacheKey = COMMENT_CACHE_PREFIX + "list:" + request.getContentId() + ":" + request.getPage() + ":" + request.getSize();
CommentListResult cachedResult = (CommentListResult) redisTemplate.opsForValue().get(cacheKey);

if (cachedResult != null) {
return cachedResult;
}

// 3. 查询评论列表
Page<Comment> commentPage = commentRepository.findByContentIdAndStatusAndIsDeleted(
request.getContentId(),
CommentStatus.APPROVED,
false,
PageRequest.of(request.getPage(), request.getSize(), Sort.by(Sort.Direction.DESC, "createdTime")));

// 4. 构建返回结果
CommentListResult result = new CommentListResult();
result.setComments(commentPage.getContent());
result.setTotalCount(commentPage.getTotalElements());
result.setPage(request.getPage());
result.setSize(request.getSize());
result.setTotalPages(commentPage.getTotalPages());

// 5. 缓存结果
redisTemplate.opsForValue().set(cacheKey, result, Duration.ofSeconds(COMMENT_CACHE_EXPIRE));

return result;

} catch (Exception e) {
log.error("查询评论列表失败", e);
CommentListResult result = new CommentListResult();
result.setComments(new ArrayList<>());
result.setTotalCount(0L);
result.setPage(request.getPage());
result.setSize(request.getSize());
result.setTotalPages(0);
return result;
}
}

/**
* 验证评论列表请求
*/
private void validateCommentListRequest(CommentListRequest request) {
if (request.getContentId() == null) {
throw new IllegalArgumentException("内容ID不能为空");
}

if (request.getPage() < 0) {
throw new IllegalArgumentException("页码不能小于0");
}

if (request.getSize() <= 0 || request.getSize() > 100) {
throw new IllegalArgumentException("每页大小必须在1-100之间");
}
}

/**
* 查询评论详情
*/
@Override
public CommentDetailResult getCommentDetail(Long commentId) {
try {
// 1. 从缓存获取
String cacheKey = COMMENT_CACHE_PREFIX + commentId;
Comment comment = (Comment) redisTemplate.opsForValue().get(cacheKey);

if (comment == null) {
// 2. 从数据库查询
comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 3. 更新缓存
redisTemplate.opsForValue().set(cacheKey, comment, Duration.ofSeconds(COMMENT_CACHE_EXPIRE));
}

// 4. 构建返回结果
CommentDetailResult result = new CommentDetailResult();
result.setComment(comment);
result.setSuccess(true);

return result;

} catch (Exception e) {
log.error("查询评论详情失败", e);
CommentDetailResult result = new CommentDetailResult();
result.setSuccess(false);
result.setMessage("查询评论详情失败: " + e.getMessage());
return result;
}
}

/**
* 删除评论
*/
@Override
public CommentResult deleteComment(Long commentId, Long userId) {
try {
// 1. 查询评论
Comment comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 2. 检查权限
if (!comment.getUserId().equals(userId)) {
throw new IllegalArgumentException("无权限删除此评论");
}

// 3. 软删除评论
comment.setIsDeleted(true);
comment.setUpdatedTime(LocalDateTime.now());
commentRepository.save(comment);

// 4. 清除缓存
clearCommentCache(commentId);

// 5. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setMessage("评论删除成功");

return result;

} catch (Exception e) {
log.error("删除评论失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("删除评论失败: " + e.getMessage());
return result;
}
}

/**
* 点赞评论
*/
@Override
public CommentResult likeComment(Long commentId, Long userId) {
try {
// 1. 查询评论
Comment comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 2. 检查是否已点赞
String likeKey = COMMENT_LIKE_CACHE_PREFIX + commentId + ":" + userId;
Boolean isLiked = (Boolean) redisTemplate.opsForValue().get(likeKey);

if (isLiked != null && isLiked) {
throw new IllegalArgumentException("已经点赞过此评论");
}

// 3. 创建点赞记录
CommentLike commentLike = new CommentLike();
commentLike.setCommentId(commentId);
commentLike.setUserId(userId);
commentLike.setIsLiked(true);
commentLikeRepository.save(commentLike);

// 4. 更新评论点赞数
comment.setLikeCount(comment.getLikeCount() + 1);
comment.setUpdatedTime(LocalDateTime.now());
commentRepository.save(comment);

// 5. 更新缓存
redisTemplate.opsForValue().set(likeKey, true, Duration.ofHours(24));
updateCommentCache(comment);

// 6. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setMessage("点赞成功");

return result;

} catch (Exception e) {
log.error("点赞评论失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("点赞失败: " + e.getMessage());
return result;
}
}

/**
* 取消点赞
*/
@Override
public CommentResult unlikeComment(Long commentId, Long userId) {
try {
// 1. 查询评论
Comment comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 2. 查询点赞记录
CommentLike commentLike = commentLikeRepository.findByCommentIdAndUserId(commentId, userId);
if (commentLike == null || !commentLike.getIsLiked()) {
throw new IllegalArgumentException("未点赞此评论");
}

// 3. 删除点赞记录
commentLikeRepository.delete(commentLike);

// 4. 更新评论点赞数
comment.setLikeCount(Math.max(0, comment.getLikeCount() - 1));
comment.setUpdatedTime(LocalDateTime.now());
commentRepository.save(comment);

// 5. 更新缓存
String likeKey = COMMENT_LIKE_CACHE_PREFIX + commentId + ":" + userId;
redisTemplate.delete(likeKey);
updateCommentCache(comment);

// 6. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setMessage("取消点赞成功");

return result;

} catch (Exception e) {
log.error("取消点赞失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("取消点赞失败: " + e.getMessage());
return result;
}
}

/**
* 举报评论
*/
@Override
public CommentResult reportComment(Long commentId, Long userId, String reason) {
try {
// 1. 查询评论
Comment comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 2. 更新举报数
comment.setReportCount(comment.getReportCount() + 1);
comment.setUpdatedTime(LocalDateTime.now());
commentRepository.save(comment);

// 3. 更新缓存
updateCommentCache(comment);

// 4. 发送举报通知
sendReportNotification(commentId, userId, reason);

// 5. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setMessage("举报成功");

return result;

} catch (Exception e) {
log.error("举报评论失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("举报失败: " + e.getMessage());
return result;
}
}

/**
* 发送举报通知
*/
private void sendReportNotification(Long commentId, Long userId, String reason) {
try {
CommentReportEvent event = new CommentReportEvent();
event.setCommentId(commentId);
event.setUserId(userId);
event.setReason(reason);
event.setEventType("COMMENT_REPORTED");
event.setTimestamp(new Date());

rabbitTemplate.convertAndSend("comment.report.queue", event);

} catch (Exception e) {
log.error("发送举报通知失败", e);
}
}

/**
* 审核评论
*/
@Override
public CommentResult auditComment(Long commentId, CommentStatus status, String reason) {
try {
// 1. 查询评论
Comment comment = commentRepository.findById(commentId).orElse(null);
if (comment == null) {
throw new IllegalArgumentException("评论不存在");
}

// 2. 更新评论状态
comment.setStatus(status);
comment.setUpdatedTime(LocalDateTime.now());
commentRepository.save(comment);

// 3. 更新缓存
updateCommentCache(comment);

// 4. 发送审核通知
sendAuditNotification(commentId, status, reason);

// 5. 构建返回结果
CommentResult result = new CommentResult();
result.setSuccess(true);
result.setMessage("审核成功");

return result;

} catch (Exception e) {
log.error("审核评论失败", e);
CommentResult result = new CommentResult();
result.setSuccess(false);
result.setMessage("审核失败: " + e.getMessage());
return result;
}
}

/**
* 发送审核通知
*/
private void sendAuditNotification(Long commentId, CommentStatus status, String reason) {
try {
CommentAuditEvent event = new CommentAuditEvent();
event.setCommentId(commentId);
event.setStatus(status);
event.setReason(reason);
event.setEventType("COMMENT_AUDITED");
event.setTimestamp(new Date());

rabbitTemplate.convertAndSend("comment.audit.queue", event);

} catch (Exception e) {
log.error("发送审核通知失败", e);
}
}

/**
* 获取评论统计
*/
@Override
public CommentStatisticsResult getCommentStatistics(Long contentId) {
try {
// 1. 从缓存获取
String cacheKey = COMMENT_CACHE_PREFIX + "statistics:" + contentId;
CommentStatisticsResult cachedResult = (CommentStatisticsResult) redisTemplate.opsForValue().get(cacheKey);

if (cachedResult != null) {
return cachedResult;
}

// 2. 查询统计信息
Long totalComments = commentRepository.countByContentIdAndStatusAndIsDeleted(contentId, CommentStatus.APPROVED, false);
Long totalLikes = commentRepository.sumLikeCountByContentIdAndStatusAndIsDeleted(contentId, CommentStatus.APPROVED, false);
Long totalReplies = commentRepository.sumReplyCountByContentIdAndStatusAndIsDeleted(contentId, CommentStatus.APPROVED, false);

// 3. 构建返回结果
CommentStatisticsResult result = new CommentStatisticsResult();
result.setContentId(contentId);
result.setTotalComments(totalComments);
result.setTotalLikes(totalLikes);
result.setTotalReplies(totalReplies);

// 4. 缓存结果
redisTemplate.opsForValue().set(cacheKey, result, Duration.ofSeconds(COMMENT_CACHE_EXPIRE));

return result;

} catch (Exception e) {
log.error("获取评论统计失败", e);
CommentStatisticsResult result = new CommentStatisticsResult();
result.setContentId(contentId);
result.setTotalComments(0L);
result.setTotalLikes(0L);
result.setTotalReplies(0L);
return result;
}
}

/**
* 清除评论缓存
*/
private void clearCommentCache(Long commentId) {
try {
String cacheKey = COMMENT_CACHE_PREFIX + commentId;
redisTemplate.delete(cacheKey);

} catch (Exception e) {
log.error("清除评论缓存失败", e);
}
}
}

三、企业级评论系统方案

3.1 评论系统管理服务

3.1.1 评论系统管理服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/**
* 评论系统管理服务
*/
@Service
public class CommentSystemManagementService {

@Autowired
private CommentService commentService;

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private RabbitTemplate rabbitTemplate;

private final String COMMENT_SYSTEM_CACHE_PREFIX = "comment_system:";
private final long COMMENT_SYSTEM_CACHE_EXPIRE = 3600; // 1小时

/**
* 批量审核评论
*/
public BatchAuditResult batchAuditComments(BatchAuditRequest request) {
try {
BatchAuditResult result = new BatchAuditResult();
result.setRequestId(request.getRequestId());
result.setStartTime(new Date());

List<CommentAuditItem> auditItems = request.getAuditItems();
List<CommentAuditResult> auditResults = new ArrayList<>();

for (CommentAuditItem item : auditItems) {
try {
CommentResult commentResult = commentService.auditComment(
item.getCommentId(),
item.getStatus(),
item.getReason());

CommentAuditResult auditResult = new CommentAuditResult();
auditResult.setCommentId(item.getCommentId());
auditResult.setSuccess(commentResult.isSuccess());
auditResult.setMessage(commentResult.getMessage());

auditResults.add(auditResult);

} catch (Exception e) {
log.error("批量审核评论失败: {}", item.getCommentId(), e);

CommentAuditResult auditResult = new CommentAuditResult();
auditResult.setCommentId(item.getCommentId());
auditResult.setSuccess(false);
auditResult.setMessage("审核失败: " + e.getMessage());

auditResults.add(auditResult);
}
}

result.setAuditResults(auditResults);
result.setTotalCount(auditItems.size());
result.setSuccessCount(auditResults.stream().mapToInt(r -> r.isSuccess() ? 1 : 0).sum());
result.setEndTime(new Date());
result.setStatus(BatchAuditStatus.COMPLETED);

return result;

} catch (Exception e) {
log.error("批量审核评论失败", e);
throw new CommentSystemException("批量审核评论失败", e);
}
}

/**
* 获取评论系统统计
*/
public CommentSystemStatisticsResult getCommentSystemStatistics(Date startTime, Date endTime) {
try {
// 从缓存获取
String cacheKey = COMMENT_SYSTEM_CACHE_PREFIX + "statistics:" + startTime.getTime() + ":" + endTime.getTime();
CommentSystemStatisticsResult cachedResult = (CommentSystemStatisticsResult) redisTemplate.opsForValue().get(cacheKey);

if (cachedResult != null) {
return cachedResult;
}

// 查询统计信息
CommentSystemStatisticsResult result = new CommentSystemStatisticsResult();
result.setStartTime(startTime);
result.setEndTime(endTime);

// 统计评论数量
result.setTotalComments(10000L); // 实际应用中需要从数据库统计
result.setPendingComments(100L);
result.setApprovedComments(9500L);
result.setRejectedComments(400L);

// 统计点赞数量
result.setTotalLikes(50000L);

// 统计举报数量
result.setTotalReports(200L);

// 统计用户数量
result.setTotalUsers(5000L);
result.setActiveUsers(3000L);

// 缓存结果
redisTemplate.opsForValue().set(cacheKey, result, Duration.ofSeconds(COMMENT_SYSTEM_CACHE_EXPIRE));

return result;

} catch (Exception e) {
log.error("获取评论系统统计失败", e);
throw new CommentSystemException("获取评论系统统计失败", e);
}
}

/**
* 清理过期评论
*/
@Scheduled(cron = "0 0 2 * * ?") // 每天凌晨2点执行
public void cleanupExpiredComments() {
try {
log.info("开始清理过期评论");

// 清理30天前的已删除评论
LocalDateTime expiredTime = LocalDateTime.now().minusDays(30);
// 这里需要实现清理逻辑

log.info("清理过期评论完成");

} catch (Exception e) {
log.error("清理过期评论失败", e);
}
}

/**
* 同步评论数据
*/
public CommentSyncResult syncCommentData(CommentSyncRequest request) {
try {
CommentSyncResult result = new CommentSyncResult();
result.setRequestId(request.getRequestId());
result.setStartTime(new Date());

// 实现数据同步逻辑
result.setSyncedCount(1000L);
result.setEndTime(new Date());
result.setStatus(CommentSyncStatus.COMPLETED);

return result;

} catch (Exception e) {
log.error("同步评论数据失败", e);
throw new CommentSystemException("同步评论数据失败", e);
}
}
}

3.2 评论系统优化服务

3.2.1 评论系统优化服务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/**
* 评论系统优化服务
*/
@Service
public class CommentSystemOptimizationService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private CaffeineCache localCache;

private final String COMMENT_OPTIMIZATION_CACHE_PREFIX = "comment_optimization:";

/**
* 优化评论查询性能
*/
public CommentQueryOptimizationResult optimizeCommentQueryPerformance(CommentQueryOptimizationRequest request) {
try {
CommentQueryOptimizationResult result = new CommentQueryOptimizationResult();
result.setRequestId(request.getRequestId());
result.setStartTime(new Date());

// 1. 分析查询模式
CommentQueryPatternAnalysis patternAnalysis = analyzeCommentQueryPattern(request);
result.setPatternAnalysis(patternAnalysis);

// 2. 优化缓存策略
CommentCacheOptimizationResult cacheOptimization = optimizeCommentCacheStrategy(request, patternAnalysis);
result.setCacheOptimization(cacheOptimization);

// 3. 优化数据库策略
CommentDatabaseOptimizationResult databaseOptimization = optimizeCommentDatabaseStrategy(request, patternAnalysis);
result.setDatabaseOptimization(databaseOptimization);

result.setStatus(CommentOptimizationStatus.COMPLETED);
result.setEndTime(new Date());

return result;

} catch (Exception e) {
log.error("优化评论查询性能失败", e);
throw new CommentSystemException("优化评论查询性能失败", e);
}
}

/**
* 分析评论查询模式
*/
private CommentQueryPatternAnalysis analyzeCommentQueryPattern(CommentQueryOptimizationRequest request) {
try {
CommentQueryPatternAnalysis analysis = new CommentQueryPatternAnalysis();
analysis.setRequestId(request.getRequestId());

// 分析查询频率
analysis.setQueryFrequency(analyzeCommentQueryFrequency(request.getContentId()));

// 分析查询复杂度
analysis.setQueryComplexity(analyzeCommentQueryComplexity(request));

// 分析数据量
analysis.setDataVolume(analyzeCommentDataVolume(request.getContentId()));

return analysis;

} catch (Exception e) {
log.error("分析评论查询模式失败", e);
throw new CommentSystemException("分析评论查询模式失败", e);
}
}

/**
* 分析评论查询频率
*/
private CommentQueryFrequency analyzeCommentQueryFrequency(Long contentId) {
try {
CommentQueryFrequency frequency = new CommentQueryFrequency();
frequency.setContentId(contentId);
frequency.setDailyCount(1000);
frequency.setHourlyCount(100);
frequency.setMinuteCount(10);

return frequency;

} catch (Exception e) {
log.error("分析评论查询频率失败", e);
return new CommentQueryFrequency();
}
}

/**
* 分析评论查询复杂度
*/
private CommentQueryComplexity analyzeCommentQueryComplexity(CommentQueryOptimizationRequest request) {
try {
CommentQueryComplexity complexity = new CommentQueryComplexity();
complexity.setParameterCount(request.getParameters().size());
complexity.setComplexityLevel(CommentComplexityLevel.MEDIUM);
complexity.setIndexCount(3);
complexity.setJoinCount(2);

return complexity;

} catch (Exception e) {
log.error("分析评论查询复杂度失败", e);
return new CommentQueryComplexity();
}
}

/**
* 分析评论数据量
*/
private CommentDataVolume analyzeCommentDataVolume(Long contentId) {
try {
CommentDataVolume volume = new CommentDataVolume();
volume.setContentId(contentId);
volume.setEstimatedComments(5000);
volume.setDataSizeKB(2500);

return volume;

} catch (Exception e) {
log.error("分析评论数据量失败", e);
return new CommentDataVolume();
}
}

/**
* 优化评论缓存策略
*/
private CommentCacheOptimizationResult optimizeCommentCacheStrategy(CommentQueryOptimizationRequest request,
CommentQueryPatternAnalysis analysis) {
try {
CommentCacheOptimizationResult result = new CommentCacheOptimizationResult();
result.setRequestId(request.getRequestId());

// 根据查询模式优化缓存策略
if (analysis.getQueryFrequency().getDailyCount() > 1000) {
result.setRecommendedCacheExpire(3600); // 1小时
result.setRecommendedCacheSize(1000);
result.setRecommendedCacheStrategy("LRU");
} else if (analysis.getQueryFrequency().getDailyCount() > 100) {
result.setRecommendedCacheExpire(1800); // 30分钟
result.setRecommendedCacheSize(500);
result.setRecommendedCacheStrategy("LFU");
} else {
result.setRecommendedCacheExpire(600); // 10分钟
result.setRecommendedCacheSize(100);
result.setRecommendedCacheStrategy("FIFO");
}

return result;

} catch (Exception e) {
log.error("优化评论缓存策略失败", e);
throw new CommentSystemException("优化评论缓存策略失败", e);
}
}

/**
* 优化评论数据库策略
*/
private CommentDatabaseOptimizationResult optimizeCommentDatabaseStrategy(CommentQueryOptimizationRequest request,
CommentQueryPatternAnalysis analysis) {
try {
CommentDatabaseOptimizationResult result = new CommentDatabaseOptimizationResult();
result.setRequestId(request.getRequestId());

// 根据数据量优化数据库策略
if (analysis.getDataVolume().getEstimatedComments() > 10000) {
result.setRecommendedIndexType("B+Tree");
result.setRecommendedPartitionStrategy("HASH");
result.setRecommendedShardingStrategy("HORIZONTAL");
} else if (analysis.getDataVolume().getEstimatedComments() > 1000) {
result.setRecommendedIndexType("B+Tree");
result.setRecommendedPartitionStrategy("RANGE");
result.setRecommendedShardingStrategy("NONE");
} else {
result.setRecommendedIndexType("B+Tree");
result.setRecommendedPartitionStrategy("NONE");
result.setRecommendedShardingStrategy("NONE");
}

return result;

} catch (Exception e) {
log.error("优化评论数据库策略失败", e);
throw new CommentSystemException("优化评论数据库策略失败", e);
}
}

/**
* 预热评论系统缓存
*/
@PostConstruct
public void warmupCommentSystemCache() {
try {
// 预热常用评论数据
List<Long> commonContentIds = Arrays.asList(1L, 2L, 3L, 4L, 5L);

for (Long contentId : commonContentIds) {
try {
String cacheKey = COMMENT_OPTIMIZATION_CACHE_PREFIX + "warmup:" + contentId;
Object warmupData = new Object();
redisTemplate.opsForValue().set(cacheKey, warmupData, Duration.ofHours(1));
} catch (Exception e) {
log.error("预热评论系统缓存失败: {}", contentId, e);
}
}

} catch (Exception e) {
log.error("预热评论系统缓存失败", e);
}
}

/**
* 清理过期缓存
*/
@Scheduled(fixedRate = 300000) // 5分钟
public void cleanupExpiredCache() {
try {
// 清理本地缓存
localCache.cleanUp();

// 清理Redis过期缓存
cleanupRedisExpiredCache();

} catch (Exception e) {
log.error("清理过期缓存失败", e);
}
}

/**
* 清理Redis过期缓存
*/
private void cleanupRedisExpiredCache() {
try {
Set<String> cacheKeys = redisTemplate.keys(COMMENT_OPTIMIZATION_CACHE_PREFIX + "*");

for (String key : cacheKeys) {
Long ttl = redisTemplate.getExpire(key);
if (ttl != null && ttl <= 0) {
redisTemplate.delete(key);
}
}

} catch (Exception e) {
log.error("清理Redis过期缓存失败", e);
}
}
}

四、性能优化与监控

4.1 性能优化

4.1.1 评论系统性能优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* 评论系统性能优化服务
*/
@Service
public class CommentSystemPerformanceOptimizationService {

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Autowired
private CaffeineCache localCache;

private final String COMMENT_PERFORMANCE_CACHE_PREFIX = "comment_performance:";

/**
* 缓存评论系统性能数据
*/
public void cacheCommentSystemPerformanceData(String requestId, Object data) {
String cacheKey = COMMENT_PERFORMANCE_CACHE_PREFIX + requestId;

try {
// 写入本地缓存
localCache.put(cacheKey, data);

// 写入Redis缓存
String redisCacheKey = "redis_cache:" + cacheKey;
redisTemplate.opsForValue().set(redisCacheKey, data, Duration.ofHours(1));

} catch (Exception e) {
log.error("缓存评论系统性能数据失败", e);
}
}

/**
* 获取缓存的评论系统性能数据
*/
public Object getCachedCommentSystemPerformanceData(String requestId) {
String cacheKey = COMMENT_PERFORMANCE_CACHE_PREFIX + requestId;

try {
// 从本地缓存获取
Object cachedData = localCache.getIfPresent(cacheKey);
if (cachedData != null) {
return cachedData;
}

// 从Redis获取
String redisCacheKey = "redis_cache:" + cacheKey;
Object redisData = redisTemplate.opsForValue().get(redisCacheKey);
if (redisData != null) {
localCache.put(cacheKey, redisData);
return redisData;
}

} catch (Exception e) {
log.error("获取缓存的评论系统性能数据失败", e);
}

return null;
}

/**
* 批量处理评论系统请求
*/
public List<CommentSystemResult> batchProcessCommentSystemRequests(
List<CommentSystemRequest> requests) {
List<CommentSystemResult> results = new ArrayList<>();

try {
// 按请求类型分组
Map<CommentSystemRequestType, List<CommentSystemRequest>> typeGroups = requests.stream()
.collect(Collectors.groupingBy(CommentSystemRequest::getRequestType));

// 并行处理各类型
typeGroups.entrySet().parallelStream().forEach(entry -> {
CommentSystemRequestType requestType = entry.getKey();
List<CommentSystemRequest> typeRequests = entry.getValue();

try {
List<CommentSystemResult> typeResults = processCommentSystemTypeRequests(requestType, typeRequests);

synchronized (results) {
results.addAll(typeResults);
}

} catch (Exception e) {
log.error("处理评论系统请求类型失败: {}", requestType, e);
}
});

} catch (Exception e) {
log.error("批量处理评论系统请求失败", e);
}

return results;
}

/**
* 处理评论系统类型请求
*/
private List<CommentSystemResult> processCommentSystemTypeRequests(CommentSystemRequestType requestType,
List<CommentSystemRequest> requests) {
List<CommentSystemResult> results = new ArrayList<>();

for (CommentSystemRequest request : requests) {
try {
CommentSystemResult result = processCommentSystemRequest(request);
results.add(result);
} catch (Exception e) {
log.error("处理评论系统请求失败: {}", request.getRequestId(), e);
CommentSystemResult errorResult = new CommentSystemResult();
errorResult.setRequestId(request.getRequestId());
errorResult.setStatus(CommentSystemStatus.FAILED);
errorResult.setErrorMessage(e.getMessage());
results.add(errorResult);
}
}

return results;
}

/**
* 处理评论系统请求
*/
private CommentSystemResult processCommentSystemRequest(CommentSystemRequest request) {
// 实现评论系统请求处理逻辑
CommentSystemResult result = new CommentSystemResult();
result.setRequestId(request.getRequestId());
result.setStatus(CommentSystemStatus.SUCCESS);
result.setData("评论系统请求处理成功");
return result;
}

/**
* 预热评论系统性能缓存
*/
@PostConstruct
public void warmupCommentSystemPerformanceCache() {
try {
// 预热常用评论系统性能数据
List<String> commonRequestIds = Arrays.asList("comment_req_1", "comment_req_2", "comment_req_3");

for (String requestId : commonRequestIds) {
try {
String cacheKey = COMMENT_PERFORMANCE_CACHE_PREFIX + requestId;
Object performanceData = new Object();
cacheCommentSystemPerformanceData(requestId, performanceData);
} catch (Exception e) {
log.error("预热评论系统性能缓存失败: {}", requestId, e);
}
}

} catch (Exception e) {
log.error("预热评论系统性能缓存失败", e);
}
}

/**
* 清理过期缓存
*/
@Scheduled(fixedRate = 300000) // 5分钟
public void cleanupExpiredCache() {
try {
// 清理本地缓存
localCache.cleanUp();

// 清理Redis过期缓存
cleanupRedisExpiredCache();

} catch (Exception e) {
log.error("清理过期缓存失败", e);
}
}

/**
* 清理Redis过期缓存
*/
private void cleanupRedisExpiredCache() {
try {
Set<String> cacheKeys = redisTemplate.keys("redis_cache:" + COMMENT_PERFORMANCE_CACHE_PREFIX + "*");

for (String key : cacheKeys) {
Long ttl = redisTemplate.getExpire(key);
if (ttl != null && ttl <= 0) {
redisTemplate.delete(key);
}
}

} catch (Exception e) {
log.error("清理Redis过期缓存失败", e);
}
}
}

4.2 监控告警

4.2.1 评论系统监控指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* 评论系统监控指标
*/
@Component
public class CommentSystemMetrics {

private final MeterRegistry meterRegistry;

public CommentSystemMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
}

/**
* 记录评论系统请求次数
*/
public void recordCommentSystemRequestCount(String requestType, String status) {
Counter.builder("comment_system.request.count")
.description("评论系统请求次数")
.tag("request_type", requestType)
.tag("status", status)
.register(meterRegistry)
.increment();
}

/**
* 记录评论系统请求时间
*/
public void recordCommentSystemRequestTime(String requestType, String status, long duration) {
Timer.builder("comment_system.request.time")
.description("评论系统请求时间")
.tag("request_type", requestType)
.tag("status", status)
.register(meterRegistry)
.record(duration, TimeUnit.MILLISECONDS);
}

/**
* 记录评论系统数据量
*/
public void recordCommentSystemDataCount(String dataType, long count) {
Counter.builder("comment_system.data.count")
.description("评论系统数据量")
.tag("data_type", dataType)
.register(meterRegistry)
.increment(count);
}

/**
* 记录评论系统成功率
*/
public void recordCommentSystemSuccessRate(String requestType, double successRate) {
Gauge.builder("comment_system.success.rate")
.description("评论系统成功率")
.tag("request_type", requestType)
.register(meterRegistry, successRate);
}

/**
* 记录评论系统失败率
*/
public void recordCommentSystemFailureRate(String requestType, double failureRate) {
Gauge.builder("comment_system.failure.rate")
.description("评论系统失败率")
.tag("request_type", requestType)
.register(meterRegistry, failureRate);
}

/**
* 记录评论系统吞吐量
*/
public void recordCommentSystemThroughput(String requestType, double throughput) {
Gauge.builder("comment_system.throughput")
.description("评论系统吞吐量")
.tag("request_type", requestType)
.register(meterRegistry, throughput);
}

/**
* 记录评论系统异常次数
*/
public void recordCommentSystemExceptionCount(String requestType, String exceptionType) {
Counter.builder("comment_system.exception.count")
.description("评论系统异常次数")
.tag("request_type", requestType)
.tag("exception_type", exceptionType)
.register(meterRegistry)
.increment();
}
}

4.2.2 评论系统告警规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# prometheus-rules.yml
groups:
- name: comment_system_alerts
rules:
- alert: HighCommentSystemRequestTime
expr: comment_system_request_time{quantile="0.95"} > 1000
for: 2m
labels:
severity: warning
annotations:
summary: "评论系统请求时间过长"
description: "评论系统请求时间P95超过1秒,当前值: {{ $value }}ms"

- alert: HighCommentSystemFailureRate
expr: comment_system_failure_rate > 0.05
for: 2m
labels:
severity: warning
annotations:
summary: "评论系统失败率过高"
description: "评论系统失败率超过5%,当前值: {{ $value }}"

- alert: LowCommentSystemThroughput
expr: comment_system_throughput < 100
for: 5m
labels:
severity: warning
annotations:
summary: "评论系统吞吐量过低"
description: "评论系统吞吐量低于100次/秒,当前值: {{ $value }}"

- alert: HighCommentSystemExceptionCount
expr: rate(comment_system_exception_count[5m]) > 5
for: 2m
labels:
severity: critical
annotations:
summary: "评论系统异常次数过多"
description: "评论系统异常频率超过5次/分钟,当前值: {{ $value }}"

- alert: CommentSystemServiceDown
expr: up{job="comment-system-service"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "评论系统服务宕机"
description: "评论系统服务已宕机超过1分钟"

五、总结

评论系统作为现代互联网应用的核心功能之一,通过合理的评论系统架构设计和数据模型,能够构建一个高效、稳定、可扩展的评论系统。本文从评论系统架构设计到数据模型,从基础实现到企业级应用,系统梳理了评论系统设计的完整解决方案。

5.1 关键要点

  1. 架构设计:通过分层架构设计实现评论系统的模块化和可扩展性
  2. 数据模型:通过合理的数据模型设计实现评论数据的有效存储和管理
  3. 服务层设计:通过服务层设计实现评论业务逻辑的封装和复用
  4. 性能优化:通过缓存、异步处理等手段优化评论系统性能
  5. 监控告警:建立完善的监控体系,及时发现和处理问题

5.2 最佳实践

  1. 数据模型设计:合理设计评论实体模型,支持评论的层级结构和状态管理
  2. 缓存策略:合理使用缓存,减少数据库查询压力
  3. 异步处理:通过异步处理提高系统响应性能
  4. 监控告警:建立完善的监控体系,确保评论系统稳定运行
  5. 安全控制:实现评论审核、举报等安全控制机制

通过以上措施,可以构建一个高效、稳定、可扩展的评论系统,为企业的各种业务场景提供评论功能支持。