高并发问题是互联网架构设计中必须要考虑的因素之一。高并发设计所要达到的效果就是让系统具有并行处理更多请求的能力。一家公司在刚成立时,通常使用的是单机系统,就是一台服务器干所有事情。随着公司业务的发展流量的增多,单机无法满足业务的需求,可能出现系统卡顿、经常宕机等问题,这时候就会出现高并发大流量问题。要解决这类问题首先要了解更详细的系统信息。
一、并发量多少
不同业务领域决定了系统的并发量。比如说淘宝、京东这种大型购物网站最大并发量可达千万级,银行、保险机构的并发量最大有十万级。优化的第一步就是确定目前系统的并发量和所属领域。
二、一致性多高
数据的一致性要求,对系统能承受的并发量影响很大。12306系统每年都要崩几次,单看12306的系统架构并不比淘宝差,甚至在机器性能和分流策略要比淘宝的还要好,但是淘宝在双十一千万并发量时依旧顺畅,12306的并发量到百万并发量时就已经顶不住了,原因就是它对数据的一致性要求太高。一个站点卖出了车票要把购买的数据同时同步到十几个站点和端系统,每一张票必须要用同步锁锁定,不能出现并发问题,要同时满足高可用和强一致性,这一要求制约了12306所能承载的压力。
三、什么样的场景出现这种问题
不同的业务场景解决方案差别很大。12306可以通过更新业务来缓解系统压力,比如通过预购票、节假日车次分批发售车票、热门城市临时开通直达班次等来缓解节假日压力。电商的秒杀场景可以前端限流、预发售等。
四、设计用量多少
设计系统时预设的系统最大容量是多少,目前状况是远未达到最大容量还是已经接近或超出设计容量。如果是远未达到就要检查系统问题、机器状态,看下当前系统是不是还有可压榨空间。如果是已经接近设置超出了设计用量,只能通过扩容、优化架构、分库分表等手段来优化。
五、公司现在的系统架构什么样
架构的优化不是一蹴而就,如果完全摒弃原有架构,所需成本是非常昂贵的。如果可以在不修改公司原有架构仅仅是增加组件或者增加机器的方式达到优化的目的,当然是最好的。如果原有系统架构已经烂到极致,只能推倒原有架构重新制定新架构。
详细了解上面几个问题之后,可以设法优化架构。
优化思路:
操作系统级优化
使用成本较低的软件优化。
一台linux机器最大可以有65536个tcp同时连接,理论最大连接数为2^96,减去无效地址和系统保留端口,理论最大连接数可以达到2^48,这一数量足够一般公司使用。一个系统的并发数量受到很多因素制约,tcp连接只是其中之一,对系统制约更大的是cpu和内存,在系统中内存常常比其他资源更容易耗尽。在程序中所有的业务处理都需要将数据先放到内存中然后再执行,内存的消耗极大,内存又比较昂贵,机器的内存不可能无限扩容,所以只能通过多台机器负载压力来达到支撑效果。
对于系统而言,每一个请求都会占用一个网络IO链路,如果系统的同时在线人数过高超过了机器负载,势必会造成卡顿严重的会导致宕机,影响用户的体验,这时可以考虑使用LVS作为软负载跳转多台机器。LVS承受峰值可达30W+qps。LVS是linux系统内核自带软件,使用非常方便。
如果是因为某一模块的业务逻辑复杂或计算数值太大造成的问题,可以使用Nginx作为软负载跳转链路,让不同的业务请求去到它执行的机器或链路上。nginx最大可达5W+qps。
如果在线用户太多并且有些模块的业务逻辑复杂,可以用LVS和NG组合,LVS==>NG==>应用集群。
应用系统优化
传统web项目的前端和后端杂糅在一起,这种项目一般规模较小,访问量也不大,开发人员大都是全栈工程师。在互联网项目中杂糅的弊端:
1、前端样式改动需要重启整个服务,开发测试不方便。如果因为前端样式而重启一个生产服务所造成的损失极大
2、有些访问只需要获取静态资源(图片、文件、文字),只需要访问html或者js就可以,但由于前端和后端代码部署在一起,同样需要到达后端服务器,并通过服务器返回结果,静态资源一般比较大,这些访问会长时间占用链路,占用服务器资源,增加服务器压力。
3、全栈工程师一般对后端和前端只是略懂一二,很少有全部精通,因此不管是优化前端还是优化后端都无法深入。
在互联网项目中实现前后端分离很有必要。前后分离优点:
1、前端样式不需要重启整个服务
2、访问静态资源可以直接在前端返回不需要到达后端服务,有效缓解后端压力
3、如果是前端到达瓶颈只需要复制前端服务就可以轻松扩展
4、专业的前端开发工程师对前端代码有更深入的理解,前端代码质量有保障。后端工程师专注后端开发优化,有效提升代码质量
传统项目的静态资源同样是放在后端服务器上,这样的部署方式会占用宽带,影响返回效率。在分离静态资源时,如果小文件多可以使用fastDFS搭建文件服务器,如果是大文件多可以使用HDFS。也可以直接购买云服务器。
传统web项目的缓存大都直接使用ecache将数据缓存在jvm中,这样会造成数据在集群中重复存在,占用内存资源,并且无法解决缓存同步问题。这时我们可以借助redis或者memcached等进程外缓存工具。加入进程外缓存可以在tomcat和数据库之间起到缓冲作用,减轻数据库压力。当需要查询数据时,首先查询缓存服务,如果缓存服务不存在数据再范围数据库。
在实际项目中,不同业务的复杂度是不一样的,执行的耗时也有很大不同,如果把这些业务放到同一个项目中,会造成复杂的业务影响简单业务访问,一小部分的不稳定造成整个系统错误率增加,原本只是某一模块到达瓶颈却不得不重新部署整个程序,得不偿失。这时需要业务与技术通力合作,将系统的模块细分,拆分成一个个小服务,就是俗称的微服务。
拆成微服务的好处:
1、将原本复杂规模系统拆分成多个简单系统,降低了系统业务复杂度
2、各个服务相互独立,开发人员可以自由选择技术栈
3、每个服务单独开发部署,缩短业务开发周期
4、故障隔离,一个服务宕机不会影响其他服务
5、小团队作战,工作更加高效
。。。
缺点:
1、单一系统的复杂性降低了,但是整体架构的复杂的大大增加
2、需要增加额外的通讯组件,来支撑整体系统运行
3、引入了分布式事务问题
4、整体系统部署变得复杂
5、出现跨服务需求,需要各系统紧密配合
。。。
弊端更多的是公司内部问题,相对公司发展而言,显然是利大于弊。服务拆分就要考虑跨域和同步执行问题,这时需要开放一个总线来解决这些问题,可以把同步锁信息放到共用的缓存服务中,其他业务信息放到服务独有的缓存服务。数据库同样要分开,对于某些会员信息、基础参数肯定要放到公用数据库,其他业务信息放到独有的数据库中。各个服务之间通过额外加的通讯服务进行交互。
缓存和数据库也可以做成分布式
通过使用算法,把数据均匀分布到不同服务器上 ,缓解单台数据服务器的压力,对于文件系统以及通讯服务也是一样的。
系统升级至此,需要同时开发运维系统来支撑系统的快速扩展,包括:日志系统、系统监控平台、链路权限维护系统、服务器监控平台、报警系统、配置管理平台以及自动化运维平台等等。。应该说当系统升级到这一步,真正的挑战才刚刚开始。
架构演变过程
公司刚刚建立,没有流量也没有客户
公司发展阶段,有些流量和客户,数据库不够看
客户增多需要用集群来缓解服务器压力
公司业务日渐成熟,规模进一步发展,需要多级负载
公司高速发展,成为某个领域独角兽,流量与客户激增
公司大力扩展,需要考虑不同地域网络延迟问题,需要在用户与服务器之间增加CDN(智能DNS解析 ),根据地域不同,将流量流向最近的服务,减少网路延迟。此时公司还需要一个大数据中心,来管理极具增长的数据,并使用这些数据开发更多领域,譬如:AI、区块链,大数据是AI的基石,没有数据支撑的人工智能就是人工智障(有数据也可能是智障)。