天天看點

keepalived+nginx實作nginx的高可用

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 &amp;&amp; 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>] &amp;&amp; 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>] &amp;&amp; . </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&gt;&amp;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&gt;&amp;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 &amp;&amp; </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 ] &amp;&amp; </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 ] &amp;&amp; </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 &gt;</code><code>/dev/null2</code><code>&gt;&amp;1</code>

<code>case</code><code>"$1"</code><code>in</code>

<code>start)</code>

<code>rh_status_q &amp;&amp; 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 &amp;&amp; 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>&lt;h1&gt;</code><code>this</code> <code>is</code> <code>apache1&lt;/h1&gt;</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>&lt;h1&gt;</code><code>this</code> <code>is</code> <code>apache2&lt;/h1&gt;</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,如需轉載請自行聯系原作者

繼續閱讀