NGINX之负载均衡及高可用

NGINX之负载均衡

1.准备环境

1.1系统环境

NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"

1.2准备五台虚拟主机:
lb01 192.168.56.32    lb02 192.168.56.33
web01 192.168.56.34 web02 192.168.56.35 web03 192.168.56.36

关闭防火墙

systemctl stop firewalld.service 
systemctl disable firewalld.service

1.3安装nginx

#!/bin/bash
yum install -y epel-release
yum install -y pcre pcre-devel openssl openssl-devel
mkdir -p /home/dilusense/tools
cd /home/dilusense/tools
yum install -y wget
wget http://nginx.org/download/nginx-1.10.2.tar.gz
tar xf nginx-1.10.2.tar.gz 
cd nginx-1.10.2/
useradd -s /sbin/nologin -M www
./configure --prefix=/usr/local/nginx-1.10.2 --user=www --group=www \
 --with-http_stub_status_module --with-http_ssl_module
make && make install
ln -s /usr/local/nginx-1.10.2 /usr/local/nginx
echo 'export PATH=$PATH:/usr/local/nginx/sbin/' >>/etc/profile
. /etc/profile
/usr/local/nginx/sbin/nginx

1.4web01 web02 wweb03nginx配置文件

[root@web01 ~]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
 worker_connections 1024;
}
http {
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 keepalive_timeout 65;
 
 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;

 server {
 listen 80;
 server_name bbs.openstarck.org;
 location / {
 root html/bbs;
 index index.html index.htm;
 }
 error_page 500 502 503 504 /50x.html;
 location = /50x.html {
 root html;
 }
 }
 server {
 listen 80;
 server_name blog.openstarck.org;
 location / {
 root html/blog;
 index index.html index.htm;
 }
 error_page 500 502 503 504 /50x.html;
}
}

1.5lb01 lb02 nginx 配置文件

worker_processes 1;
events {
 worker_connections 1024;
}
http {
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 keepalive_timeout 65;
 
 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;

 upstream server_pools {
 server 192.168.56.34 weight=2;
 server 192.168.56.35 weight=1;
 server 192.168.56.36 weight=1;
 }

 server {
 listen 80;
 server_name bbs.openstack.org;
 location / {
 proxy_pass http://server_pools;
 }
 }
}

检查语法并加载配置文件进行测试

[root@lb01 ~]# nginx -t
nginx: the configuration file /usr/local/nginx-1.10.2/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx-1.10.2/conf/nginx.conf test is successful
[root@lb01 ~]# nginx -s reload
[root@lb01 conf]# for i in {1..30};do curl 192.168.56.32;sleep 1;done

2.Nginx负载均衡核心组件

2.1Nginx upstream模块

Nginx的负载均衡功能依赖于ngx_http_upstream_module模块,所支持的代理方式包括proxy_pass\fastcgi_pass\memcached_pass等
ngx_http_upstream_module模块允许Nginx定义一组或多组节点服务器组,使用时可以通过proxy_pass代理方式把网站的请求发送到事先定义好的对应Upstream组的名字上,具体写法为"proxy_pass http://www_server_pools"其中www_server_pools就是一个Upstream节点服务器组名字。

ngx_http_upstream_module模块官方地址:

http://nginx.org/en/docs/http/ngx_upstream_module.html

2.2upstream模块语法

http {
 upstream server_pools {
 server 192.168.56.34 weight=2 max_fails=1 fail_timeout=10s;#过10s再尝试一次
 server 192.168.56.35 weight=1;
 server 192.168.56.36 weight=1 backup;
 server 192.168.56.37 weight=1 down;
 }

 server {
 listen 80;
 server_name bbs.openstck.org;
 location / {
 proxy_pass http://server_pools;
 proxy_set_header Host $host;      #>==保持主机名host不变
 proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }
 }

 server {
 listen 80;
 server_name blog.openstck.org;
 location / {
 proxy_pass http://server_pools;
 proxy_set_header Host $host; #>==保持主机名host不变
 proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }
 }
}
#==>注释说明:
其中backup热备配置(RS节点的高可用)当前面激活的RS都失败后会自动启动热备RS,这标志着这个服务器作为备份服务器,若主服务器全
部宕机了,就会向它转发请求,注意,当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup

其中down这个参数可配合ip_hash使用 ,当代码更新时可以使用down 用户无法请求 可以进行更新

3.upstream实现不同web服务器功能

一个虚拟主机多个条件:

http {
upstream upload_servers {
  server 192.168.56.35:80;
}
upstream static_servers {
 server 192.168.56.36:80;
}
upstream default_servers {
 server 192.168.56.37:80;
}
server{
listen 80;
server_name bbs.openstack.org; 
location /upload {
 proxy_pass http://upload_servers;
 proxy_set_header Host $host; #>==保持主机名host不变
 proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }

 location /static {
 proxy_pass http://static_servers;
 proxy_set_header Host $host; #>==保持主机名host不变
 proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }

 location / {
 proxy_pass http://default_servers;
 proxy_set_header Host $host; #>==保持主机名host不变
 proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }
}
}

负载均衡lb01中nginx.conf配置文件内容:

worker_processes 1;
events {
 worker_connections 1024;
}
http {
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 keepalive_timeout 65;
 
 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;

upstream upload_servers {
 server 192.168.56.35:80;
}
upstream static_servers {
 server 192.168.56.36:80;
}
upstream default_servers {
 server 192.168.56.37:80;
}

 server {
  listen 80;
  server_name bbs.openstack.org; 
  location /upload {
   proxy_pass http://upload_servers;
   proxy_set_header Host $host; #>==保持主机名host不变
   proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }

 location /static {
   proxy_pass http://static_servers;
   proxy_set_header Host $host; #>==保持主机名host不变
   proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }

 location / {
   proxy_pass http://default_servers;
   proxy_set_header Host $host; #>==保持主机名host不变
   proxy_set_header X-Forwarded-For $remote_addr; #==>记录用户真实IP
 }
 }
}

4.不同的浏览器访问不同的客户端

4.1根据客户端的设备(user_agent)转发实践

企业中,为了让不同的客户端设备用户访问有更好的体验,需要在后端架设不同服务器来满足不同的客户端访问,例如:移动客户端访问网站,就需要部署单独的移动服务器及程序,体验才能更好,而且移动端还分苹果、安卓、IPAD等,在传统的情况下,可以用如下方法解决:

1)常规4层负载均衡解决方案架构

用户记录两个域名

根据http_user_agent内容选择不同的服务器

在常规4层负载均衡架构下,可以使用不同的域名来实现这个需求,例如,人为分配好让移动客户端访问m.xionghaizei.com,PC客户端访问www.xionghaizei.com,通过不同的域名来引导用户到指定的后端服务器;

2)根据客户端设备(user_agent)转发请求实践

用户只需记录一个域名

可以判断user_agent来进行转发

为了方便测试,就不用不同的域名(网站)此次使用static_server、upload_server作为本次实验的后端的服务器池。

下面根据电脑客户端浏览器的不同设置对应的匹配规则

location / {
   if ($http_user_agent ~* "MSIE")
  {
    proxy_pass http://static_servers; #==>如果请求的是IE浏览器(MSIE)则让请求由static_server池处理
  }
   if ($http_user_agent ~* "Chrome")
  {
    proxy_pass http://upload_servers; #==>如果请求的是谷歌浏览器(Chrome)则让请求由upload_server池处理
  }
    proxy_pas http://default_servers; #==>其他客户端,由default_server池处理
}

完整配置文件

worker_processes 1;
events {
 worker_connections 1024;
}
http {
 include mime.types;
 default_type application/octet-stream;
 sendfile on;
 keepalive_timeout 65;
 
 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;

upstream upload_servers {
 server 192.168.56.35:80;
}
upstream static_servers {
 server 192.168.56.36:80;
}
upstream default_servers {
 server 192.168.56.37:80;
}

 server {
  listen 80;
  server_name bbs.openstack.org; 

location / {
  if ($http_user_agent ~* "MSIE")
  {
   proxy_pass http://static_servers; #==>如果请求的是IE浏览器(MSIE)则让请求由static_server池处理
  }
  if ($http_user_agent ~* "Chrome")
  {
   proxy_pass http://upload_servers; #==>如果请求的是谷歌浏览器(Chrome)则让请求由upload_server池处理
  }
   proxy_pass http://default_servers; #==>其他客户端,由default_server池处理
  }
 }
}

curl命令访问

curl -A chrome bbs.openstack.org/upload/index.html

5.高可用keepalived详解

安装并启动

下载阿里源
https://opsx.alibaba.com/mirror
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache  ##>==生成缓存
安装keepalived并启动
yum install -y keepalived
systemctl start keepalived.service

注意:需要关闭防火墙及selinux

配置文件

[root@lb01 keepalived]# cat -n /etc/keepalived/keepalived.conf
 1 global_defs {
 2 router_id LVS_01
 3 }
 4 
 5 vrrp_instance VI_1 {
 6 state MASTER
 7 interface eth0
 8 virtual_router_id 51
 9 priority 150
 10 advert_int 1
 11 authentication {
 12 auth_type PASS
 13 auth_pass 1111
 14 }
 15 virtual_ipaddress {
 16 192.168.0.3/24 dev eth0 label eth0:1
 17 }
 18 }

参数说明:
  第5行表示定义一个vrrp_instance实例,名字是VI_1,每个vrrp_instance实例可以认为是keepalived服务的一个实例或者作为一个
业务服务,在keepalived服务配置中,这样的vrrp_instance实例可以有多个。注意,存在于主节点中的vrrp_instance实例在备节点中
也要存在,这样才能实现故障切换管理
  第6行state MASTER表示当前实例VI_1的角色状态,当前角色为MASTER,这个状态只能有MASTERBACKUP两种状态,并且需要大写这
些字符。其中MASTER为正式工作的状态,BACKUP为备用的状态。当MASTER所在的服务器故障或失效时,BACKUP所在的服务器会接管故障的
MASTER继续提供服务
  第7行interface为网络通信接口,对外提供服务的网络接口,如eth0、eth1、
  第8行virtual_router_id为虚拟路由ID标识,这个标识最好是一个数字,并且要在一个keepalive.conf配置文件中是唯一的,但是MASTER
和BACKUP配置文件中相同实例的virtual_route_id又必须一致,否则将出现裂脑问题
  第9行为优先级 越多表示优先级越高 MASTER一般比BACKUP大50
  第10行advert_int为同步通知间隔,MASTER与BACKUP之间通信检查的时间间隔,单位为秒,默认为1.

用户访问VIP的方法

①域名解析到VIP

②listen 监听vip

nginx负载均衡监听本地不存在的IP地址,解决办法:

echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf

sysctl -p

配置文件
ll /proc/sys/net/ipv4/ip_nonlocal_bind 
-rw-r--r-- 1 root root 0 Apr 20 05:57 /proc/sys/net/ipv4/ip_nonlocal_bind

keepalived.conf配置文件使用脚本监控nginx服务状态

[root@lb01 ~]# vim /etc/keepalived/keepalived.conf

global_defs {
 router_id LVS_01
}

vrrp_scripts chk_nginx_proxy {
 script "/scriptspath/chk_nginx_proxy.sh" #<=脚本检查nginx服务宕了,停止keepalived服务,脚本需要有执行权限
 interval 2 #<=间隔2秒
 weight
}

vrrp_instance VI_1 {
 state MASTER
 interface eth0
 virtual_router_id 51
 priority 150
 advert_int 1
 authentication {
 auth_type PASS
 auth_pass 1111
 }
 virtual_ipaddress {
 192.168.0.3/24 dev eth0 label eth0:1
 }
track_script {
 chk_nginx_proxy
 }
}

lb01多实例配置文件

[root@lb01 keepalived]# cat -n keepalived.conf
 1 global_defs {
 2 router_id LVS_01
   vrrp_mcast_group4 224.0.0.19 #<==指定多播地址的配置   ##多组keepalived服务器对通信冲突问题解决方案
   (virtual route id多播224.0.0.18 )
 3 }
 4 
 5 
 6 vrrp_scripts chk_nginx_proxy {
 7 script "/scriptspath/chk_nginx_proxy.sh" #<=脚本检查nginx服务宕了,停止keepalived服务
 8 interval 2 #<=间隔2秒
 9 weight 2
 10 }
 11 
 12 vrrp_instance VI_1 {
 13 state MASTER
 14 interface eth0
 15 virtual_router_id 51
 16 priority 150
 17 advert_int 1
 18 authentication {
 19 auth_type PASS
 20 auth_pass 1111
 21 }
 22 virtual_ipaddress {
 23 192.168.0.3/24 dev eth0 label eth0:1
 24 }
 25 track_script {
 26 chk_nginx_proxy
 27 }
 28 
 29 }
 30 
 31 vrrp_instance VI_2 {
 32 state BACKUP
 33 interface eth0
 34 virtual_router_id 52
 35 priority 100
 36 advert_int 1
 37 authentication {
 38 auth_type PASS
 39 auth_pass 1111
 40 }
 41 virtual_ipaddress {
 42 192.168.0.4/24 dev eth0 label eth0:2
 43 }
 44 track_script {
 45 chk_nginx_proxy
 46 }
 47 
 48 }

 

 

 

 

 

0
如无特殊说明,文章均为本站原创,转载请注明出处

该文章由 发布

这货来去如风,什么鬼都没留下!!!
发表我的评论

Hi,请填写昵称和邮箱!

取消评论
代码 贴图 加粗 链接 删除线 签到