7.4.3 案例分享三:Nginx主主负载均衡架构

在和一些朋友交流Nginx+Keepalived网站架构技术时,笔者虽然已多次成功实施Nginx+Keepalived项目方案,但这些都是在用单主Nginx工作,从Nginx长期只是处于备份状态,如果想让两台Nginx负载均衡器都处于工作状态,其实通过Keepalived很容易就可以实现。

一般为了维护方便,企业网站的服务器都在自己的内部机房里,只开放了Keepalived的VIP地址的两个端口80、443,通过Juniper SSG550防火墙映射出去,外网DNS对应映射后的公网IP。此架构的防火墙及网络安全说明如下。

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

此系统架构仅映射内网VIP的80及443端口于外网的Juniper SSG550防火墙下,其他端口均关闭,内网所有机器均关闭iptables防火墙;外网DNS指向通过Juniper SSG550映射出来的外网地址。

Nginx主主架构服务器IP分配表如表7-3所示。

表7-3 Nginx主主架构服务器IP分配表

阅读 ‧ 电子书库

Nginx和Keepalived的安装比较简单,大家可以参考案例二,这里略过。以下附上两台Nginx负载均衡机器的nginx.conf配置文件,内容如下:

ser www www;

worker_processes 8;

pid /usr/local/nginx/logs/nginx.pid;

worker_rlimit_nofile 51200;

events

{

use epoll;

worker_connections 51200;

}

http

{

include mime.types;

default_type application/octet-stream;

server_names_hash_bucket_size 128;

client_header_buffer_size 32k;

large_client_header_buffers 4 32k;

client_max_body_size 8m;

sendfile on;

tcp_nopush on;

keepalive_timeout 60;

tcp_nodelay on;

fastcgi_connect_timeout 300;

fastcgi_send_timeout 300;

fastcgi_read_timeout 300;

fastcgi_buffer_size 64k;

fastcgi_buffers 4 64k;

fastcgi_busy_buffers_size 128k;

fastcgi_temp_file_write_size 128k;

gzip on;

gzip_min_length 1k;

gzip_buffers 4 16k;

gzip_http_version 1.0;

gzip_comp_level 2;

gzip_types text/plain application/x-javascript text/css application/xml;

gzip_vary on;

upstream backend

{

server 192.168.1.17:80;

server 192.168.1.18:80;

}

server

{

listen 80;

server_name www.1paituan.com;

location / {

root /var/www/html ;

index index.php index.htm index.html;

proxy_redirect off;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass http://backend;

}

location /nginx {

access_log off;

auth_basic "NginxStatus";

}

log_format access '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for';

access_log /data/logs/access.log access;

}

}

这里简单解释一下配置Keepalived文件的原理,其实就是通过Keepalived生成两个实例,两台Nginx互为备份,即第一台是第二台机器的备机,第二台机器也是第一台的备机,生成的两个VIP地址分别对应我们的网站http://www.1paituan.com ,这样大家在公网上都可以通过DNS轮询来访问得到该网站。任何一台Nginx机器如果发生硬件损坏,Keepalived会自动将它的VIP地址切换到另一台机器,而不影响客户端的访问,这个跟LVS+Keepalived多实例的原理是一样的,相信大家很容易就能明白。

主Nginx机器之一的keepalived.conf配置文件如下:

! Configuration File for keepalived

global_defs {

notification_email {

yuhongchun027@163.com

}

notification_email_from keepalived@chtopnet.com

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id LVS_DEVEL

}

vrrp_instance VI_1 {

state MASTER

interface eth0

virtual_router_id 51

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1paituan.com

}

virtual_ipaddress {

192.168.1.8

}

}

vrrp_instance VI_2 {

state BACKUP

interface eth0

virtual_router_id 52

priority 99

advert_int 1

authentication {

auth_type PASS

auth_pass 1paituan.com

}

virtual_ipaddress {

192.168.1.9

}

}

另一台Nginx机器的keepalived.conf配置文件如下:

! Configuration File for keepalived

global_defs {

notification_email {

yuhongchun027@163.com

}

notification_email_from keepalived@chtopnet.com

smtp_server 127.0.0.1

smtp_connect_timeout 30

router_id LVS_DEVEL

}

vrrp_instance VI_1 {

state BACKUP

interface eth0

virtual_router_id 51

priority 99

advert_int 1

authentication {

auth_type PASS

auth_pass 1paituan

}

virtual_ipaddress {

192.168.1.8

}

}

vrrp_instance VI_2 {

state MASTER

interface eth0

virtual_router_id 52

priority 100

advert_int 1

authentication {

auth_type PASS

auth_pass 1paituan

}

virtual_ipaddress {

192.168.1.9

}

}

注意:这两台Nginx应该是互为主备的关系,所以在写keepalived.conf配置文件时,一定要注意MASTER和BACKUP的关系,并且还要注意各自的优先级,不是太熟悉的朋友建议直接用以上的脚本来操作。如果此步遇到了问题,建议用TCPDump抓包分析排障,正常情况下它们都应该各自向对方发送VRRP包。

大家都知道Keepalived是实现不了程序级别的高可用的,所以我们要写Shell脚本来实现Nginx的高可用,脚本/root/nginx_pid.sh内容如下:

#!/bin/bash

while :

do

nginxpid=`ps -C nginx --no-header | wc -l`

if [ $nginxpid -eq 0 ];then

/usr/local/nginx/sbin/nginx

sleep 5

if [ $nginxpid -eq 0 ];then

/etc/init.d/keepalived stop

fi

fi

sleep 5

done

下面分别在两台主Nginx上执行如下命令:

nohup sh /root/nginxpid.sh &

正常启动两台主Nginx的Nginx和Keepalived程序后,这两台机器的正常IP显示应该如下。

IP为192.168.1.5的机器的ip addr命令显示结果为:

1: lo: mtu 16436 qdisc noqueue

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000

link/ether 00:0c:29:99:fb:32 brd ff:ff:ff:ff:ff:ff

inet 192.168.1.5/24 brd 192.168.1.255 scope global eth0

inet 192.168.1.8/32 scope global eth0

IP为192.168.1.6的机器的ip addr命令显示结果为:

1: lo: mtu 16436 qdisc noqueue

link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

inet 127.0.0.1/8 scope host lo

inet6 ::1/128 scope host

valid_lft forever preferred_lft forever

2: eth0: mtu 1500 qdisc pfifo_fast qlen 1000

link/ether 00:0c:29:7d:58:5e brd ff:ff:ff:ff:ff:ff

inet 192.168.1.6/24 brd 192.168.1.255 scope global eth0

inet 192.168.1.9/32 scope global eth0

inet6 fe80::20c:29ff:fe7d:585e/64 scope link

valid_lft forever preferred_lft forever

3: sit0: mtu 1480 qdisc noop

link/sit 0.0.0.0 brd 0.0.0.0

测试过程如下:

1)分别在这两台主Nginx上用killall杀掉Nginx进程,然后在客户端分别访问192.168.1.8和192.168.1.9这两个IP(模拟DNS轮询)看能否正常访问Web服务器。

2)尝试重启192.168.1.5的主Nginx负载均衡器,测试过程如上。

3)尝试重启192.168.1.6的主Nginx负载均衡器,测试过程如上。

4)尝试分别关闭192.168.1.5和192.168.1.6的机器,测试过程如上,以确定是否影响网站的正常访问。

目前投入生产要解决的问题为:

·日志收集系统要重新部署,现在访问日志是分布在两台Nginx负载均衡器上的。

·要考虑谷歌和百度域名收录的问题(注意看对网站的SEO有无影响)。

·要考虑DNS轮询的问题。

·证书的问题,两台Nginx负载均衡机器都需要部署GeoTrust证书。

·Nginx主主架构较之Nginx主备架构维护起来更为复杂,这点希望大家在工作中注意。

·实施此网站的架构时不要影响网站的业务系统,事实上很多业务系统在程序上都做了防作弊措施,所以在实施时考虑问题一定要全面。