Keepalived+Tengine實現高可用叢集
概述
近年來隨著Nginx在國內的發展潮流,越來越多的網際網路公司使用Nginx;憑Nginx的高效能、穩定性等成為了眾多IT者青睞的WEB反向代理伺服器;但是Nginx雖然有很強大的代理功能,只有一臺Nginx伺服器難免不會出現問題,這就形成了單點故障的問題,而恰好可以使用Keepalived來解決單點的故障問題,Keepalived故障轉移時間比較短,而且配置簡單易用,這也是選擇Keepalived做高可用的一個主要原因所在,如果日PV值不是很大的中小型企業可以考慮使用這種方案
Tengine
Tengine是由淘寶網發起的Web伺服器專案。它在Nginx的基礎上,針對大訪問量網站的需求,添加了很多高階功能和特性。Tengine的效能和穩定性已經在大型的網站如淘寶、天貓商城等得到了很好的檢驗。它的最終目標是打造一個高效、穩定、安全、易用的Web平臺
Tengine特性:
1、繼承Nginx-1.2.9的所有特性,100%相容Nginx的配置
2、動態模組載入(DSO)支援。加入一個模組不再需要重新編譯整個Tengine
3、更加強大的負載均衡能力,包括一致性hash模組、會話保持模組,還可以對後端的伺服器進行主動健康4、檢查,根據伺服器狀態自動上線下線
5、輸入過濾器機制支援。通過使用這種機制Web應用防火牆的編寫更為方便
6、組合多個CSS、JavaScript檔案的訪問請求變成一個請求
7、自動根據CPU數目設定程序個數和繫結CPU親緣性
8、監控系統的負載和資源佔用從而對系統進行保護
9、更強大的防攻擊(訪問速度限制)模組
10、動態指令碼語言Lua支援。擴充套件功能非常高效簡單
......
一、Nginx+Keepalived有兩種配置高可用方法
1、Nginx+Keepalived主備模式
使用一個虛擬IP地址即可,前端有兩臺Nginx伺服器做排程,其中一臺為主節點而另一臺有備用節點,兩臺伺服器只有一臺提供服務,而另一臺處於閒置的狀態,只有主節點伺服器出現故障時備用節點伺服器才會接管主節點伺服器上的所有服務及虛擬IP並繼續提供服務,而這一切對客戶端來說是透明的
2、Nginx+Keepalived主主模式
這種模式需要使用兩個虛擬IP地址,前端有兩臺Nginx伺服器做排程,兩臺伺服器互為主備並同時工作,如果其中一臺伺服器出現故障時,將會把所有請求都轉發到另一臺伺服器上面,這種做是不是很經濟實惠,兩臺伺服器同時提供服務,相比主備模式不僅分擔了一臺伺服器的壓力還提高了併發量
二、下面以一個案例來配置說明Keepalived+Nginx是如何實現高可用
環境介紹:
系統版本:CentOS 6_x86_64
Tengine版本: Tengine-1.5.1
Keepalived版本:keepalived-1.2.7-3.el6
1、在Nginx1與Nginx2伺服器上安裝Tengine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
######在Nginx1安裝
[root@nginx1 ~] # useradd -r nginx
[root@nginx1 ~] # tar xf tengine-1.5.1.tar.gz
[root@nginx1 ~] # cd tengine-1.5.1
######安裝Tengine的依賴環境包
[root@nginx1 ~] # yum -y install pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel lua-devel GeoIP-devel gcc gcc-c++
[root@nginx1 ~] # ./configure \
--prefix= /usr/local/nginx \
--sbin-path= /usr/local/nginx/sbin/nginx \
--conf-path= /etc/nginx/nginx .conf \
--error-log-path= /var/log/nginx/error .log \
--http-log-path= /var/log/nginx/access .log \
--pid-path= /var/run/nginx/nginx .pid \
--lock-path= /var/lock/nginx .lock \
--user=nginx \
--group=nginx \
-- enable -mods-shared=all
[root@nginx1 tengine-1.5.1] # make && make install
######在Nginx2安裝
[root@nginx2 ~] # scp 172.16.14.1:/root/tengine-1.5.1.tar.gz ./
[root@nginx2 tengine-1.5.1] # yum -y install pcre-devel openssl-devel libxml2-devel libxslt-devel gd-devel lua-devel GeoIP-devel gcc gcc-c++
[root@nginx2 tengine-1.5.1] # ./configure \
--prefix= /usr/local/nginx \
--sbin-path= /usr/local/nginx/sbin/nginx \
--conf-path= /etc/nginx/nginx .conf \
--error-log-path= /var/log/nginx/error .log \
--http-log-path= /var/log/nginx/access .log \
--pid-path= /var/run/nginx/nginx .pid \
--lock-path= /var/lock/nginx .lock \
--user=nginx \
--group=nginx \
-- enable -mods-shared=all
[root@nginx2 tengine-1.5.1] # make && make install
|
2、在Nginx1與Nginx2伺服器上為Tengine準備Sysv服務指令碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 115 116 117 118 119 |
######Nginx1提供指令碼
[root@nginx1 ~] # vim /etc/init.d/nginx
#!/bin/sh
# nginx - this script starts and stops the nginx daemon
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc .d /init .d /functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" =
"no" ] &&
exit 0
nginx= "/usr/local/nginx/sbin/nginx"
prog=$( basename $nginx)
NGINX_CONF_FILE= "/etc/nginx/nginx.conf"
[ -f /etc/sysconfig/nginx ] && .
/etc/sysconfig/nginx
lockfile= /var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`nginx -V 2>&1 | grep
"configure arguments:" |
sed 's/[^*]*--user=\([^ ]*\).*/\1/g'
-`
options=`$nginx -V 2>&1 | grep
'configure arguments:' `
for opt
in $options;
do
if [ ` echo
$opt | grep
'.*-temp-path' ` ]; then
value=` echo
$opt | cut -d "="
-f 2`
if [ ! -d "$value" ];
then
# echo "creating" $value
mkdir -p $value &&
chown -R $user $value
fi
fi
done
}
start() {
[ -x $nginx ] || exit
5
[ -f $NGINX_CONF_FILE ] || exit
6
make_dirs
echo -n $ "Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval - eq 0 ] &&
touch $lockfile
return $retval
}
stop() {
echo -n $ "Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval - eq 0 ] &&
rm -f $lockfile
return $retval
}
restart() {
configtest || return
$?
stop
sleep 1
start
}
reload() {
configtest || return
$?
echo -n $ "Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status > /dev/null 2>&1
}
case
"$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|
try-restart|reload|force-reload|configtest}"
exit 2
esac
######將Nginx加入到系統服務並啟動
[root@nginx1 ~] # chmod +x /etc/init.d/nginx
[root@nginx1 ~] # chkconfig --add nginx
[root@nginx1 ~] # service nginx start
######將Nginx1指令碼拷貝到Nignx2伺服器上並加入系統服務
[root@nginx2 ~] # scp 172.16.14.1:/etc/init.d/nginx /etc/init.d/
[root@nginx2 ~] # chmod +x /etc/init.d/nginx
[root@nginx2 ~] # chkconfig --add nginx
[root@nginx2 ~] # service nginx start
|
3、訪問測試Nginx服務是否正常
3.1、在Nginx1伺服器上測試
1 2 |
[root@nginx1 ~] # netstat -anpt|grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 15088 /nginx
|
3.2、在Nginx2伺服器上測試
1 2 |
[root@nginx2 ~] # netstat -anpt|grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 7281 /nginx
|
三、在Httpd1與Httpd2伺服器上安裝Apache
1、在Httpd1伺服器配置好YUM源,使用YUM安裝HTTPD服務
1 2 3 4 5 |
[root@httpd1 ~] # yum -y install httpd
[root@httpd1 ~] # chkconfig httpd on
[root@httpd1 ~] # service httpd start
######為Httpd1提供測試頁
[root@httpd1 ~] # echo '<h1>172.16.14.3 httpd1</h1>' > /var/www/html/index.html
|
2、在Httpd2伺服器配置好YUM源,使用YUM安裝HTTPD服務
1 2 3 4 |
[root@httpd2 ~] # yum -y install httpd
[root@httpd2 ~] # chkconfig httpd on
[root@httpd2 ~] # service httpd start
[root@httpd2 ~] # echo '<h1>172.16.14.4 httpd2</h1>' > /var/www/html/index.html
|
四、配置Tengine
1、將主配置檔案備份一份然後修改主配置檔案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 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 |
[root@nginx1 ~]# cd /etc/nginx/
[root@nginx1 nginx]# cp nginx.conf nginx.conf.bak
[root@nginx1 nginx]# vim nginx.conf
user nginx nginx;
worker_processes 2;
worker_rlimit_nofile 51200;
#error_log logs/error.log;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 51200;
}
# load modules compiled as Dynamic Shared Object (DSO)
dso { #實現動態載入模組
load ngx_http_upstream_session_sticky_module.so; #載入session模組
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"' ;
access_log logs/access. log main;
client_max_body_size 20m;
client_header_buffer_size 16k;
large_client_header_buffers 4 16k;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
gzip on; #開啟壓縮
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_proxied any;
gzip_http_version 1.1;
gzip_comp_level 3;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;
proxy_temp_path /tmp/proxy_temp;
proxy_cache_path /tmp/proxy_cache levels=1:2 keys_zone=cache_one:500m inactive=1d max_size=3g;
proxy_connect_timeout 50;
proxy_read_timeout 600;
proxy_send_timeout 600;
proxy_buffer_size 128k;
proxy_buffers 16 256k;
proxy_busy_buffers_size 512k;
proxy_temp_file_write_size 1024m;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404 http_502 http_504;
upstream allen {
server 172.16.14.3;
server 172.16.14.4;
check interval=3000 rise=2 fall=5 timeout=1000 type=http; #後端Server健康狀態檢查
check_http_send "GET / HTTP/1.0\r\n\r\n" ;
check_http_expect_alive http_2xx http_3xx;
session_sticky; #保持會話連線
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http: //allen;
}
location /status { #實現狀態監控
check_status;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# HTTPS server
#
#server {
# listen 443;
# server_name localhost;
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_timeout 5m;
# ssl_protocols SSLv2 SSLv3 TLSv1;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
註釋:Nginx的更多引數介紹請檢視前面的部落格
|
2、重啟Tengine服務訪問測試負載均衡
1 |
[root@nginx1 ~] # service nginx restart
|
由上圖可見可以成功訪問到後端的Httpd服務,接下來訪問測試狀態監控模組
3、在Nginx2伺服器配置Tengine主配置檔案
1 2 3 4 |
######複製Nginx1伺服器上的配置檔案到Nginx2伺服器
[root@nginx2 ~] # scp 172.16.14.1:/etc/nginx/nginx.conf /etc/nginx/
[root@nginx2 ~] # service nginx restart
註釋:重啟Tengine服務並測試;測試方法同Nginx1伺服器,這裡就不再做測試了
|
五、安裝Keepalived並配置
1、在Nginx1與Nginx2伺服器上安裝Keepalived
1 2 3 4 |
|