nginx编译安装Nginx,添加第三方模块(nginx-sticky-module) sticky模块与Ip_hash都是与负载均衡算法相关,但又有差别,差别是: 1.ip hash,根据客户端的IP,将请求分配到不同的服务器上 2.sticky,根据服务器给客户端的cookie,客户端再次请求时会带上此cookie,nginx会把有此cookie的请求转发到颁发cookie的服务器上 注意:在一个局域网内有3台电脑,他们有3个内网IP,但是他们发起请求时,却只有一个外网IP,是电信运营商分配在他们连接那个路由器上的, 如果使用 ip_hash 方式,则Nginx会将请求分配到不同上游服务器,如果使用 sticky 模块,则会把请求分配到办法cookie的服务器上, 实现:内网nat用户的均衡。这是iphash无法做到的 Sticky工作原理: Sticky是基于cookie的一种负载均衡解决方案,通过分发和识别cookie,使来自同一个客户端的请求落在同一台服务器上,默认cookie标识名为route : 1.客户端首次发起访问请求,nginx接收后,发现请求头没有cookie,则以轮询方式将请求分发给后端服务器。 2.后端服务器处理完请求,将响应数据返回给nginx。 3.此时nginx生成带route的cookie,返回给客户端。route的值与后端服务器对应,可能是明文,也可能是md5、sha1等Hash值 4.客户端接收请求,并保存带route的cookie。 5.当客户端下一次发送请求时,会带上route,nginx根据接收到的cookie中的route值,转发给对应的后端服务器
安装常用软件包
Sticky官网地址
官方地址: 进入此网址后下载 https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/downloads
下载Sticky,此链接不一定能下载,上面的网站进行下载
wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip
解压Sticky,解压到/usr/local/src目录下
unzip unzip 08a395c66e42.zip -d /usr/local/src/
重命名nginx-sticky-module
mv /usr/local/src/nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky-module
下载nginx-1.26.1.tar.gz
wget https://nginx.org/download/nginx-1.26.1.tar.gz
进入到nginx目录里
cd cd /root/nginx-1.26.1/
编译安装,并添加nginx-sticky-module模块
./configure --prefix=/usr/local/nginx --with-http_ssl_module --user=nginx --group=nginx --with-stream --add-module=/usr/local/src/nginx-sticky-module --with-http_stub_status_module
预编译,会报错
make
报错信息如下
/usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c: In function ‘ngx_http_init_sticky_peer’: /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:54: error: ‘ngx_http_headers_in_t’ has no member named ‘cookies’ if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:2: error: passing argument 2 of ‘ngx_http_parse_multi_header_lines’ from incompatible pointer type [-Werror] if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ In file included from /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:9:0: src/http/ngx_http.h:111:18: note: expected ‘struct ngx_table_elt_t *’ but argument is of type ‘struct ngx_str_t *’ ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r, ^ /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:2: error: too few arguments to function ‘ngx_http_parse_multi_header_lines’ if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ In file included from /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:9:0: src/http/ngx_http.h:111:18: note: declared here ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r, ^ cc1: all warnings being treated as errors make[1]: *** [objs/addon/nginx-sticky-module/ngx_http_sticky_module.o] Error 1 make[1]: Leaving directory `/root/nginx-1.26.1' make: *** [build] Error 2
解决方法如下
进入sticky模块的目录编辑ngx_http_sticky_misc.c ,新增以下两行
cd /sur/local/src/nginx-sticky-module 编辑,添加好以后保存退出 vim ngx_http_sticky_misc.c 在下面内容下面加 #include <nginx.h> #include <ngx_config.h> #include <ngx_core.h> #include <ngx_http.h> #include <ngx_md5.h> #include <ngx_sha1.h> ###这是新加的内容 #include <openssl/sha.h> #include <openssl/md5.h>
再来make,还会报错
cd /root/nginx-1.26.1 make
报错信息
[root@centos7 nginx-1.26.1]# make make -f objs/Makefile make[1]: Entering directory `/root/nginx-1.26.1' cc -c -pipe -O -W -Wall -Wpointer-arith -Wno-unused-parameter -Werror -g -I src/core -I src/event -I src/event/modules -I src/event/quic -I src/os/unix -I objs -I src/http -I src/http/modules -I src/stream \ -o objs/addon/nginx-sticky-module/ngx_http_sticky_module.o \ /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c: In function ‘ngx_http_init_sticky_peer’: /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:54: error: ‘ngx_http_headers_in_t’ has no member named ‘cookies’ if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:2: error: passing argument 2 of ‘ngx_http_parse_multi_header_lines’ from incompatible pointer type [-Werror] if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ In file included from /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:9:0: src/http/ngx_http.h:111:18: note: expected ‘struct ngx_table_elt_t *’ but argument is of type ‘struct ngx_str_t *’ ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r, ^ /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:207:2: error: too few arguments to function ‘ngx_http_parse_multi_header_lines’ if (ngx_http_parse_multi_header_lines(&r->headers_in.cookies, &iphp->sticky_conf->cookie_name, &route) != NGX_DECLINED) { ^ In file included from /usr/local/src/nginx-sticky-module/ngx_http_sticky_module.c:9:0: src/http/ngx_http.h:111:18: note: declared here ngx_table_elt_t *ngx_http_parse_multi_header_lines(ngx_http_request_t *r, ^ cc1: all warnings being treated as errors make[1]: *** [objs/addon/nginx-sticky-module/ngx_http_sticky_module.o] Error 1 make[1]: Leaving directory `/root/nginx-1.26.1' make: *** [build] Error 2
解决方法如下:
进入cd /sur/local/src/nginx-sticky-module 修改 sed -i "s/ngx_http_parse_multi_header_lines.*/ngx_http_parse_multi_header_lines(r, r->headers_in.cookie, \&iphp->sticky_conf->cookie_name, \&route) != NULL){/g" ngx_http_sticky_module.c
再来make
进入目录 cd /root/nginx-1.26.1 再来make make
安装nginx
make install
创建启动脚本服务
cat > /lib/systemd/system/nginx.service <<EOF [Unit] Description=nginx service After=network.target [Service] Type=forking ExecStart=$INSTALL_DIR/sbin/nginx ExecReload=$INSTALL_DIR/sbin/nginx -s reload ExecStop=$INSTALL_DIR/sbin/nginx -s quit PrivateTmp=true [Install] WantedBy=multi-user.target EOF
重启deme和开机自启动nginx,并立即启动
systemctl daemon-reload systemctl enable nginx --now
修改nginx.conf,启用 sticky 功能
upstream zyi { #使用sticky,不设置expires则浏览器关闭时结束会话 sticky domain=zy.csxiuneng.com path=/; server localhost:9001; } server { listen 80; server_name zy.csxiuneng.com; access_log logs/zy.access.log main; location / { proxy_pass http://zyi; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; client_max_body_size 10m; client_body_buffer_size 256k; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; }
sticky 语法:
sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] [hash=index|md5|sha1] [no_fallback] [secure] [httponly]; [name=route] 设置用来记录会话的cookie名称 [domain=.foo.bar] 设置cookie作用的域名 [path=/] 设置cookie作用的URL路径,默认根目录 [expires=1h] 设置cookie的生存期,默认不设置,浏览器关闭即失效 [hash=index|md5|sha1] 设置cookie中服务器的标识是用明文还是使用md5值,默认使用md5 [no_fallback] 设置该项,当sticky的后端机器挂了以后,nginx返回502 (Bad Gateway or Proxy Error) ,而不转发到其他服务器,不建议设置 [secure] 设置启用安全的cookie,需要HTTPS支持 [httponly] 允许cookie不通过JS泄漏,没用过