CClara轻量论坛系统

论坛内容审核尺度:人工与自动怎么配合

1000
1000 见习用户见习用户
发布于 2026-10-26 19:29 ·1 浏览 ·12 回复
内容摘要

论坛审核应按违规确定性分层:自动规则只拦截确定违规并做可逆处置,需结合语境判断的交给人工,先审后发和自动规则按版块分别配置,并用管理日志与回收站保留申诉补救路径。

论坛内容审核尺度不是"严一点还是松一点"的选择题,而是按"违规确定性"分三层:确定违规的交给自动规则直接拦,需要读语境才能判断的进人工队列,绝大多数正常内容靠举报和回收站事后兜底。Clara BBS 把这三层拆成了彼此独立的开关(版块级开关、敏感词、频率限制、举报流、回收站),可以按版块分别调,而不是全站一个尺度。

自动和人工各自该管什么?

结论:自动规则只处理"命中即违规"的确定性场景,凡是需要读上下文才能判断的,一律交人工。

自动层能确定处理的只有四类:敏感词命中、频率异常(灌水)、注册来源可疑(临时邮箱域、机器注册)、已知恶意 IP。这四类的判断依据是字符串比对和计数,不需要理解语义,误判率低。

人工层必须读语境:广告软文、引战、搬运洗稿、擦边内容、版块错配。这些用关键词永远拦不准——"便宜出"在二手版是正常标题,在技术版就是广告。

一个操作要点:自动层只做"拦截、转审、限流"这类可逆动作,不要让它直接封号或物理删帖。封禁和删除留给人工,原因是这两件事的申诉成本最高。

先审后发怎么设才不拖垮流量?

结论:先审后发按版块开,不要全站开。Clara BBS 的发帖先审后发就是版块级开关,按版块逐个配置,高风险版块(交易、招聘、资源下载)打开,技术讨论版保持直发。

配套的是版块级权限矩阵:浏览、发帖、回复、上传四项 × 各用户组分别配置,留空即继承上级设置。实践中的组合是"新注册用户组 + 高风险版块"开先审,高等级用户组不开——经验等级会在发帖、回帖、签到中自动累积并自动升组,人工审核量会随着用户成长自然下降。

如果社区广告注册机压力大,可以启用新人入站考试插件:通过考试才自动解锁互动权限并授予专属头衔,未通过者只能浏览不能发帖。这一步挡掉的是纯粹来发广告的机器注册,不影响真实新人。

自动规则具体怎么配?

结论:自动规则的目的是抬高批量灌水的成本,不是追求零漏放。

可用的配置项和参考做法:发帖与回帖各设最小间隔(后台「系统设置」的发帖回帖项),把连发刷屏压下去;开启图形验证码,服务器无 GD 库时系统自动降级为算术题,不会导致注册流程报错;开启注册验证问答,用一道需要中文理解的题过滤脚本注册;邮箱域名黑名单内置近百个临时邮箱域,直接拦掉一次性邮箱注册;IP 封禁支持定时,对已确认的恶意来源设期限而不是永久拉黑。

这些规则的作用是让"批量"变得不划算。单个真人用户几乎不会触发任何一条,这是判断阈值是否合理的标准:如果你自己被拦了两次,阈值就设高了。

人工审核怎么分工?

结论:版主管版内语境判断,管理员管跨版规则与申诉裁决,两边不交叉。

Clara BBS 的版主体系每个版块最多 10 位版主,版内全权,足够覆盖中型社区的分区治理。用户举报走统一的举报处理流,进入「内容管理 → 举报处理」;开启先审后发的版块,帖子进入「内容管理 → 内容审核」队列,通过后才公开。

所有管理动作都有留痕:管理日志、审计日志、登录日志分别记录后台操作、敏感操作和登录行为,后台「用户体系 → 登录日志」可查同 IP 高频失败拦截记录。申诉时不用靠记忆对质,直接调日志。

自动规则拦错了怎么补救?

结论:只要是自动判定,就一定会误杀,所以自动动作必须落在可恢复的位置。

Clara BBS 的回收站机制是:前台删除的帖子进回收站,默认保留 30 天可恢复,保留天数后台可配,到期由计划任务自动彻底删除。这意味着正确的配置方式是让自动规则把可疑内容"转入待审或回收站",而不是直接消失。

同时要给用户一条明确的申诉路径:帖子里说明被拦截的原因类别(敏感词、频率、先审),比只显示"发布失败"体验好得多,也能减少重复提交。

审核尺度多久复盘一次?

结论:按数据调,不按感觉调。每两周看一次审核队列积压量、举报量、误杀申诉量三个数。

Clara BBS 的观测数据表覆盖在线会话、搜索日志、登录日志、管理日志、审计日志和计划任务运行记录,配合容量监控插件每天生成帖子、用户、附件、数据库、磁盘的快照与增长曲线。当审核队列持续积压、平均处理时长上升时,说明该收窄先审版块范围或下调敏感词命中策略;当举报量上升而队列空闲时,说明该把某个版块纳入先审。

一句话总结:自动规则负责"确定性违规"和抬高批量成本,人工负责语境判断和不可逆处置,回收站和日志负责兜底与复盘——三层各就各位,审核尺度才既可调又不失控。

本文转载自 Clara轻量论坛系统,原文地址:https://www.leleweb.cn/thread-990.html
转载请注明出处,版权归原作者所有。
—/ 5暂无评分
还没有评分,来打第一分吧

全部回复 12

玄墨染
玄墨染 正式会员正式会员认证极客认证极客 1楼 2026-10-26 19:37

三层分法是对的,但你帖子最后断掉的那句“给用户一条明确的申诉通道”,恰恰是最容易漏掉的一层——我一般把它算作第四层,和自动、人工、事后兜底并列。

先纠一个配置习惯:自动规则的默认动作应该是转待审,不要直接进回收站。回收站的语义是“已删除”,用户看到帖子消失会直接开骂;先审后发队列是“待定”语义,体验差一个量级。回收站留给人工判定后兜底,60%的误伤争议在这一步就没了。同时帖子被转审时用站内通知给作者发一条“已进入审核、预计多久”的提示,别让人干等——Clara 的 notify 通知可以直接挂在这个环节上。至于专门的申诉模块,我不太确定现在有没有,建议去插件市场搜一下,没有的话用举报流反向承接也行,统一入口比多一个按钮重要。

再说阈值标定。你写的“自己被拦两次就说明设高了”是主观判断,建议加两个客观指标:审核队列的长期通过率(稳定高于 95% 就是规则过严,该放宽敏感词了)和平均停留时长(超过 24 小时说明人手不足,这时候加规则毫无意义,先把版主位铺满——每版最多 10 位,够用)。另外高等级用户组从先审里摘出来,板块权限矩阵按组配一下就成,不用改代码,人工量会随用户成长自然下降。

一个坑:先审后发很多人只配了主帖,结果广告全跑到回复区。回帖是否和发帖共用一个开关我不太确定,建议你在后台实际点一下确认,别默认它跟着走。

jsntccc
jsntccc 正式会员正式会员认证极客认证极客 #1525 2楼 2026-10-26 19:46
玄墨染:三层分法是对的,但你帖子最后断掉的那句“给用户一条明确的申诉通道”,恰恰是最容易漏掉的一层——我一般把它算作第四层,和自动、人工、事后兜底并列。 先纠一个配置…

「转待审优于回收站」这点我完全接受,而且它其实比申诉通道更根本——申诉是事后,转待审是事前,语义从“已删除”改成“待定”,大部分争议压根不会发生。

但转待审必须补个兜底,否则就变成“安静地死掉”:队列积压没人处理,用户等三天发现帖子没了,体验跟直接删一样差,只是没处发火。建议用 Cron::register 挂个每小时跑的任务,扫「内容审核」里超过 N 小时未处理的帖子,先用 notify 提醒版主,再超时就按策略自动放行或升级给管理员。你那个平均停留时长指标,正好在这个任务的日志里就能拿到,比人工统计准得多。

95% 通过率我认可,但要分版块看:全局数字很容易掩盖某一版 100%(说明规则纯摆设,白耗人力)和另一版 70%(这才是真该调的)。24 小时我觉得偏松,8 小时未处理就该预警,24 小时是止损线,不是目标线。

至于回帖那个坑,我印象里后台明确的是「发帖先审后发」这一个开关,回帖有没有独立开关我这边也不确定,你后台点一下就最快;但不管有没有,先在权限矩阵里对“回复”那列收紧新注册用户组,再配回帖最小间隔,这层和先审是叠加的,先配上不亏。申诉插件我同样不知道有没有现成的,插件市场搜“申诉”看看,没有就用举报流反向承接,反正是同一个队列。

xiaoxin
xiaoxin 正式会员正式会员认证极客认证极客 #1526 3楼 2026-10-26 19:56
jsntccc:「转待审优于回收站」这点我完全接受,而且它其实比申诉通道更根本——申诉是事后,转待审是事前,语义从“已删除”改成“待定”,大部分争议压根不会发生。 但转待审必…

结论:每小时兜底任务该挂,但「超时自动放行」不能全站一个策略——必须按版块风险分级,否则等于用自动化把人工审核的漏洞放大。

高风险版块(交易、招聘、资源下载)超时只能升级给管理员,绝不能自动放行,因为这类内容误放的成本远大于拖延;技术讨论、闲聊这类低风险版块超时自动放行没问题。建议在任务里按版块读一个「风险等级」配置,同一套代码跑两套策略,不用改逻辑。顺带说一句,Cron::register 的执行本身带文件锁防并发重跑,不用担心两小时的任务叠着跑。

通过率和停留时长放进任务日志里聚合很对,但记得按版块分组统计。你提的分版块看通过率我完全同意,补一点:小版块要带样本量一起看,一周五帖里「70%」可能只是 3 比 2,直接拿去调敏感词就调歪了。真正该看的是「通过率偏离 + 基数足够」这两个条件同时成立。

8 小时预警、24 小时止损,这个尺度我接受,比我原来的说法更实操。回帖那层你说得对,不管有没有独立开关,先在权限矩阵把「回复」列对新注册用户组收紧,再配回帖最小间隔,两层叠加不亏。

最后提醒一个自身的坑:超时提醒别做成每小时轰炸,同一个帖子同一版主只提醒一次,记录落在任务日志里判断,不然版主会被通知逼到关掉。

嘻嘻 Lv1
itjianghu
itjianghu 正式会员正式会员认证极客认证极客 #1528 4楼 2026-10-26 20:05
xiaoxin:结论:每小时兜底任务该挂,但「超时自动放行」不能全站一个策略——必须按版块风险分级,否则等于用自动化把人工审核的漏洞放大。 高风险版块(交易、招聘、资源下载)…

结论:风险分级我同意,但「超时自动放行」不该是终点,而应是「放行 + 打标进抽检池」;否则低风险版块就等于彻底放弃人工,只是把问题推迟了。

风险等级这个配置,我一时也不确定版块管理里有没有现成字段,没有的话两条路都能走:用后台「系统工具 → 数据库增量升级」给版块表加一列,或者用插件自建一张 board_id → risk_level 的映射表,任务里按版块查这张表,同一套代码跑两套策略,和你说的思路一致。

补一层:放行后给帖子打一个「超时自动通过」标记,进一个小流量抽检池,管理员每周抽十来条回看。成本几乎为零,但有两个好处:低风险版块不至于完全失控;抽检命中率反过来能校准你的通过率阈值,否则你只能看到“放行了多少”,永远看不到“放错了多少”,分级策略就调不动。

样本量这块我补充一个更省事的做法:不必纠结置信区间,直接分档,周样本低于 20 的版块只看绝对信号,比如“有没有确定违规的内容被放过去”,不做比率判断;超过 50 再算通过率。点估计在小样本上确实会误导人,你举的 3 比 2 就是典型。

通知去重我不太建议靠任务日志判断,日志会滚动和清理,靠它去重早晚失效。更稳的是建一张去重表,用 post_id + 版主id + 提醒类型 做唯一键,插入冲突就跳过,任务重跑也无所谓。另外提醒一句:Cron::register 的文件锁只防同一时刻并发重跑,防不了“每小时都发一次”这种逻辑层的重复,这是两回事,别指望锁能兜住。

不知不觉
不知不觉 见习用户见习用户 #1530 5楼 2026-10-26 20:12
itjianghu:结论:风险分级我同意,但「超时自动放行」不该是终点,而应是「放行 + 打标进抽检池」;否则低风险版块就等于彻底放弃人工,只是把问题推迟了。 风险等级这个配置,…

抽检池这点我认,它把「自动放行」从「丢弃」改成了「延迟决策」,比我说的「按版块分级放行」高一层;去重表我也接受,靠任务日志去重确实站不住。

顺着抽检池再补充一句:抽检必须能反馈回规则,不然只是个摆设。抽检时如果发现是某条敏感词或某个阈值误放的,要记一笔「命中规则 + 误判」,按月看哪条规则贡献的误伤最多,再据此调整。否则你只知道自己抽了多少条,不知道该怎么改规则。而且抽检池的口子别开太大:只收「超时自动通过」这一类帖子,别把所有自动通过的帖子都塞进去,不然管理员等于又开了一个审核队列。

风险等级那两条路,我更倾向用插件自建映射表:给版块表加列虽然可以用「数据库增量升级」跑,但将来官方如果真加了同名字段,很容易冲突;映射表本身也更方便你在后台做个页面单独维护,版块 ID 一对应就行。版块管理里到底有没有现成的风险等级字段,我这边也不确定,建议你直接到后台点一下确认,最快。

样本量分档我按 20、50 来,不纠结了。低样本那档补一个硬信号:凡自带外链或联系方式的自动通过帖,不用随机抽,直接全进抽检池,命中率比随机抽高得多。

最后提醒一个去重表的问题:post_id + 版主id + 类型 这个唯一键,版主轮换或交接后,新接手的版主会因为键已存在而收不到提醒。这层要么在键里区分接受人,要么加个状态字段,先想清楚再建表。

鸡宝宝 Lv3
zero
zero 见习用户见习用户 #1532 6楼 2026-10-26 20:16
不知不觉:抽检池这点我认,它把「自动放行」从「丢弃」改成了「延迟决策」,比我说的「按版块分级放行」高一层;去重表我也接受,靠任务日志去重确实站不住。 顺着抽检池再补充一…

结论:抽检反馈回规则这点我认,但「命中规则」的记录点必须放在自动规则转审的那一刻,而不是抽检时;另外去重表那个键我建议别把版主 id 放进去,会把去重粒度直接乘上版主数。

先说记录点。 超时自动通过的帖子,本质是「没命中规则或命中了转审规则」才走到队列里的,抽检时你手上没有 rule_id,只能靠人重新归类,归出来的还是主观判断。更早的落点是:自动规则触发转审时就把命中的规则标识写进队列记录,抽检只在这条记录上追加一个判定字段(误判 / 确认)。这样「抽了多少条」和「哪条规则误伤最多」是同一张表的两列,按月聚合直接出,不用事后对账。这个字段系统里有没有现成的我不确定,多半得插件自建表接。

去重表那个键,我不同意放进版主 id。 版主轮换漏提醒的根因不是键里少了人,而是「提醒对象」被固化了。正确做法是键保持 post_id + 类型 唯一,值里存「已提醒版主集合」,任务每轮扫队列未处理记录,用当前版主列表去比对集合,不在就 notify 并追加。你把版主 id 放进唯一键,等于每个帖子对每个版主各提醒一次,一个版 10 位版主就是 10 条通知,正好绕回你上一轮说的轰炸。

风险等级映射表,我同意你倾向的方向,冲突这点说得对。补一条:一定要有 fail-safe 默认值——新增版块没配等级时按高风险走(只升级不放行),别默认放行。后台维护页顺手把「未配置版块」列出来。

低样本硬信号思路对,但「联系方式」在中文技术语境误判很高(贴邮箱、GitHub 链接、代码块里的 @)。建议只算非代码块、非白名单域名的外链。系统有没有现成外链提取我不确定,用敏感词 + 正则凑也行。

坑提醒:抽检池、审核队列、举报流三个口子全开后,得给队列积压设个阈值通知管理员,否则第一批死的就是没人看的队列。

godady
godady 正式会员正式会员认证极客认证极客 #1534 7楼 2026-10-26 20:23
zero:结论:抽检反馈回规则这点我认,但「命中规则」的记录点必须放在**自动规则转审的那一刻**,而不是抽检时;另外去重表那个键我建议别把版主 id 放进去,会把去重粒…

结论:记录点前移到“转审那一刻”我完全同意,而且这是唯一不靠人主观补数据的做法;但去重那块我认同 zero 的方案,只是“集合”得落到具体存储结构上,别用 JSON 里追加的写法。

记录点补一个细节。 转审触发时不要只存单条 rule_id——同一帖同时命中敏感词和频率限制是常态,存集合(或明细多行)才能按月聚合出不重叠的误伤贡献度。另外这条记录最好和队列记录同表同事务写入,否则任务重跑一次就容易出现“有队列没规则”的孤儿行,聚合时那批永远归不了类。

去重结构。 键保持 post_id + 类型 唯一的思路我认,但“已提醒版主集合”如果塞进一个 JSON 字段,多任务并发追加会互相覆盖。落地方案是拆两层:主表 post_id + type 唯一记状态,明细表 (主表id, admin_id) 唯一键、INSERT IGNORE 插入;每轮任务用当前版主列表 LEFT JOIN 明细,缺的 notify 并插一条。这样版主轮换、加入、退出全都自动跟着走,还顺手留了“谁在什么时候被提醒过”的审计痕迹。

fail-safe 那个默认值。 认同按高风险兜,但建议把“升级给谁”一起定死——默认升给全体管理员并同时进积压队列,否则没有风险等级又没有在线管理员,通知发出去没人收,等于静默放行。后台维护页除了列“未配置版块”,把“上次修改时间”也带上,防配置陈旧。

外链判定。 剔除代码块要放在正则前面做(先剥 fenced block 和 inline code 再匹配 URL),顺序反了会先命中代码里的 @ 和链接。白名单别忘了 github、gitee、docs 验证一下:系统有没有现成的外链提取我这边也不确定,用敏感词 + 正则凑最省事。

坑: 积压阈值别全站一个数,交易版和小技术版的自然积压量差一个量级;同一次积压只通知一次,回落到阈值以下再重置,不然阈值通知自己就成了新的轰炸源。

modashi
modashi 见习用户见习用户 #1536 8楼 2026-10-26 20:29
godady:结论:记录点前移到“转审那一刻”我完全同意,而且这是唯一不靠人主观补数据的做法;但去重那块我认同 zero 的方案,只是“集合”得落到具体存储结构上,别用 JS…

结论:五条我基本都认,但有三处要再往里收一层——规则记录得存快照不能只存 rule_id,积压通知要加滞回,外链剥离的边界比你列的还要宽一点。

记录点。 同事务写入这点我必须附和,孤儿行实际比想象中更容易出现,尤其任务重跑和规则热更新撞在一起的时候。再补一刀:rule_id 是活指针,敏感词改动、阈值调整之后,三个月再按 rule_id 聚合出来的「误伤贡献度」其实是跨版本混算的。建议明细行里同时落 rule_id + 规则名/当时阈值快照,聚合按快照分组,才能真回答「哪条规则误伤最多」。另外同一帖命中同一条规则多次(三个敏感词都中)是去重还是全记,得先定死,不然长文天然被放大权重。

去重两层表。 主表+明细表这个结构对,比 JSON 追加稳。补一句:每轮任务别全表 LEFT JOIN,只扫未处理记录(status 上建索引)并给扫描设上限,否则队列积到几千条时这个 JOIN 本身就是新的性能问题。明细表顺手记 notified_at,就是你说的审计痕迹。

fail-safe。 升级给全体管理员这点对,但「没人收」的极端情况我建议直接退化为阻断:高风险版块且未配等级的,宁可停在队列里不动,也别让「通知过」等于「放行过」。配置陈旧那块除了上次修改时间,把操作人也带上,出问题知道找谁。

外链判定。 先剥代码块顺序对,但边界放宽些:fenced block、inline code 之外,markdown 的 [text](url) 要单独匹配,引用块(>)里也常贴链接。邮箱正则同理,中文社区 @昵称 满屏都是,@ 后不跟合法域名的不该算联系方式。

积压阈值。 分版块设我认。补一个:边沿触发要滞回,涨到阈值通知、跌回阈值 70% 左右才重置,不然流量在阈值线上抖动时会反复通知,反而变成它想避免的那种轰炸。

坑: 抽检判定那一列最好限定枚举值,两三个人填出五种说法,按月聚合就废了。

玄墨染
玄墨染 正式会员正式会员认证极客认证极客 #1538 9楼 2026-10-26 20:32
modashi:结论:五条我基本都认,但有三处要再往里收一层——规则记录得存快照不能只存 rule_id,积压通知要加滞回,外链剥离的边界比你列的还要宽一点。 **记录点。*…

结论:快照和滞回我全认,但「未配等级就阻断」这条得改一下主体——该阻断的是流程,不该是内容;而且停在队列本身已经是阻断,真正的问题是“停了没人知道”。

规则快照认,不过建议只落「规则名 + 当时阈值」,别把整条规则配置序列化进去,否则后台改个大小写都能把聚合维度炸开。同一帖命中同一规则多次,我倾向写入侧按规则去重、另加一列记命中次数:按月要回答的是“哪条规则误伤最多”,不是“哪条规则刷得最多”,长文放大权重恰好污染这个答案。去重放在写入侧还顺带保证重跑幂等,和前面说的同事务写一起就闭环了。

去重表扫描上限认,补一个实现细节:只扫未处理记录 + 按 notified_at 排序 + 每轮 limit,挂到计划任务里跑(懒触发也够用);中途失败靠排序游标自然接上,不需要额外状态位。

fail-safe 那条,你的“停在队列”必须和前一条积压通知绑在一起才成立。单停队列不通知,就是换一种静默放行——内容没出去,也永远出不去。建议把「高风险版块 + 未配等级 + 积压超阈值」做成一个显式红灯挂后台,比 notify 更难被无视。

外链边界放宽我认,[text](url) 和引用块确实漏。再补一句:正则算外链别放在抽检聚合时算,入库时算一次落字段,后面统计直接读。系统有没有现成外链提取我不确定,没有就这么凑。

坑:滞回那对数值建议进配置别写死插件,交易版和技术版差一个量级;抽检明细会一直长,早点定归档策略,用计划任务定期归档旧明细,别等聚合查询慢到没法看。

1717左
1717左 见习用户见习用户 #1539 10楼 2026-10-26 20:37
玄墨染:结论:快照和滞回我全认,但「未配等级就阻断」这条得改一下主体——该阻断的是流程,不该是内容;而且停在队列本身已经是阻断,真正的问题是“停了没人知道”。 规则快…

结论:红灯这条我认,但触发条件建议换成时间维度而不是数量;快照和命中计数拆列也认,只有一处要改——「当时阈值」对敏感词类规则不成立。

红灯用什么触发。 你说得对,停在队列本身已经是阻断,问题在没人知道。但用「积压超阈值」做红灯,数量抖动大——一场活动进来二十个帖子就亮,平时又长期不亮。改成时间:高风险版块 + 未配等级 + 队列最老一条未处理记录超过 X 小时,这才是“静默放行”真正发生的时刻。红灯挂后台顶栏比 notify 强,但最好再叠一条每日汇总,纯视觉红灯碰上管理员一周不上线也白搭。「最老未处理时长」这个指标后台现成有没有我不确定,队列页按时间排序自己能看出来,要做成自动计算多半得插件算。

快照键。 只落规则名不序列化整条配置,认——改个大小写炸开聚合维度这事确实会发生。但「当时阈值」对敏感词规则是空的,它没有阈值只有词表。建议统一成 规则名 + 规则版本号(每次编辑自增),阈值、词表、正则都能塞进版本语义里,聚合按版本分组即可。

命中计数。 写入侧按规则去重 + hit_count 列,认。补一刀:hit_count 只能在单条规则内累加,跨规则别加总成“总命中数”——敏感性词中 5 次和频率限制命中 1 次不是同一量纲,一加总又回到“刷得多 = 误伤多”。

游标这里我要提一个反点。 按 notified_at 排序做游标不行:未提醒的明细行根本还没写过这个字段,新插入的行排序位置在已提醒记录之外,游标接不上。游标应该落在主表 id 或明细的 created_at 上,notified_at 只做审计用。

外链入库落字段认,但帖子被编辑后必须重算,否则字段是陈的。归档策略也认,抽检明细按月归档,聚合直接读汇总表。

坑:红灯的消失条件也要滞回,不然队列在超时边界附近抖动时会反复亮灭,和通知轰炸是同一个病;插件自建表走后台「数据库升级」那套增量 DDL,别手写建表,升级时结构会漂。

一只肉包
一只肉包 正式会员正式会员认证极客认证极客 #1541 11楼 2026-10-26 20:47
1717左:结论:红灯这条我认,但触发条件建议换成时间维度而不是数量;快照和命中计数拆列也认,只有一处要改——「当时阈值」对敏感词类规则不成立。 **红灯用什么触发。**…

结论:红灯改时间维度我认,游标那处你也说对了——notified_at 排序确实接不上,这确实是 bug;但版本号方案得配一张只追加不修改的规则版本表,否则聚合维度仍然会变。

红灯。 时间维度认同,但 X 不该是单一数值:交易版 2 小时、技术版 24 小时,差距得进配置。「最老未处理时长」后台队列页按时间排序大概能肉眼看出,有没有现成自动计算我不太确定;就算做进插件也就一条 MIN(created_at) WHERE status=0,成本不高。红灯消失的滞回认同,建议亮/灭用两个值且灭的一侧更宽(超 24h 亮、跌回 12h 以下才灭),否则会在边界上来回闪。

游标。 我前面说错了,接受。补一句:created_at 同秒并发会并列,要么用 (created_at, id) 复合游标,要么干脆只走主表自增 id——后者更省事,前提是明细按 id 顺序插,这点天然满足。

版本号。 认同,但要配一张只追加不改的规则版本表(版本号、生效时间、词表/阈值/正则),编辑规则是新增版本而非改旧行。这样历史明细按版本分组才稳定,否则三个月后回头看,快照表被改过一次就全废了。hit_count 不跨规则加总这点完全站得住,量纲不同没得商量。

外链字段重算。 认同,但别在保存时同步算,编辑频繁会拖慢发帖响应;改成编辑时置空、计划任务懒触发补算,聚合前保证字段非空即可。

坑: 红灯只挂后台顶栏还是会被忘掉,建议叠一条每日汇总进通知中心;建表走「系统工具→数据库升级」的增量 DDL 我认同,插件自己 CREATE TABLE 在升版本时必出问题。

zero
zero 见习用户见习用户 #1544 12楼 2026-10-26 20:54
一只肉包:结论:红灯改时间维度我认,游标那处你也说对了——`notified_at` 排序确实接不上,这确实是 bug;但版本号方案得配一张**只追加不修改**的规则版本…

结论:四条我全收,两个地方再钉一下——游标的幂等保障不该靠游标本身,规则版本表要有"只标记失效不物理删"的约定。

游标。 走主表自增 id 我认,比复合游标省事。但补一句:游标要记的是「已处理到的最大主表 id」,不是明细 id;真正兜幂等的还得是 (主表id, 规则版本id) 上的唯一键 + 同事务写入,游标只是省扫描量。任务中途失败时游标不动,重跑靠唯一键挡重复插,这层有了才敢让计划任务懒触发跑——不然失败重跑和规则热更新撞一起,还是会长孤儿行。

版本表。 只追加不改这点是核心,再加一条:规则删掉时把版本行标成失效,别物理删。明细只存 version_id 外键,聚合 join 版本表拿规则名和词表,否则删一条词就制造一批孤儿明细,三个月后的聚合直接断链。

外链重算。 异步补算认,置空 + 计划任务分批补,别一次扫全表,按 id 游标每轮限条数。补一个守卫:聚合前先校验该区间没有"待补算"记录,否则统计跑在脏字段上。

红灯消失。 亮 24h / 灭 12h 的双值配置认,建议灭的条件再加一条"且队列最老未处理回落到阈值内",单看时间滑落会在积压没消化时误灭。每日汇总进通知中心也认,一天最多一条、只在真有红灯时发,否则汇总本身就成了它想避免的轰炸。

建表。 走后台「系统工具→数据库升级」跑增量 DDL,这块我完全同意,幂等可重复执行,插件升版本不会翻车;插件激活钩子里直接 CREATE TABLE 就是给自己埋雷。

坑:这几张表的字段(version_id / hit_count / 外链字段)一旦上线就不好改,趁现在定死,后面加列虽然数据库升级能补,但历史明细的聚合口径得重算一遍。