| ts | AbstractThreadPool | DefaultZoneOrderedDelayEventThreadPoll | OrderedDelayEventThreadPool | OrderedDelayEventThreadPoolNew |
|---|---|---|---|---|
| 最大延迟ms | 2549 | 2588 | 10491 | 2538 |
| 总延迟ms | 2567280 | 2314471 | 18628439 | 2303540 |
| 执行时长s | 13 | 10 | 11 | 10 |
| 事件竞争公平 | 是 | 是 | 否 | 是 |
| 自动调节 | 否 | 是 | 是 | 是 |
- 从任务调度粒度上看,mina会将有IO任务的session写入队列中,当循环执行任务时,则会轮询所有的session,并依次把session中的所有任务取出来运行。这样粗粒度的调度是不公平调度,会导致某些请求的延迟很高。
可以看出 這四種不同策略的線程池 在執行效率上幾乎是一樣的 區別在於
- AbstractThreadPool 這種固定線程數的策略類似Netty EventLoopGroup 無法根據流量自動調節線程數,且某個無關事件卡住後,整個線程上的事件都受影響
- OrderedDelayEventThreadPool
- 根据事件业务ID分区,如玩家的uid/战局的rid,每个ID单独一个分区。
- 根據流量自動調節線程數
- 各分區事件獨立互不影響:某個無關事件卡住後,只影響所屬分區的事件;
- 缺點是:粒度細的分區, 粗粒度的调度(类似于MINA的OrderedThreadPoolExecutor) ,会持续处理某个分区的事件,无论该事件的先后顺序,直至其事件处理完,才会处理下个分区的事件,導致某些分區的事件延遲過高,出現不穩定的卡頓現象
- DefaultZoneOrderedDelayEventThreadPool
- 针对OrderedDelayEventThreadPool 粒度細的分區, 粗粒度的调度,采用固定分區數量(=最大線程數)根据业务ID将事件散列在不同的分区(ID%分區數量)
- 根據流量自動調節線程數
- 同一分区的不同业务按顺序执行,避免某个业务ID的事件集中执行,其他业务ID的事件在等待执行,导致延迟不均
- 某個無關事件卡住後,只影響所屬分區的事件,但分區粒度粗,影響比OrderedDelayEventThreadPool广
- OrderedDelayEventThreadPoolNew
- 同样是对OrderedDelayEventThreadPool的改进,避免某个业务ID的事件集中执行
- 根据事件业务ID分区,如玩家的uid/战局的rid,每个ID单独一个分区。
- 记录分区中是否有事件正在被处理及处理该事件的线程
- 下个事件可执行时,放到正在处理当前分区的线程的队列中,等待执行,否则分配空闲线程
- 根據流量自動調節線程數 各分區事件獨立互不影響
- 某個無關事件卡住後,整個線程上的已被分配的分區的所有消息 都會受影響
总结
业务中采用 DefaultZoneOrderedDelayEventThreadPool较为合适
OrderedDelayEventThreadPoolNew.java
OrderedDelayEventThreadPool.java