架构师训练营第七周学习总结
本周进入性能优化章节,而性能是架构师工作内容的一个重点,一个系统比较直观的感受就是性能方面的体现,也就是并发数、请求响应时间和系统吞吐量。我们通常会按照以下的流程去完成我们的系统性能优化工作:
性能的标准
要做性能优化首先要有一套性能指标标准,一方面是为了有参照物,另一方面也是为了和相关人员证明自己的优化方案是可行的。
在性能指标中,一般采用几个常用的数值来做衡量系统性能,例如并发连接数,系统请求响应时间等。
我们建立好一套基准后,才能开始针对某一项性能指标进行优化。
性能测试
有了标准后,我们需要开展我们的性能测试,我们需要通过一下压测工具对系统进行阶梯式的负载测试,这里需要考虑的是如何尽可能还原我们真实用户的请求,这里不能简单使用一些工具针对一些接口进行反复的,统一请求参数的压力测试,我们需要更全部覆盖整个系统的压力测试,所以一般我们会考虑把线上的真实数据dump出来作为数据源,把这些数据发到距离用户侧较为接近的CDN机房,由那里发起大量的请求模拟用户的真实使用环境,现有都有一些压测平台可以提供这样的服务。为了保证测试时不影响我们线上生产环境的使用,我们可以使用网关标记分发和做业务特殊化,但是可能会增加代码的侵入性,在预算充足的情况下可以考虑临时搭建一套测试环境做压测,压测过后就可以删掉这些资源,一些云厂商可以满足我们这样的需求,按需付费。
瓶颈分析
拿到了完整的性能数据后,我们会看到我们几个指标在不同并发数下的表现如何,可以建立一张曲线图来帮助我们理解当前服务器的性能情况。
架构师需要评估出在当前的系统设计下,哪里还有优化的空间,这里需要综合考虑投入产出比。
而性能的瓶颈基本还是落在了几个地方:
1.服务器的硬件性能;
2.网络传输时延和带宽;
3.代码编写问题;
性能优化的基本模式
1.骨干网和机房网络性能优化
我们在之前的学习中提到过CDN这样的内容分发网络这样的优化手段,主要是让用户就近从网络运营商处获取请求的内容,这样可以节省网络的传输时间以及对减少我们服务器的请求压力。目前互联网应用中对于大部分的静态资源请求,尤其是高清的图片或视频等都可以用这样的方式来优化。因为大量的带宽都是为这些静态资源服务,如果能就近获取,可以减少大部分的带宽压力。
2.服务器硬件性能优化
这一点在之前的学习中也有提到,架构的垂直扩展不需要改变任何东西,仅仅是提升网卡的带宽,磁盘的转速,内存的容量,CPU的核心数这些硬指标,可以就可以很快带来非常大的性能提升。但是我们也强调过,需要关注投入产出比,可能提升一台服务器的硬件花不了多少钱,但是如果我们的集群比较庞大,那全部都提升是不可能的,需要关注系统哪些环节是瓶颈,对那些服务器进行升级。
3.操作系统性能优化
操作系统作为调度我们代码的底层软件,同样存在很多可以优化的地方,例如linux的不同发行版本中,一些内核参数是不一样的,还有对网络、磁盘、内存和CPU相关的一些操作系统优化项,都需要针对服务器所承担的业务职能去进行一些调优,例如I/O密集和计算密集,那相关的参数都是有区别的。此外,选择一个稳定的系统版本,必要的补丁安装好也是保证系统性能得到良好发挥的保证。
4.虚拟机性能优化
在Java运行环境下的服务,需要运行在JVM进程里,这里同样存在着各类参数会影响系统性能,例如设置的线程分配内存大小,选择的GC算法,Eden区和Survivor区的比例等等。和操作系统一样,需要针对服务器所承担的业务职能去进行一些调优,例如针对创建对象的生命周期长短不同,就可以调整我们的Eden区的大小。
5.基础组件优化
我们开发过程中使用到了很多框架和中间件,连接池、缓存、队列和搜索引擎等,这些框架自身也有很多参数可以进行调优,同时新版本和老版本的差异也会带来性能的提升。例如Tomcat新版本对响应式的优化,Redis6对网络I/O的异步优化都是我们可以考虑优化的。
6.软件架构和代码优化
最后就是我们自己搭建的软件架构和代码的优化,这里涉及到我们使用的设计模式、代码中是否有不必要的过程和多余申请的资源、代码是否有缺陷,这里比较普遍的就是我们过程中的同步阻塞,我们需要分析我们的业务流程是否可以把某些过程进行异步化操作,在异步操作下执行线程在网络I/O上的阻塞等待就可以得到提升,其次是我们在多线程下对锁的使用,合理的使用各种级别的锁也会提升我们代码的执行效率。
线程模型和锁实现原理
我们本周重点也了解了锁在操作系统下是如何实现的,通过对临界区的准入判断,让不同线程在访问共享数据时采用分时或排队执行的方式,这都是操作系统和硬件协同提供的。此外我们的线程模型是如何保证栈内数据不会互相干扰,线程自身的生命周期和如何被CPU调度执行。通过对这些底层操作系统的认识,进一步加深我们对自己编写的代码会如何实际执行有更清楚的认识,这里比较有意思的一点就是要求架构师在没有编写出实际代码之前,就要有想象自己代码会如何运行的能力,这就要求我们对底层的原理,我们的编译过程和执行过程有一定扎实的功底。
异步编程框架
Akka编程框架是我们异步化系统的一种手段,通过把依赖调用这样的编程模型转变成Actor、以及Actor之间通过消息传递的方式实现调用和流转,这样的模式其实就是把因为同步调用的阻塞尽可能减少,Actor与Actor之间不做任何直接依赖。线程池只为有需要的Actor进行服务,极大的提升了对请求的响应能力。
同时Akka对于分布式的支持也非常良好,可以很方便的声明一个非本地的Actor进行消息传递。对于快速搭建一个异步编程系统,Akka可以说是提供了非常便利的开发手段。
回顾本周,我们以性能测试作为切入,学习了如何测试、如何分析、如何处理在性能方面的种种问题,可以说性能问题是始终存在的,我们只有不断调整来满足我们对性能的要求。
版权声明: 本文为 InfoQ 作者【Gosling】的原创文章。
原文链接:【http://xie.infoq.cn/article/45d1d4bad01d77e6f7f3d18ff】。文章转载请联系作者。
评论