ThreadPoolExecutor使用多个PriorityBlockingQueues

时间:2018-02-05 23:27:17

标签: concurrency java-8 priority-queue

我的任务是调度&在java 8中执行大量web请求,具有以下条件:

  1. 每个网络请求都属于不同的组之一

    • web请求所属的组是请求的不可变和确定性属性(即,不是某些(伪)随机逻辑的结果,例如,想象用户代表请求正在制作
  2. 网络服务正在跟踪每个不同群组收到的网络请求的配额使用情况

  3. 网络请求可能会在任何给定时刻收到HTTP 429(太多请求),表明该组的配额已满

    • 当发生这种情况时,在响应的Retry-After标题所指示的时间之前,不允许进行同一组的Web请求,这些无效请求仍然算作配额的一部分
    • 非限制组的网络请求可以并且应该被处理,而不管其他一些组受到限制
  4. 有些请求比其他请求更平等,因此符合条件的请求应按优先顺序处理

  5. 这些不同的配额组的数量是几百个(现在) 在任何特定时刻,可能会出生一个新的团体,例如新用户加入组织

  6. 我一直在收集一些我不满意的想法:

    • 最明显的是,每个组都可以由他们自己的ThreadPoolExecutor处理,并使用相应的PriorityBlockingQueue

      • 简单有其优点,但我不喜欢运行数百个ThreadPoolExecutors实例(即使每个实例都使用单个线程执行)。
    • 我可以(尝试)沿着繁琐且容易出错的路径实现我自己的BlockingQueue,并为每个组维护一个PriorityQueue

      • BlockingQueue中的接口方法数量并不多,但该并发库的设计者认为适合扩展Collection和Queue接口,只需要花费大量时间来实现所有那些方法和测试它们听起来像是(危险的)浪费时间给我
    • 我还可以放松让非限制群体和请求进展的目标,并阻止所有请求直到规定的时间

      • 这可能没有听起来那么糟糕,我仍然需要检查达到配额限制是多么容易以及时间罚款是什么 - 其他一周的5分钟停电听起来几乎可以接受,每个午夜半小时绝对不行
    • 另一个想法是让ThreadPoolExecutor具有单个PriorityBlockingQueue(PBQ)和一个限制组映射 - >请求列表在旁边

      • 有几次(在提交时,从主PBQ消费,甚至刚刚收到HTTP 429响应),请求组将被测试被限制,如果是这样,请求将被置于那个受限制的群体 - >请求列表地图
      • 但通常情况下,ThreadPoolExecutor只会消耗请求
      • 当然,每当HTTP 429响应的Retry-After标头指示的某个限制周期结束时,相应的组将被唤醒并且所有请求将被重新提交给主PBQ
    • 我也一直在阅读RxJava,但延迟,油门或背压设施都不合适 - 或者至少我不知道怎么做。

    此时我真的不希望任何伪代码(好吧,除非它实际上更短),但我最感兴趣的是更好的想法或者指向现有设施。

    (顺便说一下,网络服务是Microsoft Graph API,万一有人想知道。)

0 个答案:

没有答案