另外由于JVM的sychronized(即使业务代码没用到,很多框架也有用到)锁优化在偏向锁升级过程中需要进入全局安全点,会有很短的STW 。考虑到通天塔应用的高并发场景,我们也关闭了偏向锁来提高吞吐;
从部署环境的角度考虑,当前我们使用的JVM实现无法感知到自己处于Docker容器环境,获取的CPU核数是物理机的核数,远超分配给我们的容器核数 。这导致了一些依赖于CPU资源限制推导的虚拟机默认参数会非常不合理 。比如,JVM默认的GC线程数会偏大,在GC纯本地计算阶段会有大量无意义的线程切换影响吞吐,因此我们手动设置了GC线程数,向容器核数对齐 。
6.2.2 日志框架优化
结合线程栈和磁盘IO分析,发现之前的日志框架(log4j/logback)都使用了同步模式 。并发量大时锁竞争激烈,上下文切换造成额外开销;另外,同步模式下,磁盘较低的IOPS影响应用的响应时间 。因此我们切换到了log4j2框架上来,并结合LMAX Disruptor,开启了全异步的日志模式,同时log4j2的对象复用机制减少了框架本身产生的内存垃圾,降低日志框架造成尾延迟的概率,将日志对应用的影响降到最低 。
图6.2.2.a:日志框架优化示意图
6.2.3 线程池优化
原先线程池设置有一些不合理的地方 。比如:线程数设置过大,导致CPU切换开销大,占用内存资源;核心线程数与最大线程数之间差值较大、线程池没有预热,造成突发流量增大时,同时申请线程资源时响应时长产生明显的抖动 。
因此我们通过压测去合理设定线程池大小,减小核心线程数与最大线程数之间的差值,有些直接设置为相等,设置线程池预热核心线程,改善上述问题 。
3 优化代码
代码层面的优化,带来的提升表现在更微观的层面,我们可以通过JMH等工具做一些微基准测试来对比优化前后的效果 。对于高流量的应用,微观层面的优化也可以带来一定的吞吐提升 。
6.3.1 深拷贝优化
为了避免对共享资源造成污染,通天塔代码中使用了深拷贝方式来保护共享资源 。原先通过序列化-反序列化的方式实现,这种方式拷贝流程长、中间对象多,GC有额外的压力 。优化后我们使用Cloning深拷贝工具,直接进行对象到对象的拷贝,缩短了拷贝流程,同时也不要求POJO实现Cloneable接口,避免了使用原型模式过多的限制 。
图6.3.1.a:深拷贝优化示意图
6.3.2 对象重用&无竞争
通天塔灰度功能采用了随机灰度的策略,代码中使用Random对象,这里存在一些代码重用和竞争的问题,优化过程如下图所示
图6.3.2.a 对象重用&无竞争优化示意图
6.3.3 其他代码优化
虽然“不提倡过早优化”这句话老生常谈,但并不意味着我们写每一行代码时可以很随意,我们完全可以选择更优的实现方式 。各种编码规约,设计模式其实就是前人总结出来的宝贵经验,帮助我们更好地编码实现 。
其实,代码层面可注意的优化点非常多,这里只列出一些供参考:
- 正则表达式使用独占模式
- JIT优化内联:短方法;尽量private/static/final修饰方法
- 锁优化:锁分离;细粒度锁;乐观锁;无锁(不可变模型/ThreadLocal等)
- 时间换空间:数据压缩降低网络IO;String常量池重用
- 空间换时间:哈希表;缓存等
总体而言,设计层面的优化难度较高,对于聚合应用而言效果最显著;组件、代码层面的优化也有不错的效果,但更多的需要通过微基准测试去验证 。最后,也是我们觉得最重要的一点就是:系统优化必须保证系统的稳定性和正确性,必须通过严格的验证和测试,否则,宁可不优化 。我是科技萌新 ~ 欢迎您关注和点赞!
以上关于本文的内容,仅作参考!温馨提示:如遇健康、疾病相关的问题,请您及时就医或请专业人士给予相关指导!
「四川龙网」www.sichuanlong.com小编还为您精选了以下内容,希望对您有所帮助:- 为什么尽量不要用花呗 开通花呗有风险吗
- 丑苹果是大凉山的好还是昭通的好
- 零钱通安全吗 零钱通是干嘛的
- 什么是京东公益众筹 京东公益众筹怎么发起
- 京东有些商品标识广告 京东618商品打标是什么意思
- 兰交大考研率
- 套白条去哪里找商家,京东白条秒到几个点
- 什么是通假字
- 堵奶了如何自己疏通 堵奶了怎么疏通
- 新鲜出炉,2021年直通车最新玩法全解析