随着21世纪互联网的快速发展以及web2.0的诞生,最初web服务器已经不能满足我们的需求.而现在我们要考虑的不再仅仅是web服务器以及数据库服务器这么简单,我们所需要考虑的就是设计出一套高性能web解决方案,并且实现多路负载均衡,自动备援等功能.
对于一个标准的高性能web架构,我通常会分为三层,即”代理层”,”web层”和”数据层”,当然可能会随着需求的不同,我们会添加其他的应用至架构中. 而往往它们所需提供的服务也无非是这三层中的其中之一.
以下我就图1-1的拓扑图做一些解释.
代理层:
我把web cache 加速和 Load Balancer 放到了同一层,因为他们的工作都是启到了proxy的作用,只是他们所做的是不同的工作.
Web cache
提到Web cache服务器或web代理服务器(我们统称为web加速服务器),很多人往往就会想到Squid , 我曾经对一个网站做过一个测试 , 在利用了Squid做加速代理后的速度比没有利用Squid做加速代理在速度有着很明显的提升. 当然除了Squid之外还有Varnish ,并且在我的对Varnish的测试中, 发现Varnish的效果要比Squid好很多,因为正如很多资料中都提到的,Varnish在内存的利用上,比Squid有着很大的优势.所以说在一个高性能的web架构中web cache是web加速是不能缺少的.
Load Balancer
F5,梭子鱼,A10等负载均衡的设备我想对大家来说并不陌生.我用过F5的设备,也体验过梭子鱼,并且A10上海的办事处目前与我的办公室也仅仅只有一墙之隔.我不得不去承认这些负载均衡的设备的性能以及在一些生产环境中为一些现有的Load Balancer架构所作出的贡献.但是这篇文章主要是围绕着基于Linux/unix,所以在此我所提到的并不是这些厂商所提供的Load Balancer的设备,而是基于linux的Load Balancer软件 Haproxy . Haproxy可以支持数以万计的并发连接,并且满足session保持,适合用于负载较大的web站点,并且haproxy可以保护web服务器不被暴露在公网上,提高了web服务器的安全性.
看到这或许你会有疑问我为什么会把web cache 比如varnish放在了haproxy的前面?而在网上很多人都是haproxy在varnish前面,后端再通过nginx做web服务器的Load Balancer,他们的设计并没有错,也是可行的.不过我想读完下面的内容,你会知道我这么做的原因.
首先,在varnish和squid中,对负载均衡的支持并不是很完美,虽然squid和varnish都能够支持一些简单的负载均衡的工作,但是他们提供的负载均衡并不能满足我们的需求,比如squid能够支持web服务器的健康检测,但是在session保持上,squid一直没有一个很好的解决方案,还是需要通过第三方的开源软件来实现..最后squid和varnish在负载均衡的执行效率上,表现的并不是很好.所以我会建议如果条件允许的话,还是把两者分开.当然haproxy也可以通过nginx做替代,唯一要考虑的问题就是session保持的问题,但是我们可以通过memcached的session共享来解决.而在Load Balancer这层haproxy的主要工作就是将varnish的请求分发到不同的web服务器,并且支持session保持.我想你也不希望在为nginx或者squid搭建一台session共享服务器吧.所以我想haproxy会是你更好的选择.
Web层:
Web层其实很简单,正如我所定义的web层的字面意思一样,在web层中所提供的服务无非也就是web服务,比如基于java,php等语言开发的站点.在这一层中有很多开源软件能够满足你的需求.比如Apache,Nginx,lighttpd,thttpd以及cherokee等.在网上看到很多朋友对apache进行一些评论,并且有些朋友的言语还是比较激烈,而这些曾误导过很多刚刚接触linux的朋友.在这我建议各位朋友,根据不同的需求来选择不同的web server那才是最完美的,比如,你需要自己定制模块,那么apache是一个很不错的选择,很多公司比如阿里巴巴和sina在apache上都有着自己的定制的模块.如果你单纯只是用来做静态页面,那你可以选择nginx,lighttpd或者是thttpd,这些都是一个很不错的选择.在一个高性能的web站点中,将动态页面和静态页面分开,通过不同的web服务器来完成不同的工作,将会起到一些关键性的作用.因为他们能让你的站点显得快些.我想这个”快”至少是你的管理层所期待的.
数据层:
在数据层,服务器所要做的工作就是对数据进行处理.而这一层往往也是最重要的,因为他不但充当着你数据的处理工作,而且还充当着数据的存储.在数据的处理上,这个直接决定着你网站呈现给用户的速度;在数据的存储上,这层存储着你网站和用户的数据,我想你并不希望哪天因为的起初架构设计的不合理导致你页面的呈现给用户的速度很慢或者因为你的架构设计的不合理导致你最终因为某种原因而丢失了一部分用户数据.我想那时候你一定会很后悔,毕竟数据是最重要的.他决定着很多.
SQL Cache
不用我介绍,我想很多人会立马想到了Memcached(请注意是memcached,并不是memcache虽然有很多人称之为memcache但是那是错误的.) , 你不知道也没关系,因为下面我会讲下Memcached,Memcached是一款不错的分布式内存缓存系统,当客户端在与 memcached 服务建立连接之后,接下来的事情就是存取对象了,而Memcached会将这些对象存储到内存中而并非硬盘上,这也就是memcached如此高效快速的原因.值得注意的是这些对象并不是持久的,服务停止之后,里边的数据就会丢失.因为他的对象都是存储在内存中的.
我相信现在已经有很多人把Memecached运用到了生产环境中去了,而且这些人对Memcached的评价也不会太差,毕竟也只有使用过Memcached的人才知道,加入了Memcached后整体站点性能的提升的幅度.所以如果你的站点中还没有Memcached的话,你可以考虑添加Memcached到你的web架构中.
SQL Server
其实数据库的选择,我想在这个我可以直接提MySQL,因为MySQL已经是一个很成熟的网络数据库服务,并且在数据处理的性能上也已经能够远远满足很多企业的需求,Master-slave和Master-Master也已经成为了一个web架构中数据库经常用的方案.但是在这值得一提的是,在一个高性能的web架构中,数据库的读写分离这个是必不可少的.而数据库的读写分离,可以在程序中进行操作,也可以通过一些开源的相关软件做mysql的Proxy. 而这个在下文也会提到,请务必继续阅读下去.
对于web的架构的三层已经做了一些解释,其实以上是一个很标准的web架构方案,虽然称不上完美,但是我想已经足以应付一些站点的需求.不过还得请你继续往下看.因为一下还会有很多内容,当然这些介绍可能你早已经知道,但是我想花一点时间读一读还是有必要的.
在上面的内容中,我没有对自动备援,数据库的读写分离等应用做过多的介绍,是因为可能会有很多初学者看到这篇文章,而往往他们并没有完全理解我所定义的三层,不过我想如果他们读完了上面的内容,或多或少会了解一些.接下来,我就会介绍利用哪些开源的软件来实现自动备援,数据库的读写分离的proxy等工作.
自动备援:
在一个高可用性的web架构中,自动备援的功能充当着很重要的工作.因为它直接就决定着你网站的任意一台服务器在down机后的站点恢复工作的时间.就拿图1-1拓扑图来说,如果你用了DNS轮询来做的负载均衡,并且解析地址为Varnish的两台服务器,如果有一天你的一台Varnish服务器因为硬件问题down机后,我想你所要面对的问题就不用我说了,首先你得去修改你的DNS解析地址,据我所了解很多公司并没有自己的DNS服务器,他利用还是域名提供商的DNS服务器来完成域名的解析工作,而往往修改过DNS的解析地址之后并不会立即就生效,需要等待一段时间之后,最新的额DNS解析才会生效.而这段时间,意味着有一部分的客户打不开你们的网站,而这意味着你们正在面对着损失一些客户的风险.如果你们销售知道了,一定会非常生气,并且还会跑到Boss那告状.
以上的情景很多朋友都曾经历过,并且到现在为止还是没有在自己的生产环境中运用到自动备援的功能.其实想实现自动备援很简单,而现在也已经有很多软件支持了自动备援的功能.在这个我要推荐Heartbeat.
在IT行业中的心跳这个术语,我想也不用我过多的解释了.而heartbeat 也是一个心跳程序, 他的工作原理就是先虚拟出一个IP地址,我们称为VIP(Virtual IP Address)通过网络(此外还有串口,只是生产环境中很少使用串口)来告诉对方自己当前的活动状态.在两台运行的heartbeat的环境中,当一台服务器因为硬件或者其他问题,导致down机后,由于另外一台运行着heartbeat的服务器没有收到这台服务器的心跳信息时,就会把这VIP绑定到自己的网卡上,简单的说,这台服务器接手了刚刚down掉的服务器的工作.而这个时间是我们所设定的,一般我们设置为10秒.
很多朋友也已经在生产环境中使用了Heartbeat,往往架构是这样,一台服务器正常工作比如运行web服务,而另外一台服务器仅仅作为这台服务器的备份机使用,我相信很多朋友朋友都是这么来操作的,而这样你的真正在为用户提供服务的服务器也仅仅只有一台.刚刚接触Heartbeat的时候我也是这样的一个环境,但是后来我一直在想,能否让两台服务器都能够利用VIP?这样的话,两台服务器不但能够同时为用户提供服务,而且两台服务器都具备了自动备援的功能.读到这我想你一定会知道我为什么介绍Heartbeat了. 而实现原理其实很简单,通过利用不同的端口以及不同的配置文件和不同的服务来使Heartbeat完成双向的自动援备的功能.
MySQL 读写分离:
数据库在一个站点中起着至关重要的角色. 而这个时候考验的就是你的数据库的性能.很多公司在数据库服务器上花了重金,购买了较好的服务器来满足数据库性能的需求.但是这些往往不够,此时我们就需要考虑数据库的读写分离,而这里也重点介绍MySQL的读写分离.
很多程序员在写程序的时候也已经考虑到了MySQL的读写分离,他们所做的也就是将数据库的查询和添加语句区分开来,这样虽然说支持了MySQL的读写分离,但是在MySQL的Load Balancer上并不能得到很好的支持,并且不方便维护.
在MySQL的读写分离上我曾经用过MySQL Proxy 而现在用的最多的则是Amoeba,不管是从性能还是从维护来看, Amoeba的表现都比MySQL Proxy有着很大的优势,而且Amoeba在对MySQL的Load Balancer上支持也是相当的出色,再配合Heartbeat . 数据库层也便具有高可用性和自动备援.至少你可以睡的香一些.
实时同步:
一个站点中还有存在着一个让人头大的问题,就是数据的同步问题,且抛开数据库那层的同步问题,因为mysql 的master-slave或者master-master的方案已经足够帮助你完成数据库层面的同步工作.而在其他数据的同步问题,我们也并不是没有解决办法,我们可以通过利用inotify和rsync的结合来完成在其他数据,比如用户的上传文件的实时同步问题.当然如果想具备更可靠的安全性,我们还可以通过inotify和csync2来完成这个工作.
监控:
在一个高可用性的web架构中,监控也是必不可少的.而监控报警,也是我们所要做的.虽然上面介绍过的内容支持自动备援的功能,但是我想监控报警服务器的架设能够让你在第一时间知道服务器down机的信息.cacti,nagios等监控软件现在也已经在很多web架构中运用.
文件系统:
文件系统的选择也决定着一个高性能的web架构的完美性,在linux下有很多文件系统,常见的文件系统有ext3,XFS, ReiserFS以及最新推出的ext4.而这些文件系统都有着自己的所长之处,根据需求的不同,选择不同的文件系统,也会直接影响着一个高性能的web架构.
定制脚本:
一个高性能的web架构自然也不能离开定制属于自己脚本,不管是基于shell还是perl又或者是python所写的脚本,其实最终的目的只有帮助你工作.就拿Heartbeat来说,虽然自动备援的功能有了,但是却无法提供服务的检测,此时我们就需要通过定制一个脚本来对服务进行检测,如果发现此服务因为某种原因停止掉了,我们就可以通过定制的脚本关闭Heartbeat的进程,我想这样这个会更完美.而这个脚本我曾用perl写过.对于Heartbeat定制的脚本我也只是举个例子,而脚本所完成的工作远远不止这些.
安全性:
在一个高性能的web架构中,安全问题,也不能忽视,就说DDos吧,我想这个肯定会让你感到很头疼,因为你会拿DDos没有办法,它是那么的可怕.我不敢保证我能够抵抗DDos的攻击,但是我能说的只是我能防范一部分DDos的攻击,就拿juniper,cisco,中国的金盾他们的防火墙来说,他们都不敢保证能够完全抵抗的DDos的攻击.我们能做的也就是防范一部分DDos的攻击和其他的一些攻击手段,在linux下能够供我们选择的防火墙有很多iptables大家也不陌生,如果你刚刚接触Linux可能你会对packet filter(PF)感觉到陌生.其实你不用担心太多,因为不管是iptables还是基于bsd的PF都能够帮助完成一个防火墙的搭建工作,并且具备这比较高的安全性.除了防火墙的安全性之外,我认为系统的安全也是很重要的,毕竟你的服务器是托管在IDC机房,你并不知道是否有人会查看你的服务器,所以我们要做好系统的安全.给grub加入MD5后的密码是必不可少的.除此之外禁止SSH root用户的登录我想也是需要的.
链路:
在前面所提到的都是基于开源软件的.但是在一个高性能的web服务器架构中,链路问题也是值得大家所要考虑的.而我所说的链路不包括租用的带宽,而仅仅是服务器与服务器之间交换数据的链路.我曾参观过很多机房,最让我担忧的就是服务器之间的链路问题.首先是线路的质量,有些机房为了节约开销,从接入层设备到服务器的线的质量并不是很好;其次就是线路的杂乱,可能你会对杂乱有所疑问.但是你不会想到以后因为种种原因要对服务器或者线路进行调整的时候,因为线路的杂乱从而导致拔错网线或者碰掉网线,导致服务器无法提供网络服务.那时候你便会后悔当初没有好好对服务器之间的线路做些整理.因为这些完全是可以避免的.
结束语:
在一个高性能的web架构中,我们能够做的还有很多而且利用的开源软件也还会有很多,比如LVS, keepalived等等,都能够实现一个高性能的web架构,而且也具备自动备援等功能,但是我们所要做的并不是盲目的去选择一个开源的软件,而是得根据客户或者公司的需求,维护成本以及日后的扩展性等来决定着自己对开源软件的选择.