安装 stream包

yum -y install nginx-mod-stream.x86_64

配置虚拟主机

stream属于最顶层的配置,Context: main,不能写在conf.d目录下,因为conf.d目录是属于http协议的。
可以在nginx.conf里面,


修改如下:

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
#增加
include /etc/nginx/stream.d/*conf;
events {
    worker_connections 1024;
}

http {
    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  /var/log/nginx/access.log  main;

创建/etc/nginx/stream.d目录

mkdir -p /etc/nginx/stream.d
在此目录下编辑mysql.conf文件如下:

stream {
# 这三台机器一定 slave, SET GLOBAL read_only = 1;
    upstream readonly_server {
        server 192.168.10.174:3306;
        server 192.168.10.175:3306;
        server 192.168.10.176:3306;
    }
# 这二台master机器 
    upstream write_server {
        server 192.168.10.172:3306;
        server 192.168.10.171:3306;

    }
 server {
        listen 33060;
        #proxy_connect_timeout 10s;
        #代理时间默认10分钟,在这个时间范围内,没有数据传递,就会关闭连接,如果这个时间设置短,就会在该主机上产生大量的FIN_WAIT2和TIME_WAIT状态的tcp连接,连接的复用率会变低
        #proxy_timeout 10m;
        # 这里的proxy是stream-proxy模块,不是http-proxy
        proxy_pass readonly_server;
    }
    server {
        listen 33061;
        #proxy_connect_timeout 10s;
        #代理时间默认10分钟,在这个时间范围内,没有数据传递,就会关闭连接,如果这个时间设置短,就会在该主机上产生大量的FIN_WAIT2和TIME_WAIT状态的tcp连接,连接的复用率会变低
        #proxy_timeout 10m;
        # 这里的proxy是stream-proxy模块,不是http-proxy
        proxy_pass write_server;
    }
}

测试

mysql -uroot -p123456 -P 33060

nginx负载均衡策略

1、轮询(默认)

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
参数:

fail_timeout

与max_fails结合使用.

max_fails

设置在fail_timeout参数设置的时间内最大失败次数,如果在这个时间内,所有针对该服务器的请求都失败了,那么认为该服务器会被认为是停机了

fail_time

服务器会被认为停机的时间长度,默认为10s。

backup

标记该服务器为备用服务器。当主服务器停止时,请求会被发送到它这里。

down

标记服务器永久停机了。

在轮询中,如果服务器down掉了,会自动剔除该服务器。
缺省配置就是轮询策略。
此策略适合服务器配置相当,无状态且短平快的服务使用。

upstream backserver {
server 172.16.1.7;
server 172.16.1.8 backup;
server 172.16.1.9 max_fails=3 fail_timeout=20s;
}
 server {
         listen 80;
         location / {
         proxy_pass http://backserver ;
        }
     }

2、指定权重

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。

upstream backserver {
server 172.16.1.7 weight=10;
server 172.16.1.8 weight=6;
server 172.16.1.9;
}
server {
         listen 80;
         location / {
         proxy_pass http://backserver ;
        }
     }

3、IP绑定 ip_hash

每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

upstream backserver {
ip_hash;
server 172.16.1.7:88;
server 172.16.1.8:80;
server 172.16.1.9;
}
server {
         listen 80;
         location / {
         proxy_pass http://backserver ;
        }
     }

4、fair(第三方)

按后端服务器的响应时间来分配请求,响应时间短的优先分配。

upstream backserver {
server 172.16.1.7;
server 172.16.1.8;
server 172.16.1.9;
fair;
}
server {
         listen 80;
         location / {
         proxy_pass http://backserver ;
        }
     }

5、url_hash(第三方)

按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。

upstream backserver {
hash $request_uri consistent;
server 172.16.1.7;
server 172.16.1.8;
server 172.16.1.9;

}
server {
         listen 80;
         location / {
         proxy_pass http://backserver ;
        }
     }

最小连接数

least connection

session共享问题

  在最简单的一主一备、负载均衡的集群下,比如两台tomcat服务器和一台nginx负载均衡服务器。当用户访问时,nginx分配给tomcat1服务器处理登陆业务,用户登陆成功,在tomcat1记录了其登陆信息,当页面刷新时,nginx将用户请求分配给tomcat2服务器,在tomcat2服务器上没有用户登陆session,这样就需要用户再次登陆,如果足够巧合,刚好再次登陆的请求转到tomcat1服务器,显示用户登陆,再次刷新刚好又分配给tomcat2服务器,又没有登陆,甚至形成既登陆又没有登陆的矛盾局面。这就造成了不好的体验。
  一般的解决办法是,tomcat服务器之间开启session共享广播,当tomcat1服务器记录了session数据后,就广播给其他tomcat服务器。但是,tomcat的session共享的节点数是有上限的。当集群中配置的tomcat节点机到达一定数量后(一般是5个),节点内部通信的流量可能被session广播占满,导致无法顺畅的处理其他业务,特别是难以适应高并发的场景。
  避免session广播形成节点上限的解决办法是,配置单点登录的session服务器,适应redis缓存模拟session保存登陆信息。
解决nginx负载均衡的session共享问题

作者:严锋  创建时间:2023-09-25 14:47
最后编辑:严锋  更新时间:2025-05-09 15:48