一提到高并发就让很多人感到头疼不已,不清楚应该怎样设计才能承载高并发,经常能听到集群、负载均衡等名词,但是具体架构是什么样的却不知道,无从下手,接下来我们一步一步解析高并发架构是如何形成的。
一、常用基本概念:
1、分布式:分布式一般指软件层面的部署,如一个应用可同时部署在多台机器上运行来分摊压力。
2、集群:集群指使用多台机器来运行同一种服务。
3、高可用:高可用指多台机器同时提供一种服务时,当其中一台机器故障后其他机器能够代替故障机继续提供正常的服务。
4、负载均衡:负载均衡相当于指挥官,当客户端发起请求后,由指挥官分配你应该走向哪台服务器,达到可均匀分配各服务器的压力值。
有了以上基本的认知,我们来看下单机架构是如何一步步的晋级并融入这些感念的。
二、架构晋级之路
1、单机架构:
从上图可以看到所有的服务均运行在同一台机器上,这也是一个网站最初的样子,用户少,业务也相对简单。
2、服务拆分:
随着用户的逐渐增多,多个服务同时占用服务器资源导致响应慢,我们吧各服务拆分到不同的服务器上来减少资源占用问题。
3、引入缓存服务:
过了一段时间后逐渐的发现,数据已经有了一定的瓶颈,我们使用缓存服务来降低数据库的压力,一般使用redis或memcache。
4、初步负载均衡:
通过一些监控手段我们逐渐发现业务层的承载能力单台服务器已经不足以支撑,我们进行横向扩充将一台机器增加到多台,同时利用NGINX的负载均衡机制转发到后端不同的业务服务器上,利用缓存的机制来共享session。
5、数据库读写分离:
当业务层的服务器足够支撑后发现数据数据库层又到了一定的瓶颈,我们将数据库进行读写分离部署,一般主库只负责读,从库只负责写,但是这样会给客户端操作带来一定的麻烦,所以这时候需要同步引入数据库中间件来简化数据库操作。个人比较推荐Mycat/sharding-jdbc两款,利用中间件可以很轻松的实现分库分表。
6、F5或LVS使用:
当后端的承载能力上来之后此时NGINX的承载能力就会显的不够用了,我们可以引入F5或LVS来负载多台NGINX进行工作。F5是硬件LVS是软件,他们都可以实现负载均衡。在性能上F5要高于LVS但价格比较高。由于LVS是单机版的软件,若LVS所在服务器宕机则会导致整个后端系统都无法访问,因此需要有备用节点。可使用keepalived软件模拟出虚拟IP,然后把虚拟IP绑定到多台LVS服务器上,客户端访问虚拟IP时,会被路由器重定向到真实的LVS服务器,当主LVS服务器宕机时,keepalived软件会自动更新路由器中的路由表,把虚拟IP重定向到另外一台正常的LVS服务器实现高可用。
7、DNS绑定多IP:
当F5或LVS依然撑不住的时候我们就需要通过DNS绑定多个IP轮训到不同的F5或LVS节点上来分摊压力,数据库层面我们也增加了很多机器分摊压力,此时我们差不多能够承载超高的并发量了,应用也肯定非常丰富了,这么多应用都集中在一起显然是不合适的,我们需要将业务进行精细化的拆分。
8、应用拆分:
对于大型网站,我们可以分而治之,把整个网站的业务分为不同的模块,同时我们将一个网站根据模块划分拆分成多个应用,每个应用进行单独的部署和维护。
将应用拆分后我们同时又增加了NoSsql,搜索引擎等以便提高应用的各项能力。当数据库中的数据多到一定规模时,数据库就不适用于复杂的查询了,往往只能满足普通查询的场景。对于统计报表场景,在数据量大时不一定能跑出结果,而且在跑复杂查询时会导致其他查询变慢,对于全文检索、可变数据结构等场景,数据库天生不适用。因此需要针对特定的场景,引入合适的解决方案。如对于海量文件存储,可通过分布式文件系统HDFS解决,对于key value类型的数据,可通过HBase和Redis等方案解决,对于全文检索场景,可通过搜索引擎如ElasticSearch解决,对于多维分析场景,可通过Kylin或Druid等方案解决。
9、微服务:
随着业务拆分,整个系统越来越大,应用的整体复杂度呈指数级增加,部署维护越来越困难,我们将各业务重复的模块拆分成微服务,由各服务统一提供服务,应用和服务之间通过HTTP、TCP或RPC请求等多种方式来访问公共服务,每个单独的服务都可以由单独的团队来管理。现在主流的微服务框架基本都具备服务治理、限流、熔断、降级等功能,提高服务的稳定性和可用性。
10、引入ESB企业服务总线
通过ESB统一进行访问协议转换,应用统一通过ESB来访问后端服务,服务与服务之间也通过ESB来相互调用,以此降低系统的耦合程度。
11、容器化:
docker是一个容器,可以利用容器快速的部署系统,同时利用K8S来管理容器。
三、常见疑惑
1、架构的调整是否必须按照上述演变路径进行?
不是的,以上只时列举了在晋级过程中所需要的知识点及思路,在实际场景中需要结合具体需求来进行演变,需要解决什么样的问题就把哪一部分的内容加入现在的架构里,切记太过死板。
2、对于将要实施的系统,架构应该设计到什么程度?
够用就好,一个简单业务没必要搞成非常复杂的架构,但是也要为以后考虑,尽量留有扩展架构的接口以便不备之需。对于不断发展的系统,如电商平台,应设计到能满足下一阶段用户量和性能指标要求的程度,并根据业务的增长不断的迭代升级架构,以支持更高的并发和更丰富的业务。
3、在设计过程中需注意什么?
其实也没有什么特别需要注意的,一般情况下如果你亲自去设计一个架构的话往往会不知不觉的考录很多方面。如最重要的一点是如何兼容新旧版本劲量做到无感升级,如出现问题如何能快速回滚到旧版本,在什么环节增加怎样的监控手段,如何保证系统的稳定运行,是否能够友好的支持扩展性等等。