V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
crayfish
V2EX  ›  程序员

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

  •  
  •   crayfish · 2023-09-09 05:06:42 +08:00 · 805 次点击
    这是一个创建于 443 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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

    runner 随意并发,获取 token ,根据 token 请求即可。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5539 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 08:27 · PVG 16:27 · LAX 00:27 · JFK 03:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.