我有一个在netty中实现的服务器,它处理用户请求,与中间件通信,并发送响应.的I/O,预计相对于往返于中间件可忽略不计,因此最大限度地减少阻塞I具有在上OrderedMemoryAwareThreadPoolExecutor的顶部时流水线上的ExecutionHandler.到目前为止没问题.
我正在研究服务器在高负载下的行为.根据我们对协议的过去经验,我们倾向于被意外的DOS攻击所淹没 - 通常,用户的脚本陷入无限循环或类似情况.理想情况下,我们可以在通过某个使用阈值后对其频道进行去优先级排序,以便其他用户的服务不受影响.
我已经实现了一个简单的ThreadPoolExecutor,它使用PriorityBlockingQueue并根据从我们自己的Session类中提取的数据设置优先级(附加到ChannelHandler中的上下文).到目前为止,没有问题.
当试图利用netty的内置ThreadPoolExecutors的排序和内存意识时,困难就出现了.理想情况下,MyThreadPoolExecutor可以只扩展OrderedMemoryAwareThreadPoolExecutor并连接优先级队列.唉,这是不可能的,原因有二:私人和最终.更详细:
一)ThreadPoolExecutor.workQueue可以在构造函数中设置,但MemoryAwareThreadPoolExecutor硬编码这是一个LinkedTransferQueue,并且不公开这个到其子OrderedMemoryAwareThreadPoolExecutor(即MyThreadPoolExecutor没有访问设置).如果有必要,可以通过一些基于反射的私人场调整来克服这个问题.
b)我希望能够覆盖MyThreadPoolExecutor.doUnorderedExecute(),这样我就可以插入优先级处理并构造必要的对象,但它被声明为final.调用它的代码不需要更改.
其结果是,把所有漂亮的网状功能,但使用优先级队列,我将不得不copy'n'paste既OrderedMemoryAwareThreadPoolExecutor和MemoryAwareThreadPoolExecutor,调整一对夫妇每行,然后从那里延伸.这并没有让我感觉良好的编码习惯!即使考虑到它也引发了警钟.
现在来几个问题:
1)我解决了错误的问题吗?我为了达到目的而完全错误地吠叫了吗?
2)如果没有,有没有比上面讨论过的更好的方法呢?
3)上述方法为去除优先级的任务带来了饥饿的风险,其中总服务器负载始终处于容量.我准备为"顽皮"的用户容忍这一点,但是一旦他们恢复到正常状态,他们现有的任务仍然会挨饿,并且为了保持排序,必须在他们后面添加任何新的,更高优先级的任务.你有什么建议可以解决这个问题吗?(业务不允许禁止用户.)
4)这是半问题,半反馈.OrderedMemoryAwareThreadPoolExecutor的netty文档有一个方便的线程X和Y图 - 可能这些是ThreadPoolExecutor中汇集的线程,而不是I/O工作线程?值得一提的是这一点.此外,当不使用ExecutionHandler时,每个通道都绑定到一个I/O工作线程 - 在ExecutionHandler后面仍然是这种情况吗?即,是否将任务添加到ExecutionHandler的顺序保证与它们到达Channel中的顺序相同?如果是这样的话,那么我看不出在这个文档的MemoryAwareThreadPoolExecutor线程X可能事件1之前处理事件2 - 我承认,这里不同的线程可以以任意顺序完成的工作,但我看不到的工作如何能不按顺序分配给同一个线程(它从workQueue弹出).ExecutionHandler中的文档暗示了这一点,但会从更多细节中受益.
非常感谢阅读,任何帮助都非常感激.
您的“警铃”解决方案看起来很熟悉 - 只需从较小的池大小开始即可。
您似乎在说您需要一个针对缓慢服务器的解决方案。您可能想了解为什么您的服务器在负载下变慢。- 线程争用(竞争)问题。- 初始池大小 - GC 配置
| 归档时间: |
|
| 查看次数: |
2143 次 |
| 最近记录: |