本文受互联网架构大会中美团、滴滴等互联网公司架构演进的启发,并结合自己的实践和实验,从宏观的角度讲述从简单lamp(linux apache mysql
php)到高可用web架构的一步步迭代过程。

下面的内容主要是从单一业务的角度考虑的,假设业务的复杂性不变,只有用户量和并发访问量的不断增加。

简单的lamp架构




最原始的web架构,一个httpd、php-fpm、mysql就可以运行一个B/S结构的系统或者站点。对于小并发量站点,httpd、php-fpm和mysql的结合是完全没有问题的。

迭代1:使用nginx做负载均衡

先看一下为啥要用nginx做负载,看看httpd的三种工作模式。

httpd有三种多进程处理模型(MPM, multi-processing module),分别是:

* prefork,多进程I/O模型,每个进程响应一个请求,默认模型
;有一个主进程,主要用来生成和回收n个子进程,创建套接字,不响应请求;多个子work进程,每个子进程处理一个请求;系统初始时,预先生成多个空闲进程,等待请求,最大不超过1024个;
*
worker,复用的多进程I/O模型,多进程多线程,有一个主进程,生成m个子进程,每个子进程负责生个n个线程,每个线程响应一个请求。同时并发响应请求m*n个请求。
*
event,事件驱动模型(worker模型的变种)。有一个主进程,生成m个子进程,每个进程直接响应n个请求,并发响应请求数为m*n个。httpd-2.4版本之后才有event的稳定版。

httpd的3工作模型可以很好的满足需求,且httpd在处理动态请求时,具有很高的稳定性。但是受系统资源的限制,httpd能够接受的请求数量也是有限制的,于是引入nginx做负载均衡服务器,并使用nginx的ip_hash机制进行路由,这样就可以灵活地扩充httpd服务了,部署结构如下图所示,



迭代2:动静态页面分离


httpd在处理动态请求时具有较高的稳定性,而nginx在处理纯静态资源,如js/css/png等有独特的优势,因此可以考虑,用nginx处理静态资源,用httpd处理动态资源,实现web站点的动静分离。对于静态资源,nginx直接响应,对于动态资源转发给后端的httpd服务器。



迭代3:使用功能更完善的负载软件:haproxy


nginx常用于静态资源和反向代理代理的服务器,在做负载时对会话保持功能没有haproxy完善。因此可以考虑,让nginx专门做静态资源服务器,代理功能由haproxy来承担。

对于后端的nginx服务器,由于是无状态的,可以使用轮询的机制实现负载均衡。同时由于此时nginx的服务器是无状态的,可以灵活的扩展nginx服务器。

对于后端的httpd服务器,由于需要保持会话信息,使用haproxy的cookie保持的机制来保证一个用户的会话被转发到同一台服务器上。



迭代4:使用keepalive保证haproxy高可用

引入keepalive来保证haproxy的高可用性。



迭代5:使用redis集群实现session共享

每个httpd服务器都有一个会话信息,若一台服务器宕机,即使使用了haproxy的cookie保持机制,也不能保证用户的会话信息不丢失。

一个可行的解决方法是,session共享。就是将所有httpd的session信息专门的保存起来,即使httpd宕机,用户的会话信息任然不会丢失。

这里采用CODIS来保存各个httpd的session信息,CODIS就是一个redis的一个分布式集群。



架构迭代到这,你可能已经发现,nginx和httpd此时都是无状态的,随意的停止某一台nginx或者httpd对web服务是无影响的。


说到无状态,这里可以扩展一下。既然是无状态了,那我们就可以使用Docker来替换在虚拟机或者服务器上部署nginx和httpd,只需根据需求创建对应数量的Docker容器即可。比如,网站的静态资源比较多,我们就可以动态的添加nginx服务器,添加的方式就是启动一个docker容器。

无状态也是微服务设计的规则之一,目的就是充分利用容器的灵活性,使系统可以灵活的扩展。

迭代6:用mysql主从复制和中间件实现读写分离


当httpd数量足够时,mysql可能就会出现瓶颈了。从高可用的角度,可以使用mysql的主从复制方式,来保证数据的安全和数据库的高可用性。从负载均衡的角度,可以考虑使用中间件实现读写分离。



迭代7:使用分布式文件系统

静态资源的安全性和访问的性能瓶颈也会是一个问题,这里可以考虑使用分布式文件系统、对象存储等方案,来保证静态资源的快速访问和完整性。



迭代8:使用cdn加速


当站点的访问跨区域时,即使架构再完善,也敌不过网联网的延迟,因此,对于动态资源,如图片、CSS、JS文件,可以考虑使用区域的CDN加速,从而提高站点的响应速度。



体会

最后再分享一张图片。



做这个分享的目的,就是希望可以把我知道的东西连接起来形成一个体系,分散的叫信息,能够串起来的才叫知识!

这个架构真正用起来也许会有问题,但是最起码有了基本的轮廓!欢迎大家一起交流学习。

参考

* Httpd的三种工作模式 <https://www.houfazhu.com/http-protocol/1662/>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信