关于网站高可用性问题的总结

本文是工做中遇到的网站高可用问题及相关解决思路和方法的总结,比较零碎,且会在后续工做过程当中不停丰富,有不对之处,请指正。html

先后端分离

先后端分离后,可使用更加轻量级的web容器部署静态资源,如nginx等,还能够对静态资源进行cdn加速,同时针对营销或者活动页面,可使用内容管理平台,实时更改页面,快速迭代。服务端出来后,专一于业务流程,且为后续的服务拆分提供了便利。nginx

按照业务领域拆分服务

随着业务量的增长,单体架构不能再知足高并发场景,按照业务领域将服务端拆分为多个独立的服务。服务拆分后,这些服务独立部署,独立扩展,服务之间彻底解耦。web

拆分后的服务一般是无状态的,会话管理等一般交给网关层,或者统一的sso服务,业务服务省去了复杂的会话管理,服务效率提升;redis

拆分后的服务支持分布式多实例部署,从而达到按需扩展的目的,在应对突发的流量暴增时,如营销活动等,能够迅速按需扩展,提升站点的可用性。算法

集群部署,负载均衡

拆分后的服务支持分布式部署,可使用集群部署、负载均衡的方式进一步提高网站可用性。集群部署模式下,多台实例分担流量,并能灵活地增减成员实例;负载均衡机制能够确保某些成员实例失效时,能迅速将流量切换到其余正常成员实例上,从而提升站点的可用性。spring

负载均衡的方式一般有两种:数据库

  • 硬件负载——F5 7层或者4层网络代理
  • 软件负载——nginx反向代理

负载均衡的算法一般有:轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小链接数法后端

可参考:6种负载均衡算法缓存

使用缓存提升查询服务性能

在查多写少的场景,很是适用使用缓存来提高查询服务的性能,减轻对数据库的压力。一般使用redis cluster做为缓存服务器,redis cluseter机制能很大程度上保证缓存服务的高可用性,及时缓存服务故障,还能从数据库获取信息。tomcat

spring+mybatis+redis作扩展缓存的具体实践后续给出。

数据库读写分离,分库分表

业务迅猛到后面,当用户在千万级别时,数据库会成为最后的瓶颈,首先能够根据业务场景分析,考虑作读写分离。写到master库,读salve库。若是读写分离也没法知足高并发要求,须要考虑使用分表分库的思路进行横向扩展。数据库只容许单表操做对于分表分库落地很是友好,所以,在开发前期就约定,业务数据库操做必须单表操做。

读写分离,分库分表的技术手段尚未尝试过,可是如今的系统设计之初就是按照单表操做约定的,所以后续进行横向扩展时会比较便利。

orcle不是分布式数据库,但提供了RAC模式。参考:oracle rac和分布式数据库的区别

分库分表的实际落地方案是有必定难度和取舍的,其中最关键点须要考虑到sharding数的扩张,有空研究下。

数据库尽可能少使用事务

通常意义上,你们都会使用数据库级别的事务来保证业务操做的原子性和数据一致性,可是数据库事务的使用会带来性能上的损耗,为此,除非非用不可,其余时候尽可能少用。实践下来,这一条是能够作到的。

那么何时能够不用呢?简单讲前置数据库操做能够重复进行时,就能够不作事务控制。就是好比用户注册场景,会先insert ‘通行证credential’表,再insert ‘用户user’表,不使用事务控制,咱们能够将credential的操做放在user表操做前面,即便credential成功,user插入失败,对数据一致性没有影响,由于用户再次注册会从新生成一个userId,能从新insert credential后,再insert user表。对于用户的影响也和加上事务控制的效果一致。很差的影响在于多生成了一条credential记录。这里的insert ‘通行证credential’表操做就是前置数据库操做,可是非关键数据库操做,由于注册的最终效果是必须在user表中插入一条userId,后续登陆时会从user表中获取用户信息进行验证。

何时非用不可呢?在订单/支付等业务系统时,同一笔订单不容许重复支持这是底线,所以在订单支付场景,须要加上事务控制,避免订单重复支付发生。

异步化非关键业务

非关键业务是指用户不关心的业务环节,好比注册完成后,发送营销短信通知给用户,用户并不关心这个营销短信是否能及时送达。对于此类非关键业务环节,能够在设计上进行异步化处理。

经常使用的处理方式有:

  • 简单的处理方式——在流业务线程以外,另起线程/线程池来出来这类异步任务;特别须要主要线程池的使用,一般要同时限定thread size和queue size,不然在某些异常状况下,异步线程所有阻塞,致使任务堆积,会影响到主业务线程的执行。
  • 更好的方式——使用queue来做为任务的中转站,有后台job进行任务的离线处理,这样作还能有其余便利之处,好比job做为基础设施存在,可以有效利用计算资源。

异步化须要考虑业务场景是不是关键场景,任务是否能够容忍丢失。若是不容忍丢失,则智能使用queue的方式,且要对消息进行持久化。

使用异步IO

tomcat使用NIO提高服务性能,对提升网站的可用性也是有益的。

NIO vs BIO vs AIO 须要从新研究下,后续补上。

服务降级,服务熔断

网站架构发展到后面,服务之间的调用变得错综复杂,故障发生以后可以清晰知道是那条服务链路出现了问题,并能及时处理变得很重要。所以须要对服务进行治理,提供服务注册、发现机制,在此基础上,当发现某个服务异常时,能够对该服务或者某个调用渠道进行服务降级,或者针对下游某个异常服务进行熔断处理,确保网站其余非异常服务的可用性。

好比:统一登陆服务场景,须要根据不一样的登录方式,调用下游不一样的帐户验证服务,A帐户验证服务一旦出现问题不能殃及B帐户验证,因此能够在A帐户/B帐户验证服务的调用上加上熔断机制处理,确保A帐户验证服务调用和B帐户验证服务调用之间互不影响。

这一点的设计思想是:理性地砍掉腐烂的手,继续前进,是一种舍得精神。

 

TODO......

相关文章
相关标签/搜索