目录
1、高可用、负载均衡、可扩展架构的需要背景
2、系统架构
3、系统规划及说明
4、系统部署及测试
5、总结
1、高可用、负载均衡、可扩展架构的需要背景
从互联网诞生以来,网站架构随着互联网的快速发展发生着巨大的变化,现今,数据每天都在以爆炸式的增长,大数据、云计算等概念被业内炒得沸沸扬扬,这些前沿技术也在各行各业落地开花。每一种新技术的提出几乎都会或多或少影响着IT的基础架构,面对数据的快速增长、我们急需一套高可用、负载均衡、可扩展的架构来作为支撑。
2、系统架构
此次博文介绍一套高可用、负载均衡、可扩展的系统架构方案,此方案能满足多数企业需要,并能随着业务的变化进行系统扩展,并尽量避免单点故障,发架设在此系统上的应用能实现365*7*24服务不中断。架构上对应用进行了拆分,如下的架构图:
第一层:负载均衡层,此层是用户的入口,此处的服务器担任director的角色,它把用户的请求根据其调度算法调度到后端的服务器上,能胜任调度器的开源软件有LVS、Haproxy、Nginx、Tengine等,为了避免单点故障,director需要做高可用,在开源软件有Hertbeat、keepalived等;
第二层:web应用层,这一层是部署具体web应用的,一般常见的web应用有httpd、php、tomcat、nginxt等,这个层次把具有各种不同的运用划分成一个组,这个组能提供相同的web服务,配合第一层就能实现负载均衡和故障隔离的效果;
第三层:数据库层,这里是在提供动态站点时程序与数据库交互数据的地方,在这个层次上一般所用的开源软件有mysql、mariadb、redis、nosql类的数据库等,数据库的设计上也应该考虑到高可用性,负载均衡功能,比如mysql的主从架构,MMM架构,或为了实现读写分离,引入中间件淘宝的amoeba、奇虎360的Atlas;
第四层:分布式文件系统层,这个系统主要是为解决web应用数据共享的,当然数据库层中需要持久化的数据也可以放在分分布式文件系统中,开源软件有MooseFs、MgileFS、GlusterFS、FastDFS、GFS、TFS等。
如果网站随着用户的增多,web应用服务器和数据库服务器的压力越来越大,那就需要考虑加入缓存层,在web应用程序前端可加入缓存web静态数据的缓存层,开源解决方案有squid、varnish、ats等,ats是yahoo向ASF贡献的一个项目;在数据库层的前端也可加入缓存层,用来缓存web应用程序从数据库中查询的数据,可以把查询的sql语句和结果存放在一个缓存中,一般所用的服务是memcached。
3、系统规划及说明
此次博文不会把涉及系统部署的全部过程都描述,只是把重要的部分进行记录与讲解。
此次测试中所使用的服务器信息整理如下表:
说明:此次用两主机配置成tomcat容器提供jsp程序的运行环境,并且在主机上安装httpd,用反向代理的方式向前端的tengine反向代理提供服务,测试环境中mysql服务器只有规划了一台,在实际生产环境下请用主从架构或MMM等有架构,nod1和nod2主机上还部署了memcached服务,它主要是在为了给tomcat中的session信息作高可用的,此次采用是MSM(Memcached Session Manager)方案实现tomcat中对session的高可用;nod3与nod4利用tengine提供反向代理的功能,keepalived实现tengine的高可用,以避免单点故障。
4、系统部署及测试
虽说在系统部署上没有严格要求有什么先后顺序,但按照一定的顺序来部署会让工作变得简单有序,这让你对整个项目有了全局观,对项目管理人员来说能更好的协调人员,能更好的掌握控制项目的进度。一般按照以下顺序来部署:
a)、部署分布式文件系统,此次博文不讨论这部分;
b)、数据库系统部署;
c)、应用服务器部署;
d)、director部署;
当然有些是有交集的,但基本要遵循“先后端再前端”的大原则,即先部署后端的服务应用,再去部署前端面的服务和应用。
4.1、分布式文件部署
这个可以根据自己熟悉的开源系统来部署。MooseFS是一个不错的选择。部署过程此博文不讨论,略。。。。
4.2、数据库及memcached部署
请参照前边的博文进行mysql主从架构的部署,此次使用单一的mysql进行测试。mysql主从架构搭建博文地址:http://zhaochj.blog.51cto.com/368705/1635982
数据库搭建好后,创建一个供测试的数据库,并建立一个用户供测试站点的使用。
memcached直接用yum源中进行安装(nod1与nod2安装方式相同):
[root@nod1 ~]# yum -y install memcached [root@nod1 ~]# service memcached start [root@nod1 ~]# netstat -tnl | grep 11211 tcp 0 0 0.0.0.0:11211 0.0.0.0:* LISTEN tcp 0 0 :::11211 :::* LISTEN
4.3、apache+tomcat部署
nod0与nod2上tomcat与httpd的部署相同,只是在配置参数上有点不同。
jdk安装配置:
[root@nod0 msm]# pwd /root/software/msm [root@nod0 msm]# rpm -ivh jdk-8u45-linux-x64.rpm [root@nod0 msm]# vim /etc/profile.d/java.sh JAVA_HOME=/usr/java/jdk1.8.0_45 export PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME [root@nod0 msm]# source /etc/profile.d/java.sh [root@nod0 msm]# java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
tomcat安装配置:
[root@nod0 msm]# tar -xf apache-tomcat-7.0.62.tar.gz -C /usr/local/ [root@nod0 local]# ln -sv apache-tomcat-7.0.62 tomcat [root@nod0 local]# vim /etc/profile.d/tomcat.sh CATALINA_HOME=/usr/local/tomcat export PATH=$CATALINA_HOME/bin:$PATH export CATALINA_HOME [root@nod0 local]# source /etc/profile.d/tomcat.sh [root@nod0 local]# catalina.sh version Using CATALINA_BASE: /usr/local/tomcat Using CATALINA_HOME: /usr/local/tomcat Using CATALINA_TMPDIR: /usr/local/tomcat/temp Using JRE_HOME: /usr/java/jdk1.8.0_45 Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar Server version: Apache Tomcat/7.0.62 Server built: May 7 2015 17:14:55 UTC Server number: 7.0.62.0 OS Name: Linux OS Version: 2.6.32-358.el6.x86_64 Architecture: amd64 JVM Version: 1.8.0_45-b14 JVM Vendor: Oracle Corporation [root@nod0 msm]# vim /etc/rc.d/init.d/tomcat #服务脚本 #!/bin/sh #Description: This shell script manage apache tomcat. #Author: zhaochj #Time: 2015-4-21 #Version: 1.0 case $1 in 'start') /usr/local/tomcat/bin/catalina.sh start ;; 'stop') /usr/local/tomcat/bin/catalina.sh stop ;; 'restart') /usr/local/tomcat/bin/catalina.sh stop sleep 3 /usr/local/tomcat/bin/catalina.sh start ;; *) echo "Usage:`basename $0` {start|stop|restart}" exit 1 ;; esac [root@nod0 msm]# chmod +x /etc/rc.d/init.d/tomcat
至此,jdk与tomcat安装完毕。
配置server.xml文件,使其再提供一个
这个
配置tomcat,使其成为MSM环境:
根据tomcat的版本去http://code.google.com/p/memcached-session-manager/wiki/SetupAndConfiguration下载相应的jar包,就是下边的这些包
[root@nod0 msm]# ls msm_kryo_serializers/ asm-3.2.jar memcached-session-manager-1.8.3.jar msm-kryo-serializer-1.8.3.jar kryo-1.04.jar memcached-session-manager-tc7-1.8.3.jar reflectasm-1.01.jar kryo-serializers-0.11.jar minlog-1.2.jar spymemcached-2.11.1.jar
把这些jar包全部拷贝到$CATALINA_HOME/lib目录下
[root@nod0 msm]# scp msm_kryo_serializers/* /usr/local/tomcat/lib/
再去编辑$CATALINA_HOME/conf/context.xml文件,使其配置memcached的相应功能(这里是以粘性的session的方式配置)
[root@nod0 msm]# vim /usr/local/tomcat/conf/context.xml...... ....
最后把jsp测试程序拷贝到server.xml配置文件中虚拟主机的网站目录“/tomcat/app/mysite”下,这次测试我用的是shopxx这个jsp程序。
一切准备好后就可以记动tomcat进行测试站点的安装了。这里我是把tomcat中该配置的都配置完后再启用的tomcat,其实在真正的实施过程中,你应该每修改一次配置文件你都要一边监控着日志输出,再去启用tomcat服务,看启动的过程中是否有警告、错误的信息,不要等你把配置文件修改得过多,一启动服务报错,而报的错又不是很好定位时,那你就只能慢慢排查了,然而,当我更改了一部份配置文件,只要此修改会改变tomcat的运行属性,那我就去启动一下tomcat,看日志是否有问题,没有问题再去做别的修改,这样即使有问题也比较好排查。
httpd反向代理tomcat部分:
先注释掉中心主机,即在http.conf配置文件中注释掉“DocumentRoot /var/www/html”这一行,再启用一个中心主机配置文件
[root@nod0 msm]# vim /etc/httpd/conf.d/virtual.confDocumentRoot /tomcat/app/mysite ServerName www.test.com ProxyVia Off ProxyRequests Off ProxyPreserveHost On ProxyPass / http://127.0.0.1:8081/ ProxyPa***everse / http://127.0.0.1:8081/
经过上边对tomcat与httpd的配置后,打开浏览器直接访问"http://nod0ipaddress"就可以访问我们部署的网站。
在另外的nod2节点上也按照上边的操作进行配置,只是有几点值得注意,如果是以mod_jk的方式反向代理tomcat,那server.xml中的"jvmRoute="jvm200""这里的值可不能与nod0上配置一样,还有这是nod2上jsp网站程序的安装问题,直接把nod0上的已安装过的站点程序拷贝过来就行了,不要再试着去连接数据进行安装(这样是错误的操作)。
4.4、Tengine+Keepalived部署
taobao对nginx做了众多的改进,在nginx中有些需要打第三方补丁才能实现的功能,而Tengine自身就自带了,还有在nginx的wiki中明明看到能使用的指令,但你配置后,语法检测是无法通过的,如果检查语法无误后,那这个指令只供商业订阅才支持的,只是在官方wiki中没有说明,老版本的文档中有此说明,不过好在都可以通过一些第三方模块实现相应的功能。而Tengine就不样,没有商业订阅这一说,而且Tengine还引进了更好的内存管理机制,即jemalloc,所以你完全可以选择Tengine来代替nginx。
要想Tengine支持jemalloc,那先要下载此程序,再编译Tengine时把此程序编译进来即可,下载地址:http://www.canonware.com/download/jemalloc/
[root@nod3 tengine]# pwd /root/software/tengine [root@nod3 tengine]# tar -xf jemalloc-3.6.0.tar.bz2 -C /usr/local/ #jemalloc只需要解压出来,不需要安装 [root@nod3 tengine]# yum -y install pcre-devel gd-devel #先处理依赖关系 [root@nod3 tengine]# tar xf tengine-2.1.0.tar.gz [root@nod3 tengine]# cd tengine-2.1.0 [root@nod3 tengine-2.1.0]# ./configure --prefix=/usr/local/tengine \ --sbin-path=/usr/local/tengine/sbin/nginx \ --conf-path=/etc/tengine/nginx.conf \ --error-log-path=/var/log/tengine/error.log \ --http-log-path=/var/log/tengine/access.log \ --pid-path=/var/run/tengine.pid \ --lock-path=/var/lock/subsys/tengine \ --user=nginx \ --group=nginx \ --with-file-aio \ --with-http_ssl_module \ --with-http_spdy_module \ --with-http_p_w_picpath_filter_module \ --with-http_flv_module \ --with-http_mp4_module \ --with-http_gunzip_module \ --with-http_gzip_static_module \ --with-http_auth_request_module \ --with-http_p_w_picpath_filter_module=shared \ --with-http_sub_module=shared \ --with-http_flv_module=shared \ --with-http_mp4_module=shared \ --with-http_rewrite_module=shared \ --with-http_fastcgi_module=shared \ --http-client-body-temp-path=/var/tmp/tengine/client \ --http-proxy-temp-path=/var/tmp/tengine/proxy \ --http-fastcgi-temp-path=/var/tmp/tengine/fastcgi \ --http-uwsgi-temp-path=/var/tmp/tengine/uwsgi \ --with-pcre \ --dso-path=/usr/local/tengine/dsomodule/dso \ --dso-tool-path=/usr/local/tengine/dsomodule/dsotool \ --with-jemalloc --with-jemalloc=/usr/local/jemalloc-3.6.0 [root@nod3 tengine-2.1.0]# make [root@nod3 tengine-2.1.0]# make dso_install [root@nod3 tengine-2.1.0]# make install [root@nod3 tengine-2.1.0]# mkdir -pv /var/tmp/tengine/{proxy,fastcgi,uwsgi} [root@nod3 tengine-2.1.0]# /usr/local/tengine/sbin/nginx -v Tengine version: Tengine/2.1.0 (nginx/1.6.2)
编译配置文件,例其成为反向代理服务器:
[root@nod3 tengine-2.1.0]# vim /etc/tengine/nginx.conf #配置文件中确保有以下代码 ...... http { ....... upstream be_server1 { consistent_hash $request_uri; server 192.168.0.200:80 id=1000 weight=1; server 192.168.0.202:80 id=1001 weight=1; check interval=3000 rise=2 fall=5 timeout=1000 type=http; check_http_send "HEAD / HTTP/1.0\r\n\r\n"; check_keepalive_requests 100; check_http_expect_alive http_2xx http_3xx; } server { listen 80; servern_ame www.test.com; location / { proxypass / http://be_server1; } location /status { check_status; access_log off; allow 192.168.0.0/24; deny all; } } ........ }
注释:tengine在upstream模块中引进了一致性hash算法来实现对上游服务器的负载均衡,nginx好像只有ip hash,least_conn、sticky cookie三种方式。
配置好后就可以启动tengine
[root@nod3 tengine-2.1.0]# /usr/local/tengine/sbin/nginx #启动tengine [root@nod3 tengine-2.1.0]# /usr/local/tengine/sbin/nginx -t #测试配置文件 [root@nod3 tengine-2.1.0]# /usr/local/tengine/sbin/nginx -s {stop|quit||reopen|reload|}
测试通过访问tengine的IP看能否访问到我们在tomcat上部署的网站,还可以打来tengine的状态页面查看上游服务器的状态,如下:
以同样的方法在nod4上完成部署。
最后来部署keepalived让tengine具有高可用性:
[root@nod3 ~]# yum -y install keepalived #以yum方式安装 [root@nod3 ~]# rpm -qa keepalived keepalived-1.2.13-5.el6_6.x86_64 [root@nod3 ~]# vim /etc/keepalived/keepalived.conf
保配置文件中有以下代码,主要是vrrp_instance实例的代码段
! Configuration File for keepalived global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id TENGINE_203 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 123 priority 180 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.0.111 } }
而nod4中的代码段如下:
[root@nod4 keepalived]# vim /etc/keepalived/keepalived.conf ! Configuration File for keepalived global_defs { notification_email { [email protected] [email protected] [email protected] } notification_email_from [email protected] smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id TENGINE_204 } vrrp_instance VI_1 { state BACKUP interface eth0 virtual_router_id 123 priority 179 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.0.111 } }
关于keepalived更详细的配置说明请查看http://zhaochj.blog.51cto.com/368705/1655449
两个节点的keepalived配置好后就启动keepalived服务,虚拟Ip应该是配置在MASTER节点上的,测试时把MASTER节点的keepalived服务关闭,再观察虚拟ip是否会被BACKUP节点抢占。
5、总结
此套系统部署完后,有以下优点:
a)、用户的接入端面实现了高可用,一个负载均衡器出现故障不会影响业务;
b)、web应用层可根据访问压力伸缩服务器;
c)、数据库层如果压力大了,只要jsp程序支持,可以加memcached缓存缓解mysql的压力,如果多读压力还大时,如果后端服务器的读压力还是大,那就加读写分离的中间件;
d)、分布文件系统也可随着业务的变化而进行扩容、减容。
最后此套系统还差一套报警监控系统,时时监控各服务器的运行状态,一旦有服务器负载过高或发生宕机,可以直接通知管理人员,以便处理故障。
监控可以从以下几个维度来描述:
第一、上班时间可以打开一个监控页面时时查看;
第二、打开邮件客户端,定时刷新以收取报警邮件;
第三、下班后手机24小开机,可以通过短信猫的形式接收报警短信。