Nginx负载均衡及集群实现

参考文档:
https://www.cnblogs.com/xiugeng/p/10155283.html#_label0
https://zhuanlan.zhihu.com/p/108577218

1 环境准备

主机名ip角色描述
hadoop101192.168.88.101主Nginx用于接收客户端请求
hadoop102192.168.88.102从Nginx当主Nginx挂掉,会接替主Nginx处理客户端请求
hadoop103192.168.88.103web服务器1使用nginx作为web服务器代理静态页面,也可以使用其他web服务器(如tomcat)
hadoop104192.168.88.104web服务器2使用nginx作为web服务器代理静态页面,也可以使用其他web服务器(如tomcat)

2 Nginx负载均衡

hadoop101和hadoop102操作相同

  1. 安装依赖
#安装编译工具及库文件,gcc-c++为编译环境,zlib为了gzip压缩,openssl为了支持ssl,devel主要是和开发相关的东西
[root@hadoop101 software]# yum -y install make zlib zlib-devel gcc-c++ libtool  openssl openssl-devel

#PCRE 作用是让 Nginx 支持 Rewrite 功能
[root@hadoop101 software]# wget https://jaist.dl.sourceforge.net/project/pcre/pcre/8.42/pcre-8.42.tar.gz
[root@hadoop101 software]# tar -zxvf pcre-8.42.tar.gz
[root@hadoop101 software]# cd pcre-8.42 
[root@hadoop101 pcre-8.42]# ./configure
[root@hadoop101 pcre-8.42]# make && make install
[root@hadoop101 pcre-8.42]# pcre-config --version
  1. 安装nginx
[root@hadoop101  software]# wget https://nginx.org/download/nginx-1.18.0.tar.gz
[root@hadoop101  software]# tar -xvf nginx-1.18.0.tar.gz
[root@hadoop101 software]# cd nginx-1.18.0

#筛选出以及可以安装的包,这个包括自定义安装的,--with 前缀开头的为可选安装包,其余为默认安装包,安装时使用 --with-模块名称安装
[root@hadoop101 nginx-1.18.0]# cat auto/options | grep YES  

#配置,prefix指定安装路径,http_stub_status_module和http_ssl_module分别是http和https组件,with-stream为stream组件,with-pcre指pcre路径
[root@hadoop101 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/opt/software/pcre-8.42  --with-stream=dynamic

#编译(生成objs目录)并安装(--prefix目录)
[root@hadoop101 nginx-1.18.0]# make && make install
  1. 添加模块(如需要)
# 查看自己添加的参数、编译时附带的可选模块或三方模块
[root@hadoop101 nginx-1.18.0]# /usr/local/nginx/sbin/nginx -V
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/opt/software/pcre-8.42  --with-stream=dynamic

# 重新配置
[root@hadoop101 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/opt/software/pcre-8.42  --with-stream=dynamic --with-http_gzip_static_module --with-http_auth_request_module --with-http_realip_module

# 重新编译
[root@hadoop101 nginx-1.18.0]# make
# 将生成的nginx执行文件copy到安装目录
[root@hadoop101 nginx-1.18.0]# cp -r /opt/module/nginx-1.18.0/objs/nginx /usr/local/nginx/sbin/
  1. 负载均衡配置
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream web {
        ip_hash;
        server 192.168.88.103 max_fails=1 fail_timeout=10;
        server 192.168.88.104 max_fails=1 fail_timeout=10;
        # server 192.168.88.103 weight=1 max_fails=1 fail_timeout=10;
        # server 192.168.88.104 weight=2 max_fails=1 fail_timeout=10 backup;
    }
    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://web;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

负载均衡流程:
1)虚拟主机接受用户请求
2)虚拟主机去找反向代理(问反向代理去哪拿数据)
3)反向代理让去找upstream
4)upstream告诉一个数据服务器IP
5)Nginx去找数据服务器,并发起用户的请求
6)数据服务器接受请求并处理请求
7)数据服务器响应请求给Nginx
8)Nginx响应请求给用户

2.1 负载均衡策略

nginx的upstream 目前支持4种方式的分配:

  1. 轮询(默认):每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。weight(权重)指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。
  2. ip_hash:每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务,好处是可以解决session的问题。因此第一种只能处理静态页面,而这种方式可以处理动态网站。
  3. fair(第三方):按后端服务器的响应时间来分配请求,响应时间短的优先分配。
  4. url_hash(第三方):按访问url的hash结果来分配请求,使每个url定向到同一个后端服务 ,后端服务器为缓存时比较有效。

负载均衡服务器参数

参数说明
down表示当前的server暂时不参与负载
weight默认为1,weight越大,负载的权重就越大(用于轮询策略,ip_hash不可用)
max_fails允许请求失败的次数默认为1,当超过最大次数时,返回proxy_next_upstream模块定义的错误
fail_timeout失败超时时间,在连接Server时,如果在超时时间之内超过max_fails指定的失败次数,会认为在fail_timeout时间内Server不可用,默认为10s
backup其他所有的非backup机器down或者忙的时候,才会请求backup机器。所以这台机器压力会最轻

2.2 示例

http://192.168.88.111:9030/bme-sso-server/swagger-ui.html ——》 http://192.168.88.103:9030/bme-sso-server/swagger-ui.html

worker_processes  1;
events {
    worker_connections  1024;
}
#http负载均衡
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    upstream web {
        ip_hash;
        server 192.168.88.103 max_fails=1 fail_timeout=10;
        server 192.168.88.104 max_fails=1 fail_timeout=10 down;
        # server 192.168.88.103 weight=1 max_fails=1 fail_timeout=10;
        # server 192.168.88.104 weight=2 max_fails=1 fail_timeout=10 backup;
    }
    upstream bme-sso-server {
        ip_hash;
        server 192.168.88.103:9030 max_fails=1 fail_timeout=10;
        server 192.168.88.104:9030 max_fails=1 fail_timeout=10;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://web;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
    server {
        listen       9030;
        server_name  localhost;
		location / {
            proxy_pass http://bme-sso-server;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

#tcp负载均衡
stream{
	log_format proxy '[$time_local] $remote_addr->$upstream_addr  '
                 '$protocol $status $bytes_sent $bytes_received '
                 '$session_time '
                 '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
	access_log logs/tcp-access.log proxy ;
	open_log_file_cache off;
	
	upstream dns {
       server 192.168.88.103:10086;
       server 192.168.88.104:10086;
    }
	server{
		listen 8597;
		proxy_pass dns;
	}
	
}

3 Nginx集群(Nginx + Keepalived)

  1. 在hadoop101和hadoop102安装Keepalived
[root@hadoop101 ~]# yum install keepalived -y
#启动
[root@hadoop101 ~]# systemctl start keepalived
#查看运行状态
[root@hadoop101 ~]# systemctl status keepalived
#停止
[root@hadoop101 ~]# systemctl stop keepalived
  1. 修改hadoop101的keepalived配置文件
[root@hadoop101 ~]# vim /etc/keepalived/keepalived.conf

#检测脚本
vrrp_script chk_http_port
{		#注意括号换行,否则脚本可能会不执行
    script "/usr/local/src/check_ngx.sh" #心跳执行的脚本,检测nginx是否启动
    interval 5                          #(检测脚本执行的间隔,单位是秒,要比脚本执行时间大,否则会报错)
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state MASTER            # 指定keepalived的角色,MASTER为主,BACKUP为备
    interface ens33         # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig/ip addr查看你具体的网卡
    virtual_router_id 51    # 虚拟路由编号,主从要一直
    priority 100            # 优先级,数值越大,获取处理请求的优先级越高
    advert_int 1            # 检查间隔,默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port            #(调用检测脚本)
    }
    virtual_ipaddress {
        192.168.88.111            # 定义虚拟ip(VIP),可多设,每行一个
    }
}

  1. 修改hadoop102的keepalived配置文件
[root@hadoop102 ~]# vim /etc/keepalived/keepalived.conf
#检测脚本
vrrp_script chk_http_port {
    script "/usr/local/src/check_ngx.sh" #心跳执行的脚本,检测nginx是否启动
    interval 5                          #(检测脚本执行的间隔,单位是秒,要比脚本执行时间大,否则会报错)
    weight 2                            #权重
}
#vrrp 实例定义部分
vrrp_instance VI_1 {
    state BACKUP                        # 指定keepalived的角色,MASTER为主,BACKUP为备
    interface ens33                      # 当前进行vrrp通讯的网络接口卡(当前centos的网卡) 用ifconfig/ip addr查看你具体的网卡
    virtual_router_id 51                # 虚拟路由编号,主从要一直
    priority 99                         # 优先级,数值越大,获取处理请求的优先级越高
    advert_int 1                        # 检查间隔,默认为1s(vrrp组播周期秒数)
    #授权访问
    authentication {
        auth_type PASS #设置验证类型和密码,MASTER和BACKUP必须使用相同的密码才能正常通信
        auth_pass 1111
    }
    track_script {
        chk_http_port                   #(调用检测脚本)
    }
    virtual_ipaddress {
        192.168.88.111                   # 定义虚拟ip(VIP),可多设,每行一个
    }
}
  1. 编写check_ngx.sh脚本
[root@hadoop101 ~]# vim /usr/local/src/check_ngx.sh
#!/bin/bash
COUNT1=`ss -anpt | grep nginx | wc -l `
if [ $COUNT1 -eq 0 ] ; then
    /usr/local/nginx/sbin/nginx
    sleep 2
    COUNT2=`ss -anpt | grep nginx | wc -l`
    if [ $COUNT2 -eq 0 ] ; then
        systemctl stop keepalived
        echo -e "keeplived is stoped"
        exit 1
    else
        exit 0
    fi
fi
[root@hadoop101 ~]# scp -r /usr/local/src/check_ngx.sh root@192.168.88.102:/usr/local/src/
  1. 检查seLinux(重要,开启可能会导致check_ngx脚本中命令无法执行成功)
# 查看seLinux状态,SELinux status参数为enabled即为开启状态
[root@hadoop101 ~]# /usr/sbin/sestatus -v
# 也可以用这个命令检查
[root@hadoop101 ~]# getenforce
# 临时关闭(不用重启),0:permissive 	1:enforcing
[root@hadoop101 ~]# setenforce 0

# 永久关闭(需要重启)
[root@hadoop101 ~]# vim /etc/selinux/config
SELINUX=disabled
  1. 启动keepalived,注意关闭防火墙
[root@hadoop101 ~]# systemctl start keepalived
[root@hadoop102 ~]# systemctl start keepalived
  1. 测试
#关闭Master,通过ip addr命令查看二个服务器的ip地址变化
[root@hadoop101 ~]# systemctl stop keepalived

#hadoop101将重新获取vip地址
[root@hadoop101 ~]# systemctl start keepalived

4 问题纪要

4.1 GeoIP等库缺失

查找GeoIp安装包并安装

[centos@localhost nginx-1.16.1]$ yum search GeoIP
已加载插件:fastestmirror, langpacks
Repository base is listed more than once in the configuration
Repository updates is listed more than once in the configuration
Repository extras is listed more than once in the configuration
Repository centosplus is listed more than once in the configuration
Repository contrib is listed more than once in the configuration
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
 * webtatic: us-east.repo.webtatic.com
=========================================== N/S matched: GeoIP ============================================
GeoIP-data.noarch : Static snapshot of GeoIP databases
GeoIP-devel.i686 : Development headers and libraries for GeoIP
GeoIP-devel.x86_64 : Development headers and libraries for GeoIP
geoipupdate.x86_64 : Update GeoIP2 and GeoIP Legacy binary databases from MaxMind
geoipupdate-cron.noarch : Cron job to do weekly updates of GeoIP databases
GeoIP.i686 : Library for country/city/organization to IP address or hostname mapping
GeoIP.x86_64 : Library for country/city/organization to IP address or hostname mapping
nginx1w-module-http-geoip.x86_64 : A module to provide variables with values depending on the client IP
                                 : address
php55w-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places
php56w-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places
php70w-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places
php71w-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places
php72w-pecl-geoip.x86_64 : Extension to map IP addresses to geographic places

  名称和简介匹配 only,使用“search all”试试。
  
[centos@localhost nginx-1.16.1]$ # 安装 GeoIP-devel.x86_64 库
[centos@localhost nginx-1.16.1]$ sudo yum install -y GeoIP-devel.x86_64

只需要重新编译 nginx 即可。nginx 还可能报缺失其他库的错误。比如缺失pcre , zlib , openssl库等,这些缺失库的问题处理都大同小异。 除了去官方下载源码进行编译之外,也可以通过依赖包软件管理器进行对应的库安装。 我们这里采用的办法就是第二种,更简便。这样就可以解决这种问题。

4.2 nginx: [emerg] unknown directive “stream” in /data1/nginx/conf/nginx.conf:16

在nginx.conf的第一行插入:

load_module /usr/lib/nginx/modules/ngx_stream_module.so;

加载modules目录下编译过的ngx_stream_module.so,有些版本不会自动加载

4.3 使用systemctl的方式启动nginx服务

在centos7上,源码安装之后的nginx无法使用systemctl管理,需要写配置文件。
systemctl启动的脚本目录有二个:

  • 系统的启动脚本目录:/usr/lib/systemd/system
  • 自定义启动脚本目录:/etc/systemd/system/

可以安装httpd服务,安装后会生成httpd的启动脚本 /usr/lib/systemd/system/httpd.service,可以通过参考该脚本编写nginx的启动脚本。

[centos@localhost nginx-1.16.1]$ vim /etc/systemd/system/nginx.service 
[Unit]
Description=nginx - high performance web server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/data1/nginx/logs/nginx.pid
ExecStart=/data1/nginx/sbin/nginx -c /data1/nginx/conf/nginx.conf
ExecReload=/data1/nginx/sbin/nginx -s reload
ExecStop=/data1/nginx/sbin/nginx -s stop
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.

[Install]
WantedBy=multi-user.target

文件说明:

[Unit]:服务的说明
Description:描述服务
After:依赖,当依赖的服务启动之后再启动自定义的服务

[Service]服务运行参数的设置
Type=forking是后台运行的形式
ExecStart为服务的具体运行命令
ExecReload为重启命令
ExecStop为停止命令
PrivateTmp=True表示给服务分配独立的临时空间
注意:启动、重启、停止命令全部要求使用绝对路径
PIDFile : pid文件路径
ExecStartPre :启动前要做什么

[Install]服务安装的相关设置,可设置为多用户

Type

  • Type=simple(默认值):systemd认为该服务将立即启动。服务进程不会fork。如果该服务要启动其他服务,不要使用此类型启动,除非该服务是socket激活型。
  • Type=forking:systemd认为当该服务进程fork,且父进程退出后服务启动成功。对于常规的守护进程(daemon),除非你确定此启动方式无法满足需求,使用此类型启动即可。使用此启动类型应同时指定 PIDFile=,以便systemd能够跟踪服务的主进程。
  • Type=oneshot:这一选项适用于只执行一项任务、随后立即退出的服务。可能需要同时设置 RemainAfterExit=yes使得systemd在服务进程退出之后仍然认为服务处于激活状态
  • Type=notify:与 Type=simple相同,但约定服务会在就绪后向systemd发送一个信号。这一通知的实现由 libsystemd-daemon.so提供。
  • Type=dbus:若以此方式启动,当指定的 BusName 出现在DBus系统总线上时,systemd认为服务就绪。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值