为旧帖子错误地创建通知

昨天,我的网站突然开始为旧帖子生成通知。这是过去几天内创建时间晚于一小时的“已发布”通知(notification_type = 9)的数量:

用于生成该表的查询语句
WITH pre AS (
	SELECT
		p.id as post_id,
		to_char(n.created_at,
			'YYYY-MM-DD') AS notified_day,
		p.topic_id,
		round(least(EXTRACT(EPOCH FROM n.created_at - p.created_at)::numeric, EXTRACT(EPOCH FROM n.created_at - p.updated_at)::numeric) / 3600)  AS hours_diff,
		p.created_at,
		p.updated_at,
		n.created_at,
		u.username
	FROM
		notifications n
	LEFT JOIN posts p ON p.post_number = n.post_number
		AND p.topic_id = n.topic_id
	left join users u on u.id = n.user_id
WHERE
	round(least(EXTRACT(EPOCH FROM n.created_at - p.created_at)::numeric, EXTRACT(EPOCH FROM n.created_at - p.updated_at)::numeric) / 3600) > 0
	AND n.notification_type = 9
ORDER BY
	n.created_at DESC
LIMIT 400
)
SELECT
	count(*), 
	notified_day
FROM
	pre
GROUP BY
	notified_day
ORDER BY
	notified_day DESC

以下是几个示例(通过运行上述查询中的 CTE 获得):

第一行高亮显示的通知创建于 12 月 8 日,但一位关注该分类的用户在 12 月 25 日收到了通知(据其他用户反馈,他们也在收到关于已查看帖子的通知)。

第二行高亮显示的通知创建于 9 月 29 日,次日被修改,并在 12 月 25 日发送了通知。

我刚刚重建了容器,因此现在运行的是最新版本的 Discourse。目前我已禁用了邮件通知。

有什么建议可以帮助我排查此问题吗?我猜测可能是某个队列因某种原因积压了,或者类似的情况。有没有办法找出是哪些操作生成了这些通知?

1 个赞

我的猜测是,这些是过去因某种原因失败的 Sidekiq 任务,而你“修复”了某些问题,导致这些通知现在发出,而不是在原本应该的时间发出。你可以查看 /sidekiq,看看是否有可以在此处删除的任务,以免它们被处理。

2 个赞

Jay,你的猜测很对。我注意到过去几天用户报告该问题时,相关数据有所上升:

我检查了计划队列,发现并没有大量未处理的消息积压。相反,大约每 10 分钟就会新增几十条这类过期的通知。

能否追踪一下是什么在向 Sidekiq 发送这些通知?

1 个赞

该问题似乎在几天后自行得到解决(幸运的是),但深入分析让我意识到我最初的 SQL 查询不完整:notifications.post_number 字段指向给定主题中第一条未读帖子,但每当有新帖子创建时,其 notification.created_at 都会更新为新的 posts.created_at

这解释了我观察到的一些时间差异,但无法解释那个神秘出现又消失的激增现象。

要修复该查询,我必须先检查 post_timings,找到给定用户已查看的最新 topic_id/post_number,并使用其 created_at 来替代来自 notifications 的时间戳。

1 个赞