什么是系统架构的高可用?需要从哪些方面去提高系统的高可用?

低调的牛肉


高可用性(HA),顾名思义,就是尽可能地减少系统不能提供服务的时间;如果一个系统能够一直保持工作状态,可以对外提供服务,那么我们就说系统的可用性是100%;大部分公司不会把话说这么满,所以经常会提出三个9、四个9的目标,也就是全年系统可用性为99.9%、99.99%。

那么如何保证系统的高可用呢?我认为核心的思想就是【防止单点,增加冗余】,先让我们看看传统的架构是什么样的,哪里会有风险。

可以看到,架构的每一个部分都是单点的话,简直是风险重重,任何一个环节出现了问题,可能会造成整个系统垮掉(缓存部分可能不会直接影响系统,但往往缓存失去效果之后,会拖垮数据库),解决方法也很容易,其实就是把系统的每个部分都增加冗余:

  • 客户端到Web应用:要增加Web应用,首先要增加反向代理层,也就是负载均衡,比如Nginx;不过如果只部署一个Nginx的话,它又是一个单点了,通常我们会部署多台,一台提供服务,另外的相当于“备胎”,通过keepalived的方式监控工作中的Nginx是否存活,当主服务器发生故障无法对外提供服务时,动态将virtual IP(虚IP)切换到备用机,继续提供服务。

  • 负载均衡到Web应用:搭建多个Web应用,在负载均衡如Nginx中配置多个Web端的地址,并且可以监控多个Web端的存活性,当监控到某台应用挂掉,那么Nginx不在将请求分发到这台机器上。

  • Web应用到服务层:这里有很多种实现方式,比如服务层前端也挂负载均衡,或者走客户端内的负载均衡(这里Web应用就是客户端,相当于配置多个服务层的地址,每次请求按照一定规则,选取连接来访问下游服务,并使用service-connection-pool监控服务层应用的存活性);也可以使用服务注册发现的方式(可提供服务的应用才会出现在注册中心)。


  • 服务层到缓存:缓存的存在,本身就是一种冗余;缓存层也可以通过集群来解决缓存层的高可用问题。以Redis为例,支持主从同步,而且有sentinel哨兵机制,来做Redis的存活性检测。

  • 服务层到数据库:数据库一般会采用主从架构;数据库【读】的高可用,通常使用db-connection-pool来保证自动故障转移;而【写】操作,通常需要keepalived+virtual IP(虚IP)自动切换。

以上都是保证系统高可用的方案,尽量做到客户端所有的请求都可以响应,但是系统资源不可能无限投入,所以需要一些方案保证系统的高可用,不过需要【牺牲】部分用户:

  • 限流:我们接口只能支持200的并发,我们的页面只能支持一万人同时访问,那么多余的部分,对不起,我需要限制你们进入;常见的限流算法有:漏桶、令牌桶;

  • 降级:牺牲非核心的业务功能,保证核心功能的稳定运行;

  • 熔断:当服务链路中(A调B,B调C,C调D),某个服务响应时间过长或失败,会进行服务的降级,进而熔断该节点服务的调用,快速返回错误信息;不过嘛,我从来没有见过谁敢用熔断...

  • 灰度发布:将部分流量导到新上线的应用上,来验证新的功能修改,如果上线后有BUG,也可以快速回滚,尽可能降低发布的风险。


我将持续分享Java开发、架构设计、程序员职业发展等方面的见解,希望能得到你的关注。


会点代码的大叔


架构上讲究“三高”(3H),这里的“三高”可不是我们日常生活中说的“三高”,而是指:高并发、高可用、高性能。

那什么是系统架构的高可用呢?

高可用性指的是系统在架构上通过某些手段,使得当发生异常时,最大程度减少服务中断时间,从而保证了服务的高度可用性。

举个例子来说明一下:有两个网站平台A和B,A和B是竞争对手关系,向用户提供的都是类似的服务。此时又出现一个C想和A与B竞争,C使用了某种手段向A与B发起了攻击,结果A网站挂了,B网站依旧坚挺,我们就说B较A而言更具高可用性。

具体在平台架构中该如何实施才能提高整个平台的高可用性呢?结合我的架构经验给出一些方案供大家参考:

1、业务分层

我们知道,一个大型平台业务是很复杂的,而且各个业务间还有复杂的调用关系。如果把所有业务的实现全部放在一起(代码上放在一起、部署时放在一起)的话,那耦合度就太高了,很容易导致一个问题影响整个平台的稳定性。

所以我们在架构实施初期就会考虑将业务分层,根据业务不同将整个系统横向切割为多个部分,比如:用户中心、订单系统、支付系统、后台系统、消息系统、日志系统等。

另外站在技术角度上我们可以将整个系统再划分为三大层,即:应用层、服务层、数据层,这3层的具体定位是:

  • 应用层:前端视图展示,前后端用户看到的界面性操作都划到此类;

  • 服务层:为应用层提供服务支持与调用的,比如API;

  • 数据层:底层数据的存储与交互,主要是:各类数据库、各类缓存等。

分层的好处就是方便后期的扩展,比如说分布式部署。

2、分布式部署

上面说到,我们可以将大型系统进行模块和业务上的分层,当分层后我们就可以分布式部署了。分布式部署能够解决传统集中式部署带来的服务器性能瓶颈问题。

分布式的实施有很多方面,如:

  • 应用及服务的分布式:将不同模块分别部署在不同服务器上、将数据库和API部署在不同服务器上;

  • 动静分离:将网站系统上所用到的静态资源(如:CSS/JS/图片/文件)等使用单独的域名来部署,不和当前系统根域名相同,以此将动态脚本请求与静态资源请求分离,这样就可以减小应用服务器的负载了。

  • 数据库分布式:将服务库分布式部署,去中心化。

3、集群部署

说到集群和分布式,可能很多人分不清楚两者区别。简单的说,两者区别是:

  • 分布式:将一个大业务拆分为多个子业务,部署在不同的服务器上,各司其职完成了一件事;

  • 集群:同一个业务,部署在多台服务器上;

  • 分布式是逻辑上的形态,集群是物理上的形态。

举个例子:如果你是一个饭店老板,客人上门时:前台迎客、下单员下单、服务员端水擦桌、厨师做菜、收银员结帐,这就是分布式;你不可能只招1个厨师吧,你招了10个厨师来做菜,这就是集群,万一哪天有个厨师生病了,还有其它厨师来做菜。

在架构中我们通常将数据库集群部署,这样可以避免单台服务器的性能瓶颈。

4、负载均衡

负载均衡机制主要是用来处理高并发的,但这种分流机制在一定程度上也涉及到了高可用性。

5、异步任务

假设有这样一个场景,用户注册我们平台后,需要发送邮件给客户确认、客户确认后给这个用户赠送初始的积分。通常我们是这样做的:

  • 用户注册信息写入数据库;

  • 然后调用邮件发送服务,等待邮件发送成功后;

  • 再来给这个用户进行积分赠送操作。

这样做就是同步操作,是阻塞式的,如果发送邮件时超时了,后面的任务可能就无法继续了,显然,这是不合理的。

我们可以将一件事拆分为多件事让不同的人去做,做好了你再来通知我。这样异步操作可以节省整体事务完成的时间。

6、合理利用缓存

利用缓存,我们可以将热点数据缓存下来,这样在一段时间内就避免去数据库中查询。缓存的目的就是减轻服务器的计算压力。

常见缓存实施种类也很多,比如说有:

  • 静态资源走CDN加速;

  • 客户端缓存策略,可以减少客户端对于服务器的请求次数;

  • NoSQL存储热点数据,缓解数据库压力,就算数据库挂了,在缓存期内不必去查询数据库,这样调用方不会出错。


以上就是我的观点,对于这个问题大家是怎么看待的呢?欢迎在下方评论区交流 ~ 我是科技领域创作者,十年互联网从业经验,欢迎关注我了解更多科技知识!

网络圈


高可用(High Availability),主要是指减少系统的故障时间,保持系统的高度可用性。下面说一下个人的一些理解:

一、很多系统架构的高可用性,理解为双机热备。当然双机热备又可以分为主备方式,双主方式,双主方式主要是指互为主备。例如,使用比较多的是keepalived,通过keepalived配置双机热备的最大好处是,你无须对你的软件系统做任何代码改动,即可实现双机热备。

二、当然借助负载均衡实现系统高可用性。实现负载均衡的第三方软件也较多。例如LVS,Engix等。这方面的配置方式的资料也比较多,有兴趣的同学,可以直接从网上查阅,此处不做详细介绍。

三、混合方式。双机热备+负载均衡的方式。例如keepalived+LVS实现更加好的高可用性。如下例所示:主要增加了负载均衡器的双机热备功能,避免了负载均衡器的单点故障,增加了系统的高可用性。

四、借助zookeeper分布式框架,实现高可用。现在好多框架借助zookeeper实现高可用。例如Dubbo微服务架构,HADOOP等,都采用zookeeper这种轻量级的分布式框架实现高可用。这种方式就需要涉及到代码编程。

看一下Dubbo:

上图是Dubbo的框架,主要是使用zookeeper实现注册器功能,生产者通过zookeeper的api接口向注册器写入服务提供者信息,消费者同样通过zookeeper的api接口从注册中心获取服务信息,借助zookeeper的分布式,实现Dubbo的高可用,这就涉及到代码的层面的实现。

当然,实现层面不止这些,欢迎大家评论,提出更好建议。

本人具有多年的java开发经验,熟悉多种框架,熟悉网络编程,熟悉java安全编程,熟悉大数据,熟悉多种安全协议,熟悉并发编程,有兴趣的同学可以互相关注,互相学习!!!


分享到:


相關文章: