nginx负载均衡

背景

随着网站、应用访问量的增加,一台服务器已经不能满足应用的需求,而需要多台服务器集群,这时就需要用到负载均衡了

负载均衡的好处

负载均衡优化了访问请求在服务器组之间的分配,消除了服务器之间的负载不平衡,从而提高了系统的反应速度与总体性能;

负载均衡可以对服务器的运行状况进行监控,及时发现运行异常的服务器,并将访问请求转移到其它可以正常工作的服务器上,从而提高服务器组的可靠性采用了负均衡器器以后,可以根据业务量的发展情况灵活增加服务器,系统的扩展能力得到提高,同时简化了管理。

负载均衡的几种常用方式

1.轮询(默认)

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

1
2
3
4
upstream backserver {
server 192.168.0.14;
server 192.168.0.15;
}

2.weight权重

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

1
2
3
4
upstream backserver {
server 192.168.0.14 weight=3;
server 192.168.0.15 weight=7;
}

权重越高,在被访问的概率越大,如上例,分别是30%,70%

3.ip_hash (解决session问题)

方式1和2存在一个问题,在负载均衡系统中,假如用户在某台服务器上登录了,那么该用户第二次请求的时候,每次请求都会随机重新定位到服务器集群中的某一个,那么已经登录某一个服务器的用户再重新定位到另一个服务器,其登录信息将会丢失,这样显然是不妥的。

我们可以采用ip_hash指令解决这个问题,如果客户已经访问了某个服务器,当用户再次访问时,会将该请求通过哈希算法,自动定位到该服务器

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

在redis.conf中进行配置:

1
2
3
4
5
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}

4、fair(第三方)

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

1
2
3
4
5
upstream backserver {
server server1;
server server2;
fair;
}

5、url_hash(第三方)

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

1
2
3
4
5
6
upstream backserver {
server squid1:3128;
server squid2:3128;
hash $request_uri;
hash_method crc32;
}

LNMP环境下负载均衡

1.域名解析

以阿里云服务器为例,进入阿里云管理后台,域名管理处,选择excample.com域名解析到服务器ip

2.nginx配置

域名解析后,进入nginx配置文件,(以centos 7下的yum install nginx为例)

80端口分发服务配置

vi /etc/nginx/conf.d/test_example_com.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
upstream test.example.com {
# ip_hash;
server 192.168.214.81:8089 weight=5;
server 192.168.214.81:8088 weight=3;
}
server {
listen 80;
server_name test.example.com;
location / {
proxy_pass http://test.example.com;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
index index.php index.html index.htm;
}
}
注意:proxy_pass反向代理的upstream域名需要和server_name一致,否则会出现访问报错

8088端口解析服务配置

vi /etc/nginx/conf.d/example8088.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
server
{
listen 8088;
server_name 192.168.214.81;
index index.php index.htm index.html;
root /opt/web/xxx/public/;
location / {
location ~* \.(js|css|html|htm)$ {
if (-f $request_filename) {
root /opt/web/a/public/;
expires 1d;
break;
}
}
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
}
index index.php index.html index.htm;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

8089端口解析服务配置

vi /etc/nginx/conf.d/example8089.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
server
{
listen 8089;
server_name 192.168.214.81;
index index.php index.htm index.html;
root /opt/web/xxx/public/;
location / {
location ~* \.(js|css|html|htm)$ {
if (-f $request_filename) {
root /opt/web/b/public/;
expires 1d;
break;
}
}
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=/$1 last;
}
index index.php index.html index.htm;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

测试

重启web服务器nginx
service nginx restart

往两个系统的首页写入标识内容

1
2
3
echo '8088 a' /opt/web/a/public/index.html
echo '8089 b' /opt/web/b/public/index.html

浏览器访问 test.excample.com

可以看到不停的变换’8089 b’和’8088 a’ 说明负载均衡成功运行

将ip_hash;前的#号去掉,重启web服务器nginx

service nginx restart

浏览器访问 test.excample.com

可以浏览器输出的内容并不会变换,说明iphash模式下的负载均衡运行成功

总结

nginx监听本地的80端口,80端口接收到请求后,将请求转发到192.168.214.81:8089,192.168.214.81:8088应用中的其中一个,如果映射的策略是ip_hash,这个策略会对请求的ip进行hash运算并将结果映射到其中一个应用,它能确保一个确定的请求ip会被映射到一个确定的服务,这样就连session的问题也就解决了。如果不需要考虑session,可选用默认的轮询或权重