相信很多朋友对企业级的负载均衡高可用实例非常感兴趣,此篇文章根据成熟的线上环境而写,旨在帮助大家迅速架构一个企业级的负载均衡高可用的web环境。

此系统架构仅映射内网VIP的80及443端口于外网的Juniper防火墙下,其它端口均关闭,内网所有机器均关闭iptables及ipfw防火墙;外网DNS指向即通过Juniper映射出来的外网地址,而此映射的地址对映的其实是内网VIP地址。这里说下端口的问题,有的朋友可能会很疑惑,这样映射端口行不?通过项目实践得知,这样完全是可行的,php-cgi需要的9000端口及MySQL的3306端口均可走内网,完全不影响业务系统的运行。

另外,我维护的电子商务网站并发大约在1000左右,此时,Nginx+Apache集群运行得非常稳定,尤其是apache,并没有想象中那般弱;其实,在内存足够(>=8G)的情况,测试时不连数据库的话,单台apache+php5能顶得住6000并发,而且相当稳定。在网站升级架构方面,我不赞成全面淘汰生级,锦上添花式的升级会更好。

第一部分:Nginx+Keepalived的说明及环境说明

喜欢看我博客或文章的朋友都知道,我一直主力推崇Nginx+Keepalived作web的负载均衡高可用架构,并积极将其用于项目方案中;Nginx负载均衡作服务器遇到的故障一般有①服务器网线松动等网络故障;②服务器硬件故障从而crash;③nginx服务死掉;遇到前二者情况,keeaplived是能起到HA的作用的;然而遇到③种情况就没有办法了,但可以通过shell监控解决这问题,从而实现真正意义上的负载均衡高可用。此篇的最新更新时间为2010年6月25号,下面将其安装步骤详细说明下:

环境:

  1. centos5.3(64位)、nginx-0.7.51、keepalived-1.1.15
  2. 主nginx负载均衡器:192.168.0.154
  3. 辅nginx负载均衡器:192.168.9.155
  4. vip:192.168.0.188

第二部分:分别安装Nginx负载均衡器及相关配置脚本

先安装Nginx负载均衡器,nginx负载的配置就用一般的模板来配置了

  1. #添加运行nginx的用户和组www
  2. groupadd www
  3. useradd -g www www
  4. wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-7.8.tar.gz
  5. tar zxvf pcre-7.8.tar.gz
  6. cd pcre-7.8/
  7. ./configure
  8. make && make install
  9. wget http://sysoev.ru/nginx/nginx-0.7.51.tar.gz
  10. tar zxvf nginx-0.7.51.tar.gz
  11. cd nginx-0.7.51/
  12. ./configure --user=www --group=www --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module
  13. make && make install

配置nginx负载均衡器的配置文件vim /usr/local/nginx/conf/nginx.conf,此篇文章仅仅只是我的某项目的配置文档,纯80转发;如果对nginx配置有https要求的可参考张宴的相关文章。

  1. user www www;
  2. worker_processes 8;
  3. pid /usr/local/nginx/logs/nginx.pid;
  4. worker_rlimit_nofile 65535;
  5. events
  6. {
  7. use epoll;
  8. worker_connections 65535;
  9. }
  10. http{
  11. include       mime.types;
  12. default_type application/octet-stream;
  13. server_names_hash_bucket_size 128;
  14. client_header_buffer_size 32k;
  15. large_client_header_buffers 4 32k;
  16. client_max_body_size 8m;
  17. sendfile on;
  18. tcp_nopush     on;
  19. keepalive_timeout 60;
  20. tcp_nodelay on;
  21. fastcgi_connect_timeout 300;
  22. fastcgi_send_timeout 300;
  23. fastcgi_read_timeout 300;
  24. fastcgi_buffer_size 64k;
  25. fastcgi_buffers 4 64k;
  26. fastcgi_busy_buffers_size 128k;
  27. fastcgi_temp_file_write_size 128k;
  28. gzip on;
  29. gzip_min_length 1k;
  30. gzip_buffers     4 16k;
  31. gzip_http_version 1.0;
  32. gzip_comp_level 2;
  33. gzip_types       text/plain application/x-javascript text/css application/xml;
  34. gzip_vary on;
  35. upstream backend
  36. {
  37. server 192.168.1.102:80;
  38. server 192.168.1.103:80;
  39. server 192.168.1.105:80;
  40. }
  41. server {
  42. listen 80;
  43. server_name www.yuhongchun027.com;
  44. location / {
  45. root /var/www ;
  46. index index.jsp index.htm index.html;
  47. proxy_redirect off;
  48. proxy_set_header Host $host;
  49. proxy_set_header X-Real-IP $remote_addr;
  50. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  51. proxy_pass http://backend;
  52. }
  53. location /nginx {
  54. access_log on;
  55. auth_basic "NginxStatus";
  56. auth_basic_user_file /usr/local/nginx/htpasswd;
  57. }
  58. log_format access '$remote_addr - $remote_user [$time_local] "$request" '
  59. '$status $body_bytes_sent "$http_referer" '
  60. '"$http_user_agent" $http_x_forwarded_for';
  61. access_log /var/log/access.log access;
  62. }
  63. }

小节:

第一部分和第二部分讲的是如何通过安装Nginx来达到负载均衡后端web集群的过程,Nginx能实现自动切换后端有故障的web服务器;但Nginx负载均衡器出了问题怎么办呢,它们之间是如何实现无故障转移的呢?

第三部分:安装Keepalived,让其分别作web及Nginx的HA

安装keepalived,并将其做成服务模式,方便以后调试。

  1. wget http://www.keepalived.org/software/keepalived-1.1.15.tar.gz
  2. #tar zxvf keepalived-1.1.15.tar.gz
  3. #cd keepalived-1.1.15
  4. #./configure --prefix=/usr/local/keepalived
  5. #make
  6. #make install
  7. #cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
  8. #cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
  9. #cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
  10. #mkdir /etc/keepalived
  11. #cd /etc/keepalived/
  12. vim keepalived.conf
  13. ! Configuration File for keepalived
  14. global_defs {
  15. notification_email {
  16. yuhongchun027@163.com
  17. }
  18. notification_email_from keepalived@chtopnet.com
  19. smtp_server 127.0.0.1
  20. smtp_connect_timeout 30
  21. router_id LVS_DEVEL
  22. }
  23. vrrp_instance VI_1 {
  24. state MASTER
  25. interface eth0
  26. virtual_router_id 51
  27. mcast_src_ip 192.168.0.154    <==主nginx的IP地址
  28. priority 100
  29. advert_int 1
  30. authentication {
  31. auth_type PASS
  32. auth_pass chtopnet
  33. }
  34. virtual_ipaddress {
  35. 192.168.0.188                      <==vip地址
  36. }
  37. }
  38. #service keepalived start

我们来看一下日志:

  1. [root@ltos ~]# tail /var/log/messages
  2. Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering new address record for 192.168.0.188 on eth0.
  3. Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering new address record for 192.168.0.154 on eth0.
  4. Oct 6 03:25:03 ltos avahi-daemon[2306]: Registering HINFO record with values 'I686'/'LINUX'.
  5. Oct 6 03:25:23 ltos avahi-daemon[2306]: Withdrawing address record for fe80::20c:29ff:feb9:eeab on eth0.
  6. Oct 6 03:25:23 ltos avahi-daemon[2306]: Withdrawing address record for 192.168.0.154 on eth0.
  7. Oct 6 03:25:23 ltos avahi-daemon[2306]: Host name conflict, retrying with <ltos-31>

很显然vrrp已经启动,我们还可以通过命令来检查

  1. [root@ltos html]# ip addr
  2. 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
  3. link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
  4. inet 127.0.0.1/8 scope host lo
  5. inet6 ::1/128 scope host
  6. valid_lft forever preferred_lft forever
  7. 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
  8. link/ether 00:0c:29:ba:9b:e7 brd ff:ff:ff:ff:ff:ff
  9. inet 192.168.0.154/24 brd 192.168.0.255 scope global eth0
  10. inet 192.168.0.188/32 scope global eth0
  11. inet6 fe80::20c:29ff:feba:9be7/64 scope link
  12. valid_lft forever preferred_lft forever
  13. 3: sit0: <NOARP> mtu 1480 qdisc noop
  14. link/sit 0.0.0.0 brd 0.0.0.0

说明vip已经启动,这样主服务器就配置好了,辅机的配置大致一样,除了配置文件有少部分的变化,下面贴出辅机的配置文件:

  1. ! Configuration File for keepalived
  2. global_defs {
  3. notification_email {
  4. yuhongchun027@163.com
  5. }
  6. notification_email_from keepalived@chtopnet.com
  7. smtp_server 127.0.0.1
  8. smtp_connect_timeout 30
  9. router_id LVS_DEVEL
  10. }
  11. vrrp_instance VI_1 {
  12. state BACKUP
  13. interface eth0
  14. virtual_router_id 51
  15. mcast_src_ip 192.168.0.155              <==辅nginx的IP的地址
  16. priority 100
  17. advert_int 1
  18. authentication {
  19. auth_type PASS
  20. auth_pass chtopnet
  21. }
  22. virtual_ipaddress {
  23. 192.168.0.188
  24. }
  25. }

第四部分:针对Keepalived的不足,用Nginx_pid.sh来监控nginx进程,实现真正意义上的负载均衡高可用。

针对Nginx+Keepalived,编写nginx监控脚本nginx_pid.sh,此脚本思路其实也很简单,即放置在后台一直监控nginx进程;如进程消失,尝试重启nginx,如是失败则立即停掉本机的keepalived服务,让另一台负载均衡器接手,此脚本直接从生产环境下载:

  1. vim /root/nginx_pid.sh
  2. #!/bin/bash
  3. while  :
  4. do
  5. nginxpid=`ps -C nginx --no-header | wc -l`
  6. if [ $nginxpid -eq 0 ];then
  7. /usr/local/nginx/sbin/nginx
  8. sleep 5
  9. nginxpid=`ps -C nginx --no-header | wc -l`
  10. if [ $nginxpid -eq 0 ];then
  11. /etc/init.d/keepalived stop
  12. fi
  13. fi
  14. sleep 5
  15. done

然后置于后台运行 sh /root/nginx_pid.sh &,这种写法是错误的,这样你用root用户logout后,此进程会消失;正确写法为nohup/bin/bash /root/nginx_pid.sh &,附带下注释:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令。该命令可以在你退出root帐户之后继续运行相应的进程。nohup就是不挂起的意思( no hang up),哈哈,差点老马失蹄了。

后记:

我的线上环境网络非常复杂,这也是LVS+Keepalived失败的原因。目前此套架构在1000并发的电子商务网站非常稳定,带来的直接影响就是nginx_backup一直处于闲置状态。相对于张宴的双机轮询而言,我感觉他的可能更加完美,因为目前我的Nginx仅仅只做了负载均衡器,如果以后有机会我会尝试做负载均衡器/反向代理加速。

揭秘企业级web负载均衡完美架构的更多相关文章

  1. 企业级web负载均衡完美架构

    转载:揭秘企业级web负载均衡完美架构(图) 2010-07-06 15:16 抚琴煮酒 51CTO.com 字号:T | T 相信很多朋友对企业级的负载均衡高可用实例非常感兴趣,此篇文章根据成熟的线 ...

  2. 【系统架构】亿级Web系统搭建(1):Web负载均衡

    当一个Web系统从日访问量10万逐步增长到1000万,甚至超过1亿的过程中,Web系统承受的压力会越来越大,在这个过程中,我们会遇到很多的问题.为了解决这些性能压力带来问题,我们需要通过搭建不同的服务 ...

  3. Web负载均衡与分布式架构

     参考帖子: Web负载均衡的几种实现方式 大型网站架构系列:负载均衡详解(上) DNS 原理入门 解决nginx负载均衡的session共享问题 什么是消息队列 Java应用架构的演化之路 Java ...

  4. web负载均衡

    在有些时候进行扩展是显而易见的,比如下载服务由于带宽不足而必须进行的扩展,但是,另一些时候,很多人一看到站点性能不尽如人意,就马上实施负载均衡等扩展手段,真的需要这样做吗?当然这个问题也只有他们自己能 ...

  5. web负载均衡整理

    参考:http://www.cnblogs.com/lovingprince/archive/2008/11/13/2166350.html http://www.cnblogs.com/loving ...

  6. 六大Web负载均衡原理与实现

    还有个姊妹篇也可以参考这个文章:LVS(Linus Virtual Server):三种负载均衡方式比较+另三种负载均衡方式, LVS 实现了负载均衡,NAT,DR,TUN zookeeper使用ZA ...

  7. Web负载均衡学习笔记之实现负载均衡的几种实现方式

    0x00 概要 负载均衡(Load Balance)是集群技术(Cluster)的一种应用.负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力.目前最常见的负载均衡应用是Web负载均衡.根 ...

  8. web负载均衡【总结归纳所有看过的资料的理论】

    web负载均衡 在有些时候进行扩展是显而易见的,比如下载服务由于带宽不足而必须进行的扩展,但是,另一些时候,很多人一看到站点性能不尽如人意,就马上实施负载均衡等扩展手段,真的需要这样做吗?当然这个问题 ...

  9. 企业级Nginx负载均衡与keepalived高可用实战(一)Nginx篇

    1.集群简介 1.1.什么是集群 简单地说,集群就是指一组(若干个)相互独立的计算机,利用高速通信网络组成的一个较大的计算机服务系统,每个集群节点(即集群中的每台计算机)都是运行各自服务的独立服务器. ...

随机推荐

  1. 毛玻璃CHBlurEffect

    1.将需要加入毛玻璃的UI控件传入接口即可 1.1 .h文件 // // 文 件 名:CHBlurEffect.h // // 版权所有:Copyright © 2018年 leLight. All ...

  2. Python中__call__的用法

    概念: Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的.换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符.  示例: 所 ...

  3. git 命令总结(转)

    结构图: <1> Workspace:工作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 一.新建代码库   # 在当前目录新建 ...

  4. Bit(位) and Byte(字节) ASCll 编码【基础】

    Bit(位) 与Byte(字节)的区别bit意为“位”,是计算机运算的基础,与数据处理速度和传输速度有关.比如:USB2.0标准接口传输速率为480Mbps,其中bps=bits per second ...

  5. loj#6435. 「PKUSC2018」星际穿越(倍增)

    题面 传送门 题解 我们先想想,在这个很特殊的图里该怎么走最短路 先设几个量,\(a_i\)表示\([a_i,i-1]\)之间的点都和\(i\)有边(即题中的\(l_i\)),\(l\)表示当前在计算 ...

  6. 前端开发快速定位bug的一些小技巧

    1,根据报错信息定位: (1) Uncaught TypeError: Cannot read property 'attr' of undefined; 此类型为变量或者对象属性未定义类型. (2) ...

  7. AtCoder - 2581 树状数组

    You are given an integer sequence of length N, a= {a1,a2,…,aN}, and an integer K. a has N(N+1)⁄2 non ...

  8. linux 虚拟环境问题

    1.python环境 python2和python3命令用来区分python版本 pip2和pip3命令用来区分pip,你的包到底安装在哪里pip3 install xxx sudo apt inst ...

  9. appium环境配置和一个例子

    最近觉得appium挺火的,看了一些资料,本来想使用npm在线安装,遇见各种问题,先简单说一下: 在cmd窗口中使用命令:npm install -g appium安装,报无python的error, ...

  10. vmware正在使用中问题

    解决方法:找到vmware目录下的.lck文件,将其删掉即可.