高可用的网站架构
一般网站将架构分为三层,分别是应用层,服务层和数据层
应用层:位于应用层的服务器为了应对高并发下的访问需求,通常会设置负载均衡服务器将一组服务器组成集群对外提供服务。
服务层:服务层也是通过集群的方式提供高可用,不过这次的负载均衡需要在应用层进行一些设置。
数据层:为了保证数据层在发生宕机时不会出现数据丢失,在进行数据写入时,会进行数据同步复制,实现数据的冗余备份。
无状态
无状态是指应用服务器不保存业务的上下文信息,多个服务器之间完全对等,将请求发送到集群中的任意一台机子上都会得到相同的结果。
Session管理
如果应用服务器中的所有实例都是无状态的,那么矛盾就来了,因为业务上总有一些需求是有状态的,比如:电商中用户购物车中的商品,微博中查看我的私信等。
在集群的情况下,请求可以被发送到任意一个机器上,所以就需要保证每个请求发送到机子上之后,该机子仍然能拿到正确的Session。解决方法如下:
- Session复制:在集群较小的情况下可以使用Session复制来保证每一个节点上都有一份Session列表,但是一旦用户量高,就需要维护成百上千个Session的一致性了。
- Session绑定:通过负载均衡算法,保证同一个IP总是能请求到某一台机器上。但是如果这台机器发生了宕机,这个用户也就不能正常使用服务了,这与集群的初衷相违背。
- 利用Cookie记录Session:早期的企业曾经把用户的Session存储到客户端,然后每次请求都会把Session发送一次。但是Cookie能够存储的信息有限,而且每次请求都要传输Cookie,降低效率。
- 使用Session服务器:可以使用专门的Session服务器(集群),每次应用服务器需要使用Session时,就去访问Session服务器。Session服务器一般使用Redis来实现。这种解决方案实际上是将有状态和无状态的集群相隔离,可对比于数据库服务器集群的读写分离。这样做提高了应用的可伸缩性。
高可用的服务
大型网站中的服务通常都独立部署,然后应用服务器远程调用。服务和应用一样,都是无状态的,因此也可以使用负载均衡策略来实现服务层的高可用,只不过这里的负载均衡在应用层进行实现。
除此之外,还可以使用以下策略来保证服务的高可用:
- 分级管理
运维上将服务器进行分级,核心应用使用更好的硬件。比如电商中的支付服务显然要比评价服务的优先级要高。
同时在服务部署上也进行必要的隔离,避免故障的连锁反应。低优先级的服务可以使用不同的线程或者不同的虚拟机实现隔离,高优先级的服务就要部署在不同的物理机上,甚至某些核心服务和数据要部署在不同地域的数据中心。 - 超时设置
在应用中设置服务调用的超时时间,一旦超时就要采取相应的策略进行处理,比如抛异常或者重试。 - 异步调用
应用对服务的调用采用消息队列等异步的方式来完成,可以避免一个服务失败而导致整个请求失败的情况。比如一个用户注册的请求需要调用三个服务,分别是记录用户信息到数据库,给用户发送邮件提示用户注册成功,给客户开通相应的权限。此时就可以先给用户返回一个注册成功的消息,然后应用内使用消息队列给三个服务发消息,即使某个服务调用失败,服务集群也会有响应的重试策略,这样可以保证用户的请求总是能够执行成功。 - 服务降级
在网站访问的高峰期,服务可能因为大量的并发调用而导致性能下降,严重时可能导致服务器宕机。为了保证核心应用和功能的正常运行,需要对服务进行降级。
降级有两种手段:拒绝服务和关闭服务。
拒绝服务:拒绝低优先级的服务,减少服务调用的并发数
关闭服务:关闭不重要的服务,或者服务内部关闭不重要的功能 - 幂等性设计
服务调用失败后,会将服务请求转发到其他的服务器上,但是这个失败可能是虚假的失败,比如服务已经处理成功,但是因为网络的原因导致应用没有收到响应。
应用层不关心服务是否真的调用成功,只要没有按时收到响应就认为调用失败,所以幂等性需要在服务层去做(如通过交易编号查询交易信息进行幂等性校验)
数据备份
数据备份分为两种:异步热备份和同步热备份
异步热备份:应用程序收到数据写入成功的响应时,只写成功了一份数据,其他的数据副本通过异步的方式进行存储。
同步热备份:应用程序收到数据写入成功的响应时,有多份数据写入成功(所有的副本全部写入成功)
关系型数据库热备份就是通常所说的Master-Slave同步机制,Master-Slave机制不但解决了数据备份的问题,而且改善了数据库系统的性能。因为实践中Master只负责写入数据,而读取数据需要访问slave。