You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发新闻RSS抓取API时,捕获重复条目异常提升性能是否可行?

问题分析与优化方案

性能假设验证

你的两处性能判断均符合实际场景:

  • 逐条查询数据库判断条目是否存在,会让单次写入操作多一次网络IO请求,整体处理效率至少下降50%,数据量较大时延迟会非常明显
  • 全量查询10万+条guid存入内存构建Map,不仅会占用大量JVM堆内存,全量查询本身对数据库的IO压力也很高,确实不适合长期运行

最优解决方案

推荐你分层实现去重,兼顾性能和资源占用:

  1. 数据库层兜底去重(核心方案)
    你已经为article表的url字段设置了唯一索引,直接使用MySQL原生的INSERT IGNORE语法即可,重复数据插入时数据库会自动忽略该条写入,不会抛出Duplicate Entry异常,也不需要提前做查询判断,性能损耗极低。
    如果业务需要更新已存在的旧文章内容(比如内容有修订),可以替换为ON DUPLICATE KEY UPDATE语法,重复时自动更新指定字段即可。
  2. 批量插入优化
    你当前的循环单条写入效率很低,调整为批量插入模式,配合INSERT IGNORE语法一次提交10~100条数据,可大幅降低数据库的网络IO开销。
  3. 轻量缓存前置过滤
    RSS内容具备强时效性,新抓取的Feed中几乎不会出现2小时之前发布的旧内容,你可以用Caffeine等本地缓存组件,只缓存最近2小时入库的文章guid,每次抓取到新条目后先查本地缓存,缓存中不存在的再发送到数据库执行写入,进一步减少无效的数据库请求。该方案缓存的条目最多只有数千条,完全不会占用过多内存。
  4. 日志级别调整
    原本捕获异常的逻辑可作为兜底容错方案,但是重复数据的日志不需要设置为error级别,调整为debug或info即可,避免日志文件被无效信息占满。

代码示例

自定义写入方法(Spring Data JPA 实现)

在你的ArticleRepository接口中新增原生SQL写入方法:

@Modifying
@Transactional
@Query(value = "INSERT IGNORE INTO article(title, url, content, guid, rss_feed_id, pub_time) " +
        "VALUES (:#{#article.title}, :#{#article.url}, :#{#article.content}, :#{#article.guid}, :#{#article.rssFeedId}, :#{#article.pubTime})",
        nativeQuery = true)
int insertIfNotExists(Article article);

批量插入实现(JdbcTemplate 实现)

public void batchSaveArticles(List<Article> articles) {
    String sql = "INSERT IGNORE INTO article(title, url, content, guid, rss_feed_id, pub_time) VALUES (?,?,?,?,?,?)";
    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
            Article article = articles.get(i);
            ps.setString(1, article.getTitle());
            ps.setString(2, article.getUrl());
            ps.setString(3, article.getContent());
            ps.setString(4, article.getGuid());
            ps.setLong(5, article.getRssFeedId());
            ps.setTimestamp(6, Timestamp.valueOf(article.getPubTime()));
        }
        @Override
        public int getBatchSize() {
            return articles.size();
        }
    });
}

注意事项

如果不同RSS源的guid可能存在重复,建议将唯一索引调整为(guid, rss_feed_id)联合唯一键,避免不同源的相同guid被误判为重复内容。

内容的提问来源于stack exchange,提问作者Lukonjun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:57:03