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

有一个计算机小白(我们今天的主人公),闲来无聊搭建了一个化妆品电商网站。他的网站有3个部分构成,一部分是社区(类似于新浪微博)、另一部分是电商、最后一部分是直播(嗯没错直播)。万万没有想到这个网站真是骨骼惊奇,从建立起开始天天流量激增。这可高兴坏了小白(已经开始盘算上市敲钟了),高兴之余小白发现原来基于lnmp(linux+nginx+mysql+php Web2.0的经典配置)的网站越来越卡,于是勤奋的小白开始他的网站优化之路。工作之余,小白写下了这篇用来记录一路心路历程。(本故事纯属虚构,如有雷同算我抄袭你。我也是不是文中的小白,我倒想是他,但是我的私人网站日dau不过10...)。

1. 搭建LNMP网站

小白打开了阿里云犹豫再三选中了最低的配置。就算是最低的配置(1Mb带宽, 512MB内存 1核CPU, 20GB硬盘)一年也要500多大洋,创业么不出点血能叫创业?哦 对了,还是需要从万网上面挑选了一个域名吧。经过一番配置终于把域名 www.54-250.com解析到了对应的服务器IP了(后面还有漫长的备案手续,暂时不表啦)。

那么商城系统用什么? 自己开发?这辈子都不可能自己开发!
捣鼓一番终于小白终于把PHP-Shop(一个虚构的商城系统)安装到了服务器上面了。打开chrome输入域名加载,华丽的商城页面加载了出来。赶紧进到后台添加了几个商品,就这样 小白商城就这样开了起来。沉静在创业刚刚开始的兴奋劲中,小白已经开始思索上市的事情了。

Tips: Nginx的gzipsendfile开关最好是开启的这样会使得性能更高。

gzip和sendfile用来做什么的 gzip很简单,就是压缩了HTML和资源的体积,减少了网络的传输的数据量性能当然会好了。那么sendfile是用来干什么的?这是linux zero-copy的一个特性,传统网络程序如果要发送一个文件(这里指的 css JavaScript这些静态资源),需要先把文件内容读取到内存中(详细过程:从硬盘拷贝到内核数据空间,再从内核数据空间拷贝到用户态),然后再把数据发送给网络的对端(内存的数据拷贝到内核数据空间,然后发送给网卡)。这个过程中存在多次用户空间数据和内核数据空间的数据拷贝(仔细想想这个是不是多余的,毕竟数据只是来回拷贝 没有变化)。linux就是针对这个情况做了特殊优化,nginx的sendfile就是利用了这个特性。

2. CDN

小白商城 运营有一段时间了,日活跃用户也越来越多,大部分都是从搜索引擎过来的。随着活跃用户越来越多小白发现网站打开越来越慢,从原来只要3秒现在需要20多秒了。 阿里云也发来数条告警短信:云服务器的IO已经到峰值。小白随手打开了chrome的inspect并刷新了页面,很快发现原来网站的图片太多了。图片加载占据了90%的时间,而且加载速度还慢。

“是时候上CDN了!” 小白暗道。

CDN的全称是Content Delivery Network, 内容分发网络主要用来通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率(这是百度百科里面的话)。用大白话说就是浏览器对于网站上面的静态资源(图片、CSS、JS)的访问可以通过DNSCNAME记录,把原来访问资源的url映射到CDN的域名上面去。然后浏览器会去最近的CDN服务器(区域上面挨着近的)获取数据(如果没有数据,CDN会向他的上级获取数据,如果上级还没有数据就会向源内容获取数据,俗称“回源”)。CDN会在一定时间里面Cache这个数据,当第二次访问的时候就可以直接从Cache返回了,速度就上来了。

image

通过设置了子域名img.54-250.comres.54-250.com 2个域名的CNAME记录并把所有的image css javascript的url迁移到这2个子域名下。刷新下页面网站加载速度又快了起来,小白露出邪恶的微笑。

3. 数据库主从

小白商城自从上次上了CDN后没多久后用户又激增了,日DAU到3w了(全是钱啊)。但是页面又开始卡顿了,小白第一时间查询了CDN的系统,发现问题并不是出现在CDN上面。手动点击刷新浏览器上面的刷新按钮后有几次竟然出现了Mysql Connection Error。小白这下明白, 这是数据库到了访问的上限了。为了缓解问题首先先去阿里云上面提升了配置(4Mb带宽, 4GB内存,500G SSD硬盘),升级后访问速度又再次快了起来。但是小白担忧了起来,万一数据库损坏不能恢复了那我的心血不就付诸东流了。越想越担心还是把数据单独抽离出来做个主从热备份吧。

Mysql主从:mysql集群特性,通过简单的mysql的配置就可以让多台mysql数据库服务器组合 master-slave架构。在master-slave架构下,只能对master服务器进行写操作。master数据库服务器会把数据变动写入binlog中,并发送给slave机器(slave机器还可以有自己的slave机器)同步数据(事实上从分布式架构上面来说这种设计不能保证数据绝对的一致性)。但是master和slave可以同时抗读(可能有人会觉得,如果slave当下数据有可能和master不完全一样咋办?是存在这个问题,要适当规避)。

Myqsl主主:mysql集群的另一种搭建方式,多台服务器都是master机器,互相同步binlog。在这种情况下所有的机器都可以写入,但是要做写入隔离(试想一下,A、B两台服务器互为 master-master架构。同时 给A服务器 set id = 1, 给B服务器 set id = 2,稍后A把id = 1的信息发送给了B, B把id = 2的信息发送给了A。那么问题就来了到底id是多少?如图所示)所以对于同一个数据的设置必须hash到其中一台机器,保证数据写入的有序性。所有的服务器都是用来抗读,问题和主从架构下类似。

image

小白经过一番思索后决定使用,多主多从的架构:

image

通过搭建双主服务器,master后有拖着2个slave服务器。通过对PHP-Shop的数据库的操作逻辑加以了修改后,对写操作做了Hash操作(写隔离),对读取可以随机访问了任何一台服务器, 把原来服务器的数据同步过来后这套架构就正式上线了。经过这样一轮大刀阔斧的修改后,网站的速度又快了起来。再也没有出现过Mysql Connection Error了。

5. 局域网隔离

这段时间小白商城一直快速发展着(连小白都觉得某明奇妙)已经快到日dau 5w了。这天小白突然收到服务器流量反常激增的短信。跑到阿里云后台一瞧,发现居然是一台数据库服务器收到大量的莫名其妙的IP发来的数据包。小白立刻明白了这是被DDOS攻击了(互联网最没有技术含量的攻击,分CC和SYNC 2种,都是通过发送大量数据包来消耗服务器资源或者带宽资源)。还好数据库的服务器之前在配置的时候设置了iptable白名单,但是这台服务器的带宽还是被吃满了。幸好这次的攻击事件没有带来什么本质的损失,但是小白还是心有余悸。于是开始对后台架构开始了新一轮的改造计划。

实施如下:

image

通过组件局域网,对外网的接入是一个网关。网关把数据接入到局域网里面,传递给了逻辑服务器,逻辑服务器和数据库集群都运行在局域网内。

网关:也是一台服务器,只是这台服务器比较特殊,它有2个网卡。其中一个网卡是外网网卡,接受公网的数据请求。另一个是内网网卡,它接入了内网的交换机可以和内网的服务器进行数据通讯。

局域网防火墙:局域网的交换机都是带有防火墙。所谓防火策略总结成一句话,如果防火墙没有之前没有和外网的地址通讯过,那么当这个地址发送来数据,防火墙就会丢掉(话说就算不丢掉,按照路由器和交换机的路由策略也不知道发给谁...)。有了防火墙等于有了一个隔离,使得内网的数据必须走网关才能和公网通讯。这样内网的服务器就算有漏洞(数据库弱口令等等)也不会轻易被外网黑客利用。对外只暴露了网关,网关上面基本上只部署数据中转服务,并不部署数据库之类的软件。所以也保障了数据在内网的安全性(由于防火墙的这个特性,所以在做p2p直连的时候需要做防火墙渗透,暂时不表)。

小白购买了阿里云的VPC(阿里云虚拟私有网络,类似于局域网),折腾了数天。那么在网关服务器上面到底应该部署什么软件比较好?

【not end】接下文 一步一步构建高性能Web服务网站(2)

版权所有,如有转载请联系我本人http://www.breakerror.com/?p=218

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