keepalived+nginx實作nginx的高可用
=================================
nginx的高可用
nginx實作後端realserver的負載均衡
==================================
實驗環境:
OS:Centos 6.4(redhat 6.4)
yum源:
1
2
3
4
5
6
7
8
9
10
11
<code>[centos]</code>
<code>name=sohu-centos</code>
<code>baseurl=http:</code><code>//mirrors</code><code>.sohu.com</code><code>/centos/</code><code>$releasever</code><code>/os/</code><code>$basearch</code>
<code>gpgcheck=1</code>
<code>enable</code><code>=0</code>
<code>gpgkey=http:</code><code>//mirrors</code><code>.sohu.com</code><code>/centos/RPM-GPG-KEY-CentOS-6</code>
<code>[epel]</code>
<code>name=sohu-epel</code>
<code>baseurl=http:</code><code>//mirrors</code><code>.sohu.com</code><code>/fedora-epel/</code><code>$releasever/$basearch/</code>
<code>enable</code><code>=1</code>
<code>gpgcheck=0</code>
<code></code>
拓撲圖:
<a href="http://blog.51cto.com/attachment/201309/145632498.png" target="_blank"></a>
拓撲圖的規劃:
IP位址
軟體
Master
172.16.22.1(VIP:172.16.22.100)
keepalived+nginx
Backup
172.16.22.2(VIP:172.16.22.100)
apache1
172.16.22.3
httpd
apache2
172.16.22.4
此架構需考慮的問題
1)、Master沒挂,則Master占有vip且nginx運作在Master上
2)、Master挂了,則backup搶占vip且在backup上運作nginx服務
3)、如果master伺服器上的nginx服務挂了,則vip資源轉移到backup伺服器上
4)、檢測後端伺服器的健康狀态
Master和Backup兩邊都開啟nginx服務,無論Master還是Backup,當其中的一個keepalived服務停止後,vip都會漂移到keepalived服務還在的節點上,
如果要想使nginx服務挂了,vip也漂移到另一個節點,則必須用腳本或者在配置檔案裡面用shell指令來控制。
首先必須明确後端伺服器的健康狀态檢測keepalived在這種架構上是無法檢測的,後端伺服器的健康狀态檢測是有nginx來判斷的,但是nginx的檢測機制有一定的缺陷,後端伺服器某一個當機之後,nginx還是會分發請求給它,在一定的時間内後端服務響應不了,nginx則會發給另外一個伺服器,然後當客戶的請求來了,nginx會一段時間内不會把請求分發給已經當機的伺服器,但是過一段時間後,nginx還是會把分發請求發給當機的伺服器上。
一、安裝keepalived+nginx
Master:
1、安裝keepalived和編譯安裝nginx
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<code>[root@jie1 ~]</code><code># yum -y install keepalived</code>
<code>[root@jie1 ~]</code><code>#tar xf nginx-1.4.2.tar.gz</code>
<code>[root@jie1 ~]</code><code>#yum -y groupinstall "Development tools" "Server Platform Development"</code>
<code>[root@jie1 ~]</code><code>#yum -y install pcre-devel</code>
<code>[root@jie1 ~]</code><code># cd nginx-1.4.2</code>
<code>[root@jie1 nginx-1.4.2]</code><code># groupadd nginx</code>
<code>[root@jie1 nginx-1.4.2]</code><code># useradd -r -g nginx nginx</code>
<code>[root@jie1 nginx-1.4.2]</code><code>#./configure \</code>
<code>--prefix=</code><code>/usr</code><code>\</code>
<code>--sbin-path=</code><code>/usr/sbin/nginx</code><code>\</code>
<code>--conf-path=</code><code>/etc/nginx/nginx</code><code>.conf \</code>
<code>--error-log-path=</code><code>/var/log/nginx/error</code><code>.log \</code>
<code>--http-log-path=</code><code>/var/log/nginx/access</code><code>.log \</code>
<code>--pid-path=</code><code>/var/run/nginx/nginx</code><code>.pid \</code>
<code>--lock-path=</code><code>/var/lock/nginx</code><code>.lock \</code>
<code>--user=nginx \</code>
<code>--group=nginx \</code>
<code>--with-http_ssl_module \</code>
<code>--with-http_flv_module \</code>
<code>--with-http_stub_status_module \</code>
<code>--with-http_gzip_static_module \</code>
<code>--http-client-body-temp-path=</code><code>/var/tmp/nginx/client/</code><code>\</code>
<code>--http-proxy-temp-path=</code><code>/var/tmp/nginx/proxy/</code><code>\</code>
<code>--http-fastcgi-temp-path=</code><code>/var/tmp/nginx/fcgi/</code><code>\</code>
<code>--http-uwsgi-temp-path=</code><code>/var/tmp/nginx/uwsgi</code><code>\</code>
<code>--http-scgi-temp-path=</code><code>/var/tmp/nginx/scgi</code><code>\</code>
<code>--with-pcre</code>
<code>[root@jie1 nginx-1.4.2]</code><code># make && make install</code>
2、提供nginx的system V服務腳本檔案
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<code>[root@jie1 nginx-1.4.2]</code><code># vim /etc/rc.d/init.d/nginx</code>
<code>#!/bin/sh</code>
<code>#</code>
<code># nginx - this script starts and stops the nginx daemon</code>
<code># chkconfig: - 85 15</code>
<code># description: Nginx is an HTTP(S) server, HTTP(S) reverse \</code>
<code># proxy and IMAP/POP3 proxy server</code>
<code># processname: nginx</code>
<code># config: /etc/nginx/nginx.conf</code>
<code># config: /etc/sysconfig/nginx</code>
<code># pidfile: /var/run/nginx.pid</code>
<code># Source function library.</code>
<code>. </code><code>/etc/rc</code><code>.d</code><code>/init</code><code>.d</code><code>/functions</code>
<code># Source networking configuration.</code>
<code>. </code><code>/etc/sysconfig/network</code>
<code># Check that networking is up.</code>
<code>[ </code><code>"$NETWORKING"</code><code>= </code><code>"no"</code><code>] && exit0</code>
<code>nginx=</code><code>"/usr/sbin/nginx"</code>
<code>prog=$(</code><code>basename</code><code>$nginx)</code>
<code>NGINX_CONF_FILE=</code><code>"/etc/nginx/nginx.conf"</code>
<code>[ -f </code><code>/etc/sysconfig/nginx</code><code>] && . </code><code>/etc/sysconfig/nginx</code>
<code>lockfile=</code><code>/var/lock/subsys/nginx</code>
<code>make_dirs() {</code>
<code># make required directories</code>
<code>user=`nginx -V 2>&1 | </code><code>grep</code><code>"configure arguments:"</code><code>| </code><code>sed</code><code>'s/[^*]*--user=\([^ ]*\).*/\1/g'</code><code>-`</code>
<code>options=`$nginx -V 2>&1 | </code><code>grep</code><code>'configure arguments:'</code><code>`</code>
<code>foropt </code><code>in</code><code>$options; </code><code>do</code>
<code>if</code><code>[ `</code><code>echo</code><code>$opt | </code><code>grep</code><code>'.*-temp-path'</code><code>` ]; </code><code>then</code>
<code>value=`</code><code>echo</code><code>$opt | </code><code>cut</code><code>-d </code><code>"="</code><code>-f 2`</code>
<code>if</code><code>[ ! -d </code><code>"$value"</code><code>]; </code><code>then</code>
<code># echo "creating" $value</code>
<code>mkdir</code><code>-p $value && </code><code>chown</code><code>-R $user $value</code>
<code>fi</code>
<code>done</code>
<code>}</code>
<code>start() {</code>
<code>[ -x $nginx ] || exit5</code>
<code>[ -f $NGINX_CONF_FILE ] || exit6</code>
<code>make_dirs</code>
<code>echo</code><code>-n $</code><code>"Starting $prog: "</code>
<code>daemon $nginx -c $NGINX_CONF_FILE</code>
<code>retval=$?</code>
<code>echo</code>
<code>[ $retval -eq0 ] && </code><code>touch</code><code>$lockfile</code>
<code>return</code><code>$retval</code>
<code>stop() {</code>
<code>echo</code><code>-n $</code><code>"Stopping $prog: "</code>
<code>killproc $prog -QUIT</code>
<code>[ $retval -eq0 ] && </code><code>rm</code><code>-f $lockfile</code>
<code>restart() {</code>
<code>configtest || </code><code>return</code><code>$?</code>
<code>stop</code>
<code>sleep1</code>
<code>start</code>
<code>reload() {</code>
<code>echo</code><code>-n $</code><code>"Reloading $prog: "</code>
<code>killproc $nginx -HUP</code>
<code>RETVAL=$?</code>
<code>force_reload() {</code>
<code>restart</code>
<code>configtest() {</code>
<code>$nginx -t -c $NGINX_CONF_FILE</code>
<code>rh_status() {</code>
<code>status $prog</code>
<code>rh_status_q() {</code>
<code>rh_status ></code><code>/dev/null2</code><code>>&1</code>
<code>case</code><code>"$1"</code><code>in</code>
<code>start)</code>
<code>rh_status_q && exit0</code>
<code>$1</code>
<code>;;</code>
<code>stop)</code>
<code>rh_status_q || exit0</code>
<code>restart|configtest)</code>
<code>reload)</code>
<code>rh_status_q || exit7</code>
<code>force-reload)</code>
<code>force_reload</code>
<code>status)</code>
<code>rh_status</code>
<code>condrestart|try-restart)</code>
<code>*)</code>
<code>echo</code><code>$</code><code>"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"</code>
<code>exit2</code>
<code>esac</code>
<code>[root@jie1 nginx-1.4.2]</code><code># chmod +x /etc/rc.d/init.d/nginx</code>
<code>[root@jie1 nginx-1.4.2]</code><code># service nginx start</code>
<code>Starting nginx: [ OK ]</code>
<code>[root@jie1 nginx-1.4.2]</code><code># scp -p /etc/rc.d/init.d/nginx 172.16.22.2:/etc/rc.d/init.d #把nginx的服務腳本複制到backup上,-p是保持原有的權限</code>
3、修改配置檔案
<code>[root@jie1 ~]</code><code># cd /etc/keepalived/</code>
<code>[root@jie1 keepalived]</code><code># vim keepalived.conf</code>
<code>global_defs {</code>
<code> </code><code>notification_email {</code>
<code> </code><code>root@localhost</code>
<code> </code><code>}</code>
<code> </code><code>notification_email_from admin@localhost</code>
<code> </code><code>smtp_server 127.0.0.1</code>
<code> </code><code>smtp_connect_timeout 30</code>
<code> </code><code>router_id LTT</code>
<code>vrrp_script chk_nginx { </code><code>#檢測nginx服務是否在運作有很多方式,比如程序,用腳本檢測等等</code>
<code> </code><code>script </code><code>"killall -0 nginx"</code> <code>#用shell指令檢查nginx服務是否存在</code>
<code> </code><code>interval 1 </code><code>#時間間隔為1秒檢測一次</code>
<code> </code><code>weight -2 </code><code>#當nginx的服務不存在了,就把目前的權重-2</code>
<code> </code><code>fall 2 </code><code>#測試失敗的次數</code>
<code> </code><code>rise 1 </code><code>#測試成功的次數</code>
<code>vrrp_instance IN_1 {</code>
<code> </code><code>state MASTER</code>
<code> </code><code>interface eth0</code>
<code> </code><code>virtual_router_id 22</code>
<code> </code><code>priority 100</code>
<code> </code><code>advert_int 1</code>
<code> </code><code>authentication {</code>
<code> </code><code>auth_type PASS</code>
<code> </code><code>auth_pass aaaa</code>
<code> </code><code>}</code>
<code> </code><code>virtual_ipaddress {</code>
<code> </code><code>172.16.22.100</code>
<code> </code><code>track_script {</code>
<code> </code><code>chk_nginx </code><code>#引用上面的vrrp_script定義的腳本名稱</code>
<code>[root@jie1 keepalived]</code><code>#scp keepalived.conf 172.16.22.2:/etc/keepalived #把配置檔案copy到Backup伺服器上,copy之前要保證Backup伺服器上面已經安裝了keepalived</code>
4、開啟keepalived和nginx的服務
<code>[root@jie1 keepalived]</code><code># service keepalived start</code>
<code>Starting keepalived: [ OK ]</code>
<code>[root@jie1 keepalived]</code><code># chkconfig --add keepalived</code>
<code>[root@jie1 keepalived]</code><code># chkconfig keepalived on</code>
<code>[root@jie1 ~]</code><code># service nginx start</code>
<code>[root@jie1 ~]</code><code># chkconfig --add nginx</code>
<code>[root@jie1 ~]</code><code># chkconfig nginx on</code>
Backup:
<code>[root@jie2 ~]</code><code># yum -y install keepalived</code>
<code>[root@jie2 ~]</code><code>#tar xf nginx-1.4.2.tar.gz</code>
<code>[root@jie2 ~]</code><code>#yum -y groupinstall "Development tools" "Server Platform Development"</code>
<code>[root@jie2 ~]</code><code>#yum -y install pcre-devel</code>
<code>[root@jie2 ~]</code><code># cd nginx-1.4.2</code>
<code>[root@jie2 nginx-1.4.2]</code><code># groupadd nginx</code>
<code>[root@jie2 nginx-1.4.2]</code><code># useradd -r -g nginx nginx</code>
<code>[root@jie2 nginx-1.4.2]</code><code>#./configure \</code>
<code> </code><code>--prefix=</code><code>/usr</code> <code>\</code>
<code> </code><code>--sbin-path=</code><code>/usr/sbin/nginx</code> <code>\</code>
<code> </code><code>--conf-path=</code><code>/etc/nginx/nginx</code><code>.conf \</code>
<code> </code><code>--error-log-path=</code><code>/var/log/nginx/error</code><code>.log \</code>
<code> </code><code>--http-log-path=</code><code>/var/log/nginx/access</code><code>.log \</code>
<code> </code><code>--pid-path=</code><code>/var/run/nginx/nginx</code><code>.pid \</code>
<code> </code><code>--lock-path=</code><code>/var/lock/nginx</code><code>.lock \</code>
<code> </code><code>--user=nginx \</code>
<code> </code><code>--group=nginx \</code>
<code> </code><code>--with-http_ssl_module \</code>
<code> </code><code>--with-http_flv_module \</code>
<code> </code><code>--with-http_stub_status_module \</code>
<code> </code><code>--with-http_gzip_static_module \</code>
<code> </code><code>--http-client-body-temp-path=</code><code>/var/tmp/nginx/client/</code> <code>\</code>
<code> </code><code>--http-proxy-temp-path=</code><code>/var/tmp/nginx/proxy/</code> <code>\</code>
<code> </code><code>--http-fastcgi-temp-path=</code><code>/var/tmp/nginx/fcgi/</code> <code>\</code>
<code> </code><code>--http-uwsgi-temp-path=</code><code>/var/tmp/nginx/uwsgi</code> <code>\</code>
<code> </code><code>--http-scgi-temp-path=</code><code>/var/tmp/nginx/scgi</code> <code>\</code>
<code> </code><code>--with-pcre</code>
<code>[root@jie2 nginx-1.4.2]</code><code># make && make install</code>
2、之前 已經從Master複制了nginx的system V服務腳本檔案,啟動nginx服務
<code>[root@jie2 ~]</code><code># service nginx start</code>
<code>[root@jie2 ~]</code><code># chkconfig --add nginx</code>
<code>[root@jie2 ~]</code><code># chkconfig nginx on</code>
<code>[root@jie2 ~]</code><code># cd /etc/keepalived/</code>
<code>[root@jie2 keepalived]</code><code># vim keepalived.conf #此配置檔案是從Master伺服器上copy過來,隻需小小改動</code>
<code>state BACKUP </code><code>#把這裡原先的MASTER改成BACKUP</code>
<code>priority 99 </code><code>#把這裡原先的100改成99</code>
4、開啟服務
<code>[root@jie2 keepalived]</code><code># service keepalived start</code>
<code>[root@jie2 keepalived]</code><code># chkconfig --add keepalived</code>
<code>[root@jie2 keepalived]</code><code># chkconfig keepalived on</code>
apache1:
1、安裝(部落客這裡用rpm包安裝,各位朋友可以用源碼編譯安裝)
<code>[root@jie3 ~]# yum -y install httpd</code>
2、建立測試網頁檔案
<code>[root@jie3 ~]# cd /</code><code>var</code><code>/www/html/</code>
<code>[root@jie3 html]# cat index.html #建一個測試網頁</code>
<code><h1></code><code>this</code> <code>is</code> <code>apache1</h1></code>
3、開啟服務
<code>[root@jie3 html]# service httpd start</code>
<code>Starting httpd: [ OK ]</code>
<code>[root@jie3 html]# chkconfig --add httpd</code>
<code>[root@jie3 html]# chkconfig httpd on</code>
apache2:
<code>[root@jie4 ~]# yum -y install httpd</code>
<code>[root@jie4 ~]# cd /</code><code>var</code><code>/www/html/</code>
<code>[root@jie4 html]# cat index.html #建一個測試網頁</code>
<code><h1></code><code>this</code> <code>is</code> <code>apache2</h1></code>
<code>[root@jie4 html]# service httpd start</code>
<code>[root@jie4 html]# chkconfig --add httpd</code>
<code>[root@jie4 html]# chkconfig httpd on</code>
此緻所有安裝已經完成。
二、nginx實作後端realserver的負載均衡,由于兩邊的配置檔案必須保持一緻,是以在Master配置完後直接copy到Backup上
<code>[root@jie1 ~]</code><code># cd /etc/nginx/</code>
<code>[root@jie1 nginx]</code><code># grep -v "#" nginx.conf | grep -v "^$"</code>
<code>worker_processes 1;</code>
<code>events {</code>
<code> </code><code>worker_connections 1024;</code>
<code>http {</code>
<code> </code><code>include mime.types;</code>
<code> </code><code>default_type application</code><code>/octet-stream</code><code>;</code>
<code> </code><code>sendfile on;</code>
<code> </code><code>keepalive_timeout 65;</code>
<code> </code><code>upstream apacheweb { </code><code>#定義負載均衡的子產品</code>
<code> </code><code>server 172.16.22.3:80 max_fails=3 fail_timeout=2s;</code>
<code> </code><code>server 172.16.22.4:80 max_fails=3 fail_timeout=2s;</code>
<code> </code><code>}</code>
<code> </code><code>server {</code>
<code> </code><code>listen 80;</code>
<code> </code><code>server_name localhost;</code>
<code> </code><code>location / {</code>
<code> </code><code>root html;</code>
<code> </code><code>index index.html index.htm;</code>
<code> </code><code>}</code>
<code> </code><code>error_page 500 502 503 504 </code><code>/50x</code><code>.html;</code>
<code> </code><code>location = </code><code>/50x</code><code>.html {</code>
<code> </code><code>location ~ \.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {</code>
<code> </code><code>root </code><code>/var/www/html</code><code>; </code><code>#此處定義後端伺服器網頁存放路徑</code>
<code> </code><code>proxy_pass http:</code><code>//apacheweb</code><code>;</code>
<code>[root@jie1 nginx]</code><code># scp nginx.conf 172.16.22.2:/etc/nginx</code>
兩邊分别重新開機服務
<code>[root@jie2 nginx]</code><code># service nginx restart</code>
<code>nginx: the configuration </code><code>file</code> <code>/etc/nginx/nginx</code><code>.conf syntax is ok</code>
<code>nginx: configuration </code><code>file</code> <code>/etc/nginx/nginx</code><code>.conf </code><code>test</code> <code>is successful</code>
<code>Stopping nginx: [ OK ]</code>
驗證負載均衡:
<a href="http://blog.51cto.com/attachment/201309/180649323.png" target="_blank"></a>
<a href="http://blog.51cto.com/attachment/201309/180726478.png" target="_blank"></a>
本部落格隻是簡單的用nginx做了方向代理和靜态頁面的負載均衡,keepalived+nginx實作高可用的nginx的動靜分離,讀寫分離,後續會持續更新
本文轉自 jie783213507 51CTO部落格,原文連結:http://blog.51cto.com/litaotao/1302100,如需轉載請自行聯系原作者