1138 字
6 分钟
做了个追星小程序《偶像簿》

最近做了个追星的微信小程序叫《偶像簿》,这个小程序可以展示 ins 上的明星的信息,最主要的是完全免费,展示的信息也都是高清无水印的。
说一说遇到的问题吧,小程序的数据来自三方 ins 平台,在抓取时每一页都有一个游标,抓取只能顺序串行进行无法跟第几页那样去抓取,最开始还比较奇怪这个设计,不太懂为什么这么设计,直到我自己做这个小程序的时候才发现问题的关键所在。

- 我做的小程序的列表页如图,其中推荐页面有几十万条帖子,在进行分页时倘若服务端使用一般的 offset 和 limit 去进行分页的话会有一系列的问题暴露出来。
- 问题1:当 offset 过大时分页查询特别慢
- 这是查询时不可避免的问题,当 offset 过大时每次去跳过的数据量特别多因此查询的速度变慢了
- 问题2:正在加载下一页时候倘若此时有用户发布了新的帖子就会出现重复的帖子被加载出来
- 这个问题的原因不复杂,举个例子,假设每一页加载 10 条数据,我现在加载第二页数据,此时用户发布了新的帖子,那我加载第二页数据时的 offset 就是 10,因为用户发布了一条新的帖子所以 offset 的为 10 的位置变成了最开始的 9 的位置,因此会重复加载第十条数据放置在了第二页,因此在滚动时就会出现重复的帖子。
- 出现了这种情况才理解了为什么 ins 上使用游标分页而不是页码分页。
- 我还有一个搜索页面如下:
因为ins上的数据量过于庞大,我希望当用户搜索出来后点击该明星时如果这条数据不存在我的数据库中那么我就去抓取该数据,想法很简单想了多种实现方案说一说都有啥问题
- 方案1:用户点击该明星后数据不存在就去抓取ins需要满足几个条件:相同明星不能重复抓取、抓取失败需要可以重新抓取、抓取时用户可以感知到正在收录中。
- 抓取的部分我单独放在了一个仓库中,想的是单独起一个服务来做抓取的工作,或者直接与我的服务端放在一起,这样子就很简单的可以做到没有收录时就去抓取。抓取中使用redis来做互斥锁来避免重复抓取。
- 方案2:抓取部分放在github的actions中去做抓取,使用workflow通知github的actions去执行即可,这样子可以忽略掉抓取的服务器开销。
最终采纳了方案 2,原因是 github 的 actions 的带宽比我的应用的带宽大的多,去跑一些抓取任务非常合适,其次使用了 redis 来做互斥锁,互斥锁的 key 使用的是抓取的明星 id 作为 key,可以很好的避免 actions 重复执行,还增加了 MQ 层,通过了 MQ 来做抓取失败的重新入队操作,增强了稳定性。在抓取完成后释放互斥锁。避免互斥锁释放不掉,因此给互斥锁设置了一个较大的过期时间,即使 actions 的 webhook 请求失败也不会导致锁释放不掉。
抓取部分使用了多账户的能力,注册了 5 个账号通过随机取号的方式去抓取信息,减小了单个账号请求数据量过大被封禁的风险。
因本人没有钱没办法去使用付费代理池,免费的稳定性又太差,只能从采用上述的方法了,经过测试目前封禁了一个账号,我又减小了爬取的频率和并发,到目前剩下的四个账号均正常使用。感兴趣的小伙伴可以直接微信扫下方的小程序码去体验一下吧~





