问一个业务相关的类似主备切换的方案

2023-09-09 05:06:42 +08:00
 crayfish

业务场景: 我个人项目需要获取一个数据,需要大量调用网站的 api 去获取数据,然后他们一般都有调用次数限制,次数到了就返回错误或空.

情况: 所以我就找了多个网站的相同功能的 api,然后用一个循环链表连起来,当一个 api 响应失败的时候调用下一个链表的 api 如果还是失败就返回 error

问题: 然后现在问题来了,我需要并发情况下去调用这些 api,因为她们响应速度实在太慢,但是不加锁我怎么保证指向下一个链表的操作只执行一次. 我知道最简单的方法是 api 请求前加锁响应后释放,但是我一次请求估计要调用几十上百次 api 加了锁估计得等几分钟才能响应,所以有什么更好的方案去实现这个功能

补充一下我的项目是用 go 写的

862 次点击
所在节点    程序员
3 条回复
seth19960929
2023-09-09 10:46:55 +08:00
你的描述有问题, 没有人能理解你说的是什么. 既然你是上一个失败, 才链式调用下一个. 那么何来并发只说. 也无上锁之说.
你要说你并发调用链表中所有, 任意一个成功就可以返回, 或者所有失败的话. 那么就用 ctx, 所有 request 公用一个 ctx
ctx,cancel := context.WithCancel()
当有成功的一个, 主动调用 cancel() 函数, 其它 http client 就会取消
ccde8259
2023-09-09 12:49:50 +08:00
环状列表+头指针
读操作其实是可以 LockFree 的,所有请求拿一份环状列表+头指针的快照回来,存一个尾指针指向下一个对象,第一个请求失败以后就取尾指针,顺序调用第二个,尾指针下移直到尾指针指向头指针。
SmiteChow
2023-09-11 10:07:17 +08:00
还是用锁,但是要把这个锁暴露为 token ,因为你的 runner 需要并发请求。

实现一个 token 管理员服务,生成分发 token (注意加读写锁),比如生成如下 token 列表 [主,主,主,备,备]

runner 随意并发,获取 token ,根据 token 请求即可。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/972182

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX