通过我们会用Nginx的upstream做基于http/https端口的7层负载均衡,由于Nginx老版本不支持tcp协议,所以基于tcp/udp端口的四层负载均衡一般用LVS或Haproxy来做。至于4层负载均衡和7层负载均衡的区别,可以参考:http://www.cnblogs.com/kevingrace/p/6137881.html。然而Nginx从1.9.0版本开始,新增加了一个stream模块,用来实现四层协议的转发、代理或者负载均衡等,鉴于Nginx在7层负载均衡和web service上的成功,和Nginx良好的框架,stream模块前景一片光明。
Nginx的stream模块默认不会自带安装,需要编译安装的时候手动添加上这个模块。废话不多说了,下面介绍下一个自己使用stream做四层负载均衡的案例:
在此之前已经使用Ningx+Keepalived(主从模式)做了7层负载均衡的LB环境,之前编译的时候,没有加上这个stream模块,所以需要后续手动添加该模块。 由于Nginx的LB已经有业务跑在上面,可以选择平滑添加stream模块,并不会对线上业务造成多大影响。步骤如下: 1)现在LB的slave从机上进行平滑添加,然后再将vip切换到从机上,随即在对master主机进行平滑添加该模块。 2)平滑添加即是重新configure编译的时候加上--with-stream,接着make。 3)千万注意,make之后,不要make install,否则会覆盖掉之前的配置!!! -------------------------------------------------------------------------------------------------- 由于本人的LB环境升级了openssl版本,再添加--with-stream重新编译的时候报了错误,具体可参考: http://www.cnblogs.com/kevingrace/p/8058535.html -------------------------------------------------------------------------------------------------- 检查下,发现nginx没有安装stream模块 [root@external-lb01 ~]# /data/nginx/sbin/nginx -V nginx version: nginx/1.12.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) built with OpenSSL 1.1.0g 2 Nov 2017 TLS SNI support enabled configure arguments: --prefix=/data/nginx --user=www --group=www --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre 操作之前,一定要备份一下之前的nginx安装目录,防止操作失败进行回滚! [root@external-lb01 ~]# cp -r /data/nginx /mnt/nginx.bak 之前的编译命令是: [root@external-lb01 vhosts]# cd /data/software/nginx-1.12.2 [root@external-lb01 nginx-1.12.2]# ./configure --prefix=/data/nginx --user=www --group=www --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre 现在需要手动添加stream,编译命令如下: [root@external-lb01 vhosts]# cd /data/software/nginx-1.12.2 [root@external-lb01 nginx-1.12.2]# ./configure --prefix=/data/nginx --user=www --group=www --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream [root@external-lb01 nginx-1.12.2]# make [root@external-lb01 nginx-1.12.2]# cp -f /data/software/nginx-1.12.2/objs/nginx /data/nginx/sbin/nginx [root@external-lb01 nginx-1.12.2]# pkill -9 nginx [root@external-lb01 nginx-1.12.2]# /data/nginx/sbin/nginx 检查下,发现nginx已经安装了stream模块了 [root@external-lb01 nginx-1.12.2]# /data/nginx/sbin/nginx -V nginx version: nginx/1.12.2 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-18) (GCC) built with OpenSSL 1.1.0g 2 Nov 2017 TLS SNI support enabled configure arguments: --prefix=/data/nginx --user=www --group=www --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-openssl=/usr/local/ssl ====================================================================================================================== stream的4层负载均衡和upstream的7层负载均衡可以共同配置在nginx中,stream模块用法和http模块差不多,关键的是语法几乎一致。 具体如下: [root@external-lb01 ~]# cat /data/nginx/conf/nginx.conf user www; worker_processes 8; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 65535; } stream { upstream kk5 { server 10.0.58.22:5100; server 10.0.58.23:5100; } upstream kk5http { server 10.0.58.22:8000; server 10.0.58.23:8000; } upstream kk5https { server 10.0.58.22:8443; server 10.0.58.23:8443; } server { listen 5100; proxy_connect_timeout 1s; proxy_pass kk5; } server { listen 8000; proxy_connect_timeout 1s; proxy_pass kk5http; } server { listen 8443; proxy_connect_timeout 1s; proxy_pass kk5https; } } http { include mime.types; default_type application/octet-stream; charset utf-8; ###### ## set access log format ###### log_format main '$remote_addr $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '$http_user_agent $http_x_forwarded_for $request_time $upstream_response_time $upstream_addr $upstream_status'; ####### ## http setting ####### sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; proxy_cache_path /var/www/cache levels=1:2 keys_zone=mycache:20m max_size=2048m inactive=60m; proxy_temp_path /var/www/cache/tmp; fastcgi_connect_timeout 3000; fastcgi_send_timeout 3000; fastcgi_read_timeout 3000; fastcgi_buffer_size 256k; fastcgi_buffers 8 256k; fastcgi_busy_buffers_size 256k; fastcgi_temp_file_write_size 256k; fastcgi_intercept_errors on; # client_header_timeout 600s; client_body_timeout 600s; # client_max_body_size 50m; client_max_body_size 100m; client_body_buffer_size 256k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.1; gzip_comp_level 9; gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php; gzip_vary on; ## includes vhosts include vhosts/*.conf; } [root@external-lb01 ~]# cd /data/nginx/conf/vhosts/ [root@external-lb01 vhosts]# ls -rw-r-xr-- 1 root root 889 12月 26 15:18 bpm.kevin.com.conf -rw-r-xr-- 1 root root 724 12月 26 14:38 mobi.kevin.com.conf [root@external-lb01 vhosts]# cat bpm.kevin.com.conf upstream os-8080 { ip_hash; server 10.0.58.20:8080 max_fails=3 fail_timeout=15s; server 10.0.58.21:8080 max_fails=3 fail_timeout=15s; } server { listen 80; server_name bpm.kevin.com; access_log /data/nginx/logs/bpm.kevin.com-access.log main; error_log /data/nginx/logs/bpm.kevin.com-error.log; location / { proxy_pass http://os-8080; proxy_set_header Host $host; proxy_redirect http://os-8080/ http://bpm.kevin.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_502 http_503 http_504; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } [root@external-lb01 vhosts]# cat mobi.kevin.com.conf upstream mobi_cluster{ server 10.0.54.20:8080; } server { listen 80; server_name mobi.kevin.com; access_log /data/nginx/logs/mobi.kevin.com-access.log main; error_log /data/nginx/logs/mobi.kevin.com-error.log; location / { proxy_pass http://mobi_cluster; proxy_set_header Host $host; proxy_redirect http://mobi_cluster/ http://mobi.kevin.com/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } 关闭防火墙,否则要依次打开如上配置中的端口! [root@external-lb01 vhosts]# /data/nginx/sbin/nginx -s reload 重启nginx后,发现http端口80、8080、8000、8443都起来了(lsof命令可以查看到),而tcp/udp端口5100没有起来,这是正常的。