导语
随着物联网的逐步深化,对信息系统的并发提出了更高要求。随着云化时代的到来,软件服务架构也从传统的单体架构向微服务架构转变,微服务架构发展的如火如荼。但是,微服务是一把双刃剑,特别是大并发微服务架构下的性能问题由于其涉及技术面广、影响范围深,在信息化系统建设中如何有效提升系统性能是一个非常突出的问题。
常见系统性能问题 1、大并发下常见的系统性能问题
随着系统并发访问量的增大,系统时常伴有响应慢、无法提供服务等问题,通过对其细化分析,常见的性能问题如下:
网络瓶颈:交互次数过多、交互数据量大
IO繁忙:大量的数据读写造成系统缓慢
CPU过载:存在大量计算
内存不足:内存泄漏,内存耗尽
过载与阻塞:突发大流量,连接耗尽,排队等待
2、微服务架构引起的性能问题在微服务架构下,由于服务数量暴增引起的各种复杂的架构问题:
性能损失:原本一次调用可以返回结果,现在需要流经几个或几十个服务才能返回结果;
一致性问题:微服务架构下数据一致性无法完全通过数据库保证;
级联问题:基于微服务的系统,功能通过多个服务组合提供,因此存在大量的集成点和接触点,当其他微服务时出现异常时,异常会由后向前传导,导致系统瘫痪;
系统性能提升,可在系统实施时通过提升服务器配置、扩展应用节点数量等方式进行一定提升,但是系统的性能整体上还是依赖于软件的架构,那么在系统建设初期的软件设计研发层面我们如何进行系统性能优化提升呢?
研发优化方法
1、服务框架优化
RPC服务框架优化
虽然http+json的RPC框架被广泛使用,但是在性能并非最优。一些高性能的RPC服务框架可以有效提升系统内部的响应能力,例如Protobuf具有空间开销小以及高解析性能,非常适合于对性能要求高的RPC调用。
连接模式优化
服务调用使用长连接、共用连接池,可以有效避免重复建立连接导致的性能损失。例如Feign在默认情况下使用JDK原生的URLConnection 发送HTTP请求,没有连接池,使用Apache自带的HTTPClient,支持HTTP 2.0,修改成长链接模式,减少连接消耗。
串行改并行调用
对于多个串行的远程调用可以改为并行远程调用,可以有效降低系统响应时间。但是也要注意,业务量大后,请求高峰期会造成内存暴涨。
2、服务组件优化 缓存的利用
分布式缓存,例如redis、memcache,吞吐量大概在10万qps这个级别,相对数据库几千qps来说是一个非常大的提升。基础的、频繁查询的数据,可以把数据放到缓存中,提升服务的性能。
缓存虽然可以有效提升系统性能,也要防患分布式缓存带来的一致性问题。
异步处理机制
引入消息中间件,同步的业务处理流程改为异步处理模式,可以实现对请求的削峰填谷,提升吞吐量,提升响应速度。对于消息中间件,也应注意消息中间件的幂等性问题。
3、尽量减少网络与IO避免循环体内的IO操作
循环体内的IO、远程调用,改为循环外去重后批量执行,避免重复发起调用。
多个单次调用改为组合调用
针对频繁的IO操作、数据库请求等应用场景,采用将数据进行汇总传递的方式,服务之间的网络交互,提升服务效率。
4、前端优化减少http请求
多次网络请求不但增加了网络请求,同时keep-alive服务器可能会被断开,不能完成整个keep-alive状态的保持。可以将多个脚步合并为一个脚步,多个css文件合并为一个css文件,理想情况下:一个页面应该使用不多于一个的脚步和样式表。为了保持模块化编程思维,开发模式下保持js文件的模块化,生成打包的时候生成一个目标文件部署到线上。
文件压缩
对资源文件进行压缩,可以有效节省网络流量,提升加载速度,同时对代码进行保护,防止被篡改。
添加异步请求
XMLHttpRequest(该对象可以调用AJAX)使得资源的异步加载变得流行起来,它允许无阻塞资源加载,并且使 onload 启动更快,允许页面内容加载,而不需要刷新页面,提升页面响应速度。
利用浏览器缓存
对于web应用来说,使用浏览器缓存可以有效提升页面性能同时减少对服务器压力。
5、数据库优化SQL优化
随着数据的增加,SQL的执行效率对于程序运行的效率影响逐渐增大,导致系统的响应时间越来越慢,因此必须对SQL进行优化。
SQL优化时,可对照数据库的执行计划进行优化。
分区、索引与冗余
正确的使用分区和索引,可以快速的定位数据,有效减少IO扫描,提升数据库响应速度。为了提升数据库响应速度,必要时对相关数据做必要的冗余处理。
读写分离与批量读写
对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
程序处理上,对频繁的读写操作进行批量处理,提升效率。
分库分表
随着单库中的数据量越来越大、数据库的查询QPS越来越高,相应的,对数据库的读写所需要的时间也越来越多。在经过分区、索引等纯数据库层面的传统优化手段还无法解决后,可以考虑对数据库、表进行拆分,通过分库来分担单个数据库的连接压力,把数据按照一定的规则拆分成多张表,来解决单表环境下无法解决的存取性能问题。
分库分表要注意分布式事务及跨库查询处理。
6、提升微服务的稳定性接口超时处理
通过设置RPC调用的超时时间,可以适当提升服务的稳定性。针对不同的业务场景,需要做好超时的处理机制,包括直接忽略、接口重试、异常补偿等机制。
服务的自我保护
随着业务的扩展,服务的数量也会随之增多,逻辑会更加复杂,一个服务的某个逻辑需要依赖多个其他服务才能完成。一旦一个依赖不能提供服务很可能会产生雪崩效应,最后导致整个服务不可访问。
限制客户端的调用来达到限流的做法是很常见的,比如,我们限制每秒最大处理200个请求,超过个数量直接拒绝请求;在客户端控制对依赖的访问,如果调用的依赖不可用时,则不再调用,直接返回错误。
资源隔离
大并发场景下,某个服务不可用,容易导致所有的服务资源都再请求该服务,导致其它服务无法响应,通过对容易出问题的服务进行资源隔离,有利提升整个服务的稳定性。
结语
针对研发性能优化的方法有很多,本文仅介绍了常见的优化方法,具体场景还需根据业务需要综合使用。同时,这些优化方法也会带来一些负面影响,优化时需要根据场景权衡使用。



