一步一步构建高性能Web服务网站 (2)

接上篇 一步一步构建高性能Web服务网站(1)

6. 反向代理负载均衡

终于经过这段时间的改造,终于不用担心数据库数据丢失(毕竟多台数据库的服务器同时出现问题的概率还是不高的),终于也不用存在没有及时修补的系统漏洞或者弱口令而被黑客入侵(毕竟内网的渗透还是门槛很高的)。

小白商城随着这段时间的发展,用户数也有了质的提升。从Dau 5W涨到了10W,PV也达到了50W每天。这天小白向往常一样刷新自己的网站,但是发现网站的速度又比以前还是慢了很多。登录服务器后台,发现是由于逻辑服务器(就是运行PHP的服务器)的性能到瓶颈了,但是这台服务器已经是64G内存 8核的了。所以如果继续提升这台服务器性能,总有一天也会到达性能瓶颈。所以解决的办法通过反向代理的方式把数据请求负载到不同的机器上面,从而提高整体的并发性能。

一步一步构建高性能Web服务网站 (2)_第1张图片
image

反向代理是一种非常简单的中继服务器,这类服务器主要来接受外部的数据请求。然后把数据包转发给它"后面"的服务器。"后面"的服务器处理完数据得出结果后把数据回复给反向代理服务器在由它回复给外部的请求服务器。

负载均衡是在反向代理服务器上面,每次数据请求转发到"后面"的服务器。那么"后面"的服务器可以有多台,那么转发给哪一台做具体的数据处理?那么这个过程就是负载均衡。

反向代理主要有两种4层反向代理7层反向代理,如果从实现的角度来说分为2种:硬件负载均衡器(F5负载均衡器)和软件负载均衡器(nginx、lvs)

4层反向代理 主要工作在ISO网络七层模型的第4层,比如 大名鼎鼎的LVS(还有三种网络模式,这里不表)。
7层反向代理 主要工作在ISO网络七层模型的第7层,主要是对应用层的协议(一般指的是HTTP协议)做代理。比如 Nginx服务器。

那么小白商城目前主要是Web性质的服务,所以采用Nginx七层负载均衡就足够了。通过设置反向代理网站的性能又一次提升了上来,流畅度又再一次顺滑了起来。

7. 添加DNS轮训

今天小白早上发现服务器访问不了。于是赶紧登陆后台看看发生了什么。审查一番后发现反向代理服务器的Nginx进程挂了(? 具体原因完全不知道了,可能是系统的问题吧)。所以当下这个反向代理服务器存在故障就完蛋了(不管是性能问题还是宕机)。所以规避这个问题的关键是:当这台服务器出现故障影响的人越来越好。解决方案:配置多个反向代理服务器每个服务器就可以负载均衡到"后面"的集群。然后URL转IP(DNS的过程)可以按照不同的策略返回不同的反向代理服务器的IP地址,这个过程的关键是域名和IP的一对多的映射。关于这个映射表示需要DNS提供商来设置的,通过整改后的网络架构如下(其实就是加了一台新的服务器)。

一步一步构建高性能Web服务网站 (2)_第2张图片
image

通过 DNS轮训可以有效的对 反向代理负载服务器做负载均衡,而且就算 反向服务器部分出现了问题,也不会导致所有的用户都访问不了。

8. Cache服务器和Cache服务器集群

随着网站的发展,日Dau终于突破了20w大关,日PV也顺利突破300w大关。中间除了提升了部分服务器的配置和添加了部分服务器后没有什么大的架构的变动。但是Mysql性能瓶颈还是出现了,对于高频率的查询Mysql在当前的机器数量下还是出现响应慢的情况。对于小白商城这种电商的场景下,有很多数据是不经常变动的(比如 商品描述、用户的评论表)。所以采用Redis作为服务器Cache服务器(redis作为高性能的服务器,可以每秒提供高达20w~40w的QPS),由于Redis会把数据全部放在内存中。所以我们需要估算需要Cache的数据的大小然后选定要多大的规模的集群,集群可以利用HAProxy或者Codis来反向代理Cache服务器。

一步一步构建高性能Web服务网站 (2)_第3张图片
image

通过对 逻辑服务器的源码的改造。使得一些固定不常变得数据,每次数据获取的时候先从Cache服务器里面获取,如果没有就先从 Mysql里面提取出来并Cache到Cache服务器集群里面。同样对于一些简单逻辑的数据也是存放在 Redis也是非常方便的(比如:商品被访问的次数 等等)。通过搭建速度更快的 Cache服务器集群终于大大减少了数据对 Mysql数据库的压力。

9. 搜索引擎

小白商城目前采用的是搜索策略是对Mysql全文检索,这种方式的搜索方式非常之低效,一不小心就会出现全表扫描。然而对于电商网站搜索入口是主要的流量入口,所有这里可以elasticsearch搭建搜索引擎集群(搭建集群和使用方式这里就不表了)。每次有新品上线的时候就把数据提交到elasticsearch里面,然后从里面查询就可以了。elasticsearch通过分词建立倒排序表之后查询会把查询词做分词Query,然后直接从倒排序表中捞数据就行了。所以elasticsearch会有比这Mysql更加优秀的搜索性能。

10. 消息队列

服务器消息队列在集群中的地位越来越重要了。尤其对于需要异步处理的耗时操作都可以推送到消息队列里面。然后通过消息队列消费程序来完成相应的任务。比如用户注册了,我们需要向注册的邮箱发送注册邮件。所以最佳实践就是把当前要操作的数据发送到消息队列里面,由消费程序处理发送。还有每次数据上新品的时候,也可以通过消息队列来通知搜索引擎集群更新索引,用户评论更新或者添加后可以通过消息队列来通知

11. 针对类似Weibo的时间轴的优化策略

小白商城还提供了类似于Weibo这样的互相订阅的社区服务。这之前每次用户刷新Timeline服务器就会获取当前用户关注了哪些用户,然后在获取这些用户发送的分享然后在按照时间排序所得。这个过程对数据库的操作非常重,而且由于Timeline的数据可能随时在变化(只要关注的用户发送了分享,数据就变动了。这个过程是不能预测的)。所以这部分数据不能cache的。

所以只能换个思路:首先把用户之间的互相关注的数据(也就是 "我的关注人列表"和"关注我的人的列表")存在在Redis集群里面。然后每个人分配一个独立的列表,叫做Timeline列表。每次当有一个用户发布分享的时候,就把这个操作推送到消息队里里面。然后再后台取出所有关注这个用户的所有用户,并向他们的Timeline列表里面新增进去。所以每次用户刷新的时候,只要从Timeline列表里面取数据就行了,再也不要做复杂的数据库操作了。

12. 结论

本人只是通过了最简单 最基础的方式搭建了一个高并发的Web站点,对于redis集群的高可用 数据库高可用 Mysql拆库拆表 分布式数据一致性 支付事务 还没有做阐述。以后有机会慢慢说...

版权所有,如有转载请联系我本人http://www.breakerror.com/archives/244-i.html

你可能感兴趣的:(一步一步构建高性能Web服务网站 (2))