前提
说起高并发,一定会想着比如jvm调优,SQL优化,引入各种高大上的中间件或者优化持久化容器。但其实收效甚微,各种调优只有在代码写的极差的情况下可能会有着比较显著的效果。其实在设计高并发程序的时候,优先需要考虑的是架构,后续要考虑各种请求响应时间,并不是一味的需要引入各种很强的中间件。
优化
在面对一个高并发程序的时候,我个人认为,架构是最好的优化手段,就好像盖楼一样,当地基不够稳定的时候,后期就只能各种打补丁甚至推到重做。
面对高并发的时候,我们需要优先考虑的就是整体的方向,例如微服务的颗粒度拆分、MQ削峰中间件的引入点、持久化层的水平垂直扩容、缓存、负载均衡、异步吞吐量的提升等等。
微服务的拆分
出色的微服务体系离不开合适的颗粒度拆分,一般会考虑两种拆分,例如业务依赖的拆分和物理依赖的拆分。
业务依赖拆分:
例如一个稳定的电商系统,一定会有用户模块、订单模块、商品模块、权限模块等等。而在业务流水线上订单模块肯定是强依赖于商品模块和用户模块,权限模块强依赖于用户模块等,这条流水线可以在产品经理的需求中完整的理出来,自此就可以根据业务的每一步合理规划微服务体系的拆分。
物理依赖拆分:
物理依赖这里指的是数据库层面的依赖关系,可以理解为隐形外键,利用物理依赖拆分的时候,可以通过前期数据库的构建划分各个模块的依赖关系,当后期对某模块的数据库进行水平垂直扩容时,可以做到不影响别的系统,因为数据库是独立的。
微服务模块的划分是高并发编程中最重要也是最基础的一个环节,合理划分颗粒度,当后期某一功能到达瓶颈的时候可以合理进行集群扩容,做到该扩容的扩容,不该扩容的维持不动,节省了大部分的机器资源。例如电商平台通常会集群启动订单模块,支付模块等核心模块,因为这些模块的请求量和数据量是最大的,而用户模块则可以单机运行。
MQ削峰
MQ最重要的特点之一就是削峰,这点可以参考12306的架构体系,12306的并发量在春节期间可以跟双11的淘宝不相上下,而如果不引入MQ的话会面临单张票多人抢购的情况,会导致数据库锁死,请求过多等情况。12306的架构特点就是使用MQ进行削峰,当购买请求进来时,并不会第一时间去请求数据库,而是将请求进行排队,通过MQ先进先出的设计,可以让最早的一批人完成订单的购买,后续的购买请求就会被打会,通过这种削峰的手段,避免了数据库一次性大批量的请求,当完成请求后,后台会通过Websocket推送给前端,形成一种伪同步的体验。
持久层扩容
对持久层的扩容在数据量大的情况下是很有必要的,Mysql的性能瓶颈大约在500W,也就是说当Mysql单表达到这个瓶颈的时候,查询效率就会急转直下,这个时候需要考虑对数据库进行扩容,例如分表分库,这个在SDP里面应用的比较多,这种情况可以很好避免单表超过500W的情况,有效的提高查询和写入的效率,提高用户体验。
缓存
缓存是老生常谈的一个点了,高并发下最直观提高性能的手段就是缓存,不管是静态页面缓存还是后台数据缓存,都是可以提高数据请求效率,毕竟在大多数情况下都是读多写少,缓存可以帮助大部分的读请求完成高效的响应。
数据缓存
使用缓存的时候需要考虑缓存击穿、缓存穿透、缓存雪崩以及缓存热更新的情况,例如我们在使用redis做缓存时,一定需要考虑缓存的有效时长以及缓存雪崩后的恢复方案,比较多的手段就是RDB和AOF,但这种手段是极端手段,更多时候我们需要考虑缓存的有效性,这里给大家提供一个方案,大家可以使用canal去进行缓存的实时刷新,既可以避免缓存雪崩的情况,又可以避免热数据更新的问题。
静态页面缓存
电商平台大多数情况下都会在nginx层对商品做一层静态页面缓存,由后台模板生产静态页面,然后放入nginx缓存路径下,建议大家可以尝试用nginx通过lua脚本进行一些业务逻辑的简单处理,在处理请求的效率方面,脚本语言的效率是秒杀java的,网上有一份测试数据,如果java做到极限可以一秒处理1000个请求,那lua脚本可以做到一秒10W。
负载均衡
负载均衡其实比较多的时候还是需要用lvs+nginx来完成,借助web端的负载均衡可以让用户请求进行隔离,后期也能很轻而易举的完成集群扩容。
异步
用异步的时候虽然会损失实时性和线程切换的资源,但异步确实可以很优秀的提高程序的吞吐量,Rxjava
和disruptor
都是很优秀的异步驱动框架。异步程序在合理的使用下可以将服务器性能提升到极致,因为目前服务器都是多核CPU,多线程的方式可以充分利用服务器资源,最大程序的提高吞吐量,但异步一定会造成程序延时,这是不可避免的,还有一个不可避免的就是线程安全问题,异步一定会造成线程安全的问题,所以要合理运用异步,最大程序提升服务器吞吐量。
总结
其实提升服务器最好的手段,就是人民币。但在有限条件的情况下,我们需要考虑程序的各个环节,谨慎的引入中间件,其实最好的武器就是代码,当我们最大程度的使用了机器性能的时候,就已经完成最大程序的优化,希望我的文章能对大家有帮助。