java disruptor压测_基于Disruptor游戏服务器消息总线的设计

我们原先的设计是基于LinkedBlockingQueue进行投递的,生产和消费都用到了锁,生产用的是putLock,消费是takeLock。替换成Disruptor后,生产时锁消失,消费时由于用的是BlockingWaitStrategy策略,所以还存在锁,但由于是单线程消费所以,基本没什么锁竞争的消耗。

以下是测试测试环境:

model nameIntel(R) Xeon(R) CPU E3-1230 V2 @ 3.30GHz

cpu core8

cache size15360 KB

OSWindows 7 64bit

JDK1.8.60

Disruptor3.3.2

ringBufferSize33554432

producerTypeProducerType.MULTI

WaitStrategyBlockingWaitStrategy

从消息处理量进行对比:

处理的消息数量:32*1024*1024=33554432

耗时对比:

49493105

Duration(ms)LinkedBlockingQueueDisruptor对比

15771420973%

25725347960.77%

35433322859.41%

45297280552.95%

55745247743.12%

66124242839.65%

088d8ca8e80a588047c95b4b8cb09b7e.png

QPSLinkedBlockingQueueDisruptor对比

158143187972067137%

258610369644850165%

3617604110394805168%

4633461111962364189%

5584063213546400232%

6547916913819783252%

8486ce5c2e2149dde13caae991b64636.png

分析:当线程较少时,性能提升并不是很明显,单线程时耗时降为原先的73%,QPS提升到原先的137%,随着线程数增多,性能提升幅度越来越大,当生产者为六根线程时,耗时已经降为了原先的39.65%,QPS处理量已经达到了252%,可以预见,线程越多,性能提升越大。

而LinkedBlockingQueue,当线程数<=4时,随着线程数增多,多线程的处理消息的正面效果大于锁竞争带来的负面效果,所以性能慢慢提升,但超过5根后,效果反转,性能表现越来越差,可以预见,线程越多,性能会越来越差,在各方面表现上都完败Disruptor.

从CPU占用来看:

LinkedblockedQueue压测时的CPU表现:

8a4b4683c838e1de9062427368713383.png

Disruptor压测时的CPU表现:

aa4f6531beb03860f43e17223550753a.png

分析LinkedblockedQueue的CPU占用在30%~35%上下浮动,Disruptor的CPU占用在25%~30%上下浮动,CPU占用降低5%左右占用。

线程CPU耗时对比:

7ed1fe6ec118f118ef7daf4cf050b4e2.png

分析:

第1组:LinkedblockedQueue-produce-1 和 :LinkedblockedQueue-produce-2 为生产者,对应的LinkedblockedQueue为消费者;

第2组:Disruptor--produce-1 和:Disruptor-produce-2 为生产者,对应的Disruptor-1为消费者;

很明显,处理同样的消息量33554432,LBQ耗时达到了Disruptor的2.26倍左右。

最后,再说下消息缓冲区提前分配的问题,以下是网上一段精彩的描述:"避免GC:写Java程序的时候,很多人习惯随手new各种对象,虽然Java的GC会负责回收,但是系统在高压力情况下频繁的new必定导致更频繁的GC,Disruptor避免这个问题的策略是:提前分配。在创建RingBuffer实例时,参数中要求给出缓冲区元素类型的Factory,创建实例时,Ring Buffer会首先将整个缓冲区填满为Factory所产生的实例,后面生产者生产时,不再用传统做法(顺手new一个实例出来然后add到buffer中),而是获得之前已经new好的实例,然后设置其中的值。举个形象的例子就是,若缓冲区是个放很多纸片的地方,纸片上记录着信息,以前的做法是:每次加入缓冲区时,都从系统那现准备一张纸片,然后再写好纸片放进缓冲区,消费完就随手扔掉。现在的做法是:实现准备好所有的纸片,想放入时只需要擦掉原来的信息写上新的即可"

由于压力测试过程中,会瞬间创建海量消息(33554432),所以导致年老代将近被占满而导致会不断的进行fullGC,所以压测时,务必要调大内存分配,尽量少让FULLGC来影响测试结果,毕竟生产环境不会需要这么大的消息缓存的(目前生产环境容量仅为压测时的1/100)。

总之,优化后,消息总线的处理性能至少翻倍。

https://i-blog.csdnimg.cn/blog_migrate/11931267964279df26aaeb4754532f3a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值