第四届阿里中间件性能挑战赛 初赛心得分享

本次只分享初赛,赛题介绍见链接:第四届阿里中间件性能挑战赛
成绩目前是第16名:

中间件比赛排名
总结下,这次比赛收获特别大,从搭建环境都需要两周的一个小白到能走到复赛还能名次这么靠前,这其中靠的是每日每夜的对知识的渴望,还有成绩一点点的不断上升带来的动力。


1. 要做什么?

赛题背景见比赛官网第四届阿里中间件性能挑战赛,这里面已经做了很多介绍了。总结下来主要做以下几点:
实现一个高性能的 Service Mesh Agent 组件,并包含如下一些功能:
1. 服务注册与发现
2. 协议转换
3. 负载均衡
试卷已经给你了 ,怎么才算提交呢?本次比赛需要提交一个docker镜像,所以jvm的优化也会是一部分。

2. 怎么做

入门篇

1. 先让demo跑起来

之前自己也没有接触过docker,连centos也只是部署一下业务,所以需要了解下docker,充分利用学校资源,在睿思上下载了个视频迅速的了解下docker,再结合网上的资料,终于弄懂了这个docker其实就是一个虚拟机,需要自己写好启动脚本,docker启动后,你的服务也要启动,之后官方测试脚本会来调用你的服务,然后评分。贴心的举办方还提供了一个demo, 你可以直接拿这个demo去跑分,跑出来后是1000多分,相信很多人在有成绩后和我一样激动把。

2. 搭建自己的测试平台

官方起初的时候只有5次提交机会,那你本地想测试怎么办?自己用的是win平台,官方提供的都是在linux环境下的。又是经过一番查找资料,找到了jmeter这个工具,是一个非常优秀的开源的性能测试工具,关键是在win平台下可用,然后再安装一个etcd,一键启动。然后把service的代码pull下来,根据官方提供的启动脚本start-agent.sh和压测脚本,经过一番操作后,你就拥有自己的测试平台了。根据电脑性能差异,跑分效果也不是一样的。只要在同一环境下,分数提高,提交的时候都会有分数的提升的。

初级篇

1. Epoll的优化

之前在实习面试的时候曾经有个面试官问我了解Epoll吗,当时不知道,之后稍微了解了下,大概知道这东西在linux上是最好的。所以先把PA请求Provider之前的都改为Epoll。经过测试,成绩有所提升。

2. 异常的处理

在官方的demo中,运行时候会报很多异常的。此时找到这些异常,一点点的去处理。

3. 负载均衡

demo用的随机,因为Provider的处理性能我们是知道的,我们可以用加权随机。
经过上述的一些操作和一些尝试,此时就已经算入门了,接下来就要上实打实的改造了。

进阶篇

自己之前接触的都是业务开发,用用框架,感觉请求就是这样一步一步的,但看到别人的QPS都达到4000+,经过上面调优后顶多也就2000左右,这样肯定还差得远,那到底怎么做呢。瓶颈在哪里?看着群里面大佬们的交流逐渐开始了解netty、线程、零拷贝等,然后自己也去看书,此处推荐《netty权威指南》和《netty实战》两本书,看一点就做一点。

1. PA到CA的改造

demo用的是OkHttpClient请求PA,这样的话会开启一个线程,同步的等待,会很耗CPU,用jvisualvm去查看发现线程会一直等待很浪费资源,那么此时可以参考PA到P的请求方式,用一个Future回调,当有结果的时候调用done来通知接收,期间是await的,让出资源来。然后根据学的netty,把PA到CA也改为了netty通信。差不多能到2500左右把。
说了这么多了此时差不多我认为这是第一版的极限了,之后就是架构了。让我们回顾下整个流程。
架构图
1. 首先C到CA之间采用HTTP协议,目前使用的是spring boot自带的undertow来暴露CA的服务。
2. CA和PA之间采用Netty连接,CA发出请求后,等待future的回调,虽然使用await会让出资源,但还是开辟了一个线程。
3. PA和P之间也是使用netty,dubbo协议,请求过程和2中一样
仔细考虑下整个过程,压测环境是256个线程也就是256个用户并发访问,也就是说在CA这边我们至少会开启256个线程去处理请求。而CPU是8C16G,线程的切换肯定会带来很大的压力,同理PA这边也是一样的。此时我们就需要修改架构异步化。

2. 异步化初探,先把PA释放出来

首先还是看dubbo怎么做的,dubbo协议里面有一个字段是id,这个id是唯一的,而请求接收的时候也是根据这个id来寻找回调给谁的,那么我们可以借鉴这个设计,在整个链路C->CA->PA->P统一在CA加上一个id,这样PA的话只需要把这个请求加个头部转发给Provider就好,同理结果也一样,只需要CA这边开启256个线程就好。而PA这边只需要开启一个线程处理和CA的收发,再开启一个线程处理和Provider之间的收发就好。经过这样修改在256压测的情况下就已经达到了3400+的QPS。但是还不够。CA这边压力还是他带

3. 异步化深化,Servlet3.0

把PA改造好之后,用jvisualvm去查看CA和PA,就会发现CA这边开了很多线程,并且垃圾回收很严重。既然PA这边异步化,那么CA这边的服务暴露肯定也有异步的方法,刚好赛题的consumer更新了一下,他们的consumer采用了一个AsyncClient来请求,还特意标注了下是servlet3.0,那么就去看下servlet3.0就好了,发现竟然支持异步化,只需要把开启异步就好。调用HttpServletRequest中的startAsync方法,然后回调就可以了。之后经过一系列的测试优化,已经能达到3800QPS了,真真切切的感觉到了自己是可以做的更好的,离大佬们的差距越来越近。
做到此步,之后进行了一些优化,感觉真的做不动了,刚好看到群里面有人说用netty支持多路复用,自己也潜心开始看书去深入的了解netty,去了解底层原理。期间还用UDP做了一次,效果也不是很好,主要是UDP会丢包,丢包重传带来的开销还是得不偿失,最终放弃了UDP,之后还是会在考虑下的,毕竟TCP会维持一个连接,并且UDP有广播的特性,可以做一些高级的东西,那是后话了。

高级篇

在差不多把《netty权威指南》和《netty实战》通读一遍后,和自己C++的实验室小伙伴疯狂的讨论底层TCP、Epoll、Eventloop、文件描述符,感觉自己做的东西越来越豁然开朗。此时又看到了一些高级特性

1. netty的多路复用,CA的改造

demo中CA采用的暴露给C采用的springboot中的undertow,针对虽然可以支持异步,但是还是为每个请求开辟一个线程,并不支持多路复用,并且gc很频繁。所以采用netty自己写一个http服务迫在眉睫。并且netty有专门的http解码器,十分的方便,关键还是支持多路复用啊。起初的时候eventloop数量采用的和核心数量是一样的,也就是8个,改造完之后瞬间破4000大关。

2.初赛开始,题目改动

在改完后差不多就初赛开始了,之后都是一些小优化,连接数,权重比等。初赛开始后,题目修改为采用512个连接去压测,幸亏采用的是netty的Epoll,影响并不大,512压测能达到5800左右。

3.优化过程

至此整个架构就已经定型了,下面说几个优化点。
1. eventloop的复用,在CA中是有一个server和一个client的,都采用的EpollEventloop,所以是可以复用的。
2. PA和CA之间的通信,用Json传的话很方便,但是是没有压缩的,所以采用了protobuf,对数据是有压缩的,但是编解码是有Cpu消耗的。
3. CA的etcd是不需要暴露服务的,所以只需要访问就可以了,不需要保持心跳,省掉一个线程。
4. PA和CA分离,可能是自己写代码比较乱,其中有写耦合,所以将其拆成了2个客户端,分别调用,此时也意识到了jvm的优化也是一方面。
5. jvm优化的话首先是对netty的优化:leakDetectionLevel的关闭,开启noJdkZlibDecoder,设置allocator.pageSize等
6. 开启-server优化。
经过一系列操作后此时就已经上了6000+了,之后深感自己一个人做真的是有点吃力,很多问题都是共性的,所以有幸在交流群里面见到了自己的队友,然后也见识到了一些新的工具IntObjectHashMap和更好的内存管理等。经过一系列优化我们队伍目前达到了6800+分,第16名。

扩展篇

由于时间原因,复赛题目已经公布,所以优化也停止在了6800+,但自己还是有写点感觉还是可以尝试的。
1. 线程模型的优化,在CA端是有一个server和一个client的,理论上是2个selector,也就是在同一个进程开启了2个selector,那么是否把这2个合并为一个呢?可能需要自己去写这个selector逻辑。
2. Epoll还是poll?epoll是采用注册轮询的方式,也就是会多一步注册,而在业务频繁和连接少的情况下采用poll会更好,也就是在CA-PA-P之间采用poll可能会更好,这篇博客很好的证明了这个猜想Epoll和poll比较
3. jvm的优化,虽然netty采用了零拷贝等技术,但系统整体上还是有gc的,所以针对gc也有优化的空间,比如采用何种垃圾回收,比如ParallelGC等,还有Xss等的设置等。
4. UDP的尝试?主要是想利用udp广播的特性来做负载均衡,在保持业务幂等的情况下,负载比较轻的是可以把任务接过来处理的。
5. 把链路信息放在请求id中,根据id来确定回传给那个信道,从而省去在CA端使用ConcurrentHashmap来记录删除请求的会传地址。
展望:通过初赛收获的东西真的是太多了,最大的收获还是收获了两个队友,交流真的是太重要了,能省去很多重复的工作,期望复赛能取得一个好成绩把!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值