问题:在集群中有多台服务器的情形下,开发者会在Cookie中记录一些字段,甚至是登录态。所以需要让访问者访问到某台机器后,后续的请求仍然在同一台服务器上处理。
一、需求分析
目前,负载分发问题的约束条件是:
- 众多访问者的请求尽可能均匀地被分发到后端集群的机器中。
- 同一个访问者再次访问,多个请求被同一台机器处理。
解决方案:
- IP Hash:利用用户在上网时,一段时间内的ip是不会改变的原理。将用户的ip做哈希,对其请求进行分发。因为用户的ip暂时不变,所以其请求会被分发到同一台机器上。
- 基于Cookie做跟踪:第一次请求时,服务器给客户端下发一个cookie,具有特定cookie的请求会分配给同一个服务器。
上述两种方案中显然第二种更优。因为约束条件第一条,请求尽可能均匀地被分发。用IP做Hash的情况,当属于某种类型IP的用户请求非常多的话,负载会出现不均匀的情况。另外,如果前置还有代理服务器的话,IP相同的情况,也会出现请求分布不均匀。所以采用第二种方案较好,Sticky第三方模块就是利用第二种方案的思路。
二、下载安装
下载
下载地址:http://code.google.com/p/nginx-sticky-module/downloads/list
或者
wget https://code.google.com/p/nginx-sticky-module/downloads/detail?name=nginx-sticky-module-1.1.tar.gz
解压:
tar -xzvf nginx-sticky-module-1.1.tar.gz
我这里解压到
/usr/local/nginx/sticky/nginx-sticky
安装
在Nginx源码编译的目录下,运行代码:
./configure —prefix=/usr/local/nginx —add-module=/usr/local/nginx/sticky/nginx-sticky
make
(不要make install,要不然就相当于重新安装了。)
复制编译后的二进制文件到目录(拷贝前把服务停掉):
1 | cp /usr/local/nginx/nginx /usr/local/nginx/nginx.bak |
使用
在nginx.conf配置文件中,对upstream块添加sticky;即可。1
2
3
4
5
6
7upstream myproject{
#添加sticky模块后加入此配置
sticky;
#被代理的服务
server 192.168.1.100:8081;
server 192.168.1.101:8080;
}
三、问题及解决
编译出现类型转换错误
1 | cc1: warnings being treated as errors |
解决:
第一步:根据资料 把ngx_http_sticky_misc.c 的281行修改如下:
原digest->len = ngx_sock_ntop(in,digest
->data, len, 1);改成digest->len = ngx_sock_ntop(in,sizeof(struct sockaddr_in),digest
->data, len, 1);
第二步:对nginx-sticky-module-1.1/ngx_http_sticky_module.c文件也进行修改(主要是1.9.x版本会出现这问题)
修改两个地方,如下图:
第6行添加:
1 | #include <nginx.h> |
第340行左右修改(iphp->rrp.current = iphp->selected_peer;)为:
1 | iphp->rrp.current = peer; |
版本问题,修改stick代码后,问题得以解决。
编译出现hash和md5问题
问题描述:
1 | ngx_http_sticky_misc.c: In function 「ngx_http_sticky_misc_md5」: |
解决:
解决方式就是在下载解压缩之后的sticky模块文件夹中,修改ngx_http_sticky_misc.c文件
将这两个模块
下面红色标注地方
1 | #include <openssl/sha.h> |
引入的问题,引入之后再重新编译就不会出现这种原因的错误了。
编译出现依赖的模块问题
描述:1
fatal error: openssl/aes.h:No such file or directory
解决:
尝试编译的程序使用OpenSSL,但是需要和OpenSSL链接的文件(库和头文件)在Linux平台系统上缺少。(其它类似的错误也可以照此处理)
要解决这个问题,安装OpenSSL。
要在Debian、Ubuntu或者其他衍生版上安装OpenSSL:1
sudo apt-get install libssl-dev
要在Fedora、CentOS或者RHEL上安装OpenSSL开发包:1
sudo yum install openssl-devel
安装完后,尝试重新编译程序。
参考&致谢
nginx-sticky-module文档
nginx-sticky-module-ng文档问题