协同办公

Odoo 链接预览为什么不会无限抓网页:预览缓存、域名节流与消息同步边界讲透

很多人以为消息里贴链接后,Odoo 就会每次现抓网页生成卡片。源码里的 `mail.link.preview` 实际做了 URL 去重、消息与预览关系表、域名级节流和最多预览数限制。也就是说,链接预览是被严格控成本、控噪音的协作增强,不是无上限爬虫。

协同办公
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 5 阅读

先说结论

Odoo 的链接预览不是“每次看到 URL 都重新抓网页”。

它本质上是一套带缓存、关系映射、域名节流和数量上限的预览系统,目标是提升协作体验,而不是把消息系统变成无上限抓取器。

这就是为什么有些链接会秒出卡片,有些不会,有些又会沿用旧预览。


一、预览不是直接挂在消息正文里

源码里有两个层次:

  • mail.link.preview:存 URL 对应的预览数据
  • mail.message.link.preview:存消息与预览的关系

这说明 Odoo 不想让每条消息都拷贝一份预览数据。

更合理的做法是:

  • 相同 URL 复用同一个预览实体
  • 每条消息只维护自己和预览的关联与顺序

这样既省存储,也方便更新和广播。


二、为什么不是所有链接都抓

_create_from_message_and_notify() 里有多道限制:

  • 只从消息 HTML 里提取合格链接
  • 会忽略某些站内 Odoo URL
  • 单条消息最多只保留有限数量的预览
  • 域名级节流命中后不再继续抓

这说明链接预览在 Odoo 里不是“尽可能多”,而是“够用且不失控”。


三、域名节流为什么很关键

_is_domain_thottled() 会按域名统计短时间内创建的预览数量,并结合配置参数判断是否节流。

这么做的意义很直接:

  • 防止某个高频域名引发大量外部请求
  • 降低消息系统被恶意链接刷爆的风险
  • 避免贴很多相似链接时拖慢协作界面

也就是说,Odoo 很清楚链接预览虽然好看,但它本质上是在花网络和处理成本。


四、为什么旧预览会被复用

如果数据库里已经有相同 source_url 的预览,系统会优先复用,而不是重抓。

这是个很典型的协作产品思路:

  • 预览信息通常不是秒级必须刷新
  • 大多数情况下,复用已有卡片性价比更高

当然代价就是:

  • 某些网页后来变了
  • Odoo 里的预览可能不会立刻跟着变

但对消息协作来说,这通常是可以接受的折中。


五、为什么删除/更新也要通知前端

创建完或更新完消息预览后,源码会通过 Store / bus 把 message_link_preview_ids 推给前端。

这说明链接预览被视为消息对象的一部分协作视图,而不是后台懒得刷新的附属信息。


六、最容易踩的误区

误区 1:每个链接都应该立刻有预览

不对,可能被节流、过滤或超出数量上限。

误区 2:同链接每次都会重新抓

不对,命中缓存就复用。

误区 3:链接预览失败一定是 bug

不一定,很多时候是成本控制机制在生效。


七、排错顺序

当用户问“为什么这条消息没有预览卡片”时,建议按这个顺序查:

  1. 消息正文里是否真的是可解析链接
  2. 是否被站内 URL 过滤掉
  3. 同一消息是否已达到预览数量上限
  4. 该域名最近是否触发节流
  5. 是否已有旧预览被复用但前端尚未刷新

最后一句

Odoo 链接预览的核心设计,不是把网页抓得越全越好,而是在协作体验和系统成本之间找到一个可长期运行的平衡。

这也是它看起来“没那么激进”的原因。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。