17.proxy优化模块与Nginx负载均衡后端状态
Posted 柯正
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了17.proxy优化模块与Nginx负载均衡后端状态相关的知识,希望对你有一定的参考价值。
算法名称 | 简称 | 概述 |
---|---|---|
轮询(默认) | round-robin(RR) | 按照时间顺序逐一分配到后端不同的服务器 |
weight | weight-round-robin(WRR) | 加权轮询,weight值越大,分配到的访问几率越高 |
ip_hash | ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务 |
url_hash | url_hash | 按照访问URL的hash结果来分配请求,是每个URL定向到同一个后端服务器 |
least_conn | least_conn | 最少链接数,那个机器链接数少就分发 |
proxy优化模块
[root@nginx ~]# vim /etc/nginx/proxy_params
proxy_set_header Host $http_host; # 请求头带上的域名
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 客户端真实IP
# nginx代理与后端服务器连
proxy_connect_timeout 30;
# nginx代理等待后端服务器的响应时间
proxy_send_timeout 60;
# 后端服务器数据回传给nginx代理超时时间
proxy_read_timeout 60;
## 优化缓冲区
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
# 解决负载均衡常见典型故障
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
轮询
upstream zh_lb {
server 10.0.0.7; # 依次分配请求
server 10.0.0.8;
}
server {
listen 80;
server_name zh.com;
location / {
proxy_pass http://zh_lb;
include proxy_params; # 包含的优化
}
}
加权轮询
upstream zh_lb {
server 10.0.0.7 weight=6; # 按照6:1来分配请求
server 10.0.0.8 weight=1;
}
server {
listen 80;
server_name zh.com;
location / {
proxy_pass http://zh_lb;
include proxy_params;
}
ip_hash
具体配置不能和weight一起使用。
# 如果客户端都走相同代理, 会导致某一台服务器连接过多
upstream zh_lb {
ip_hash;
server 10.0.0.7; # 固定访问服务器
server 10.0.0.8;
}
server {
listen 80;
server_name zh.com;
location / {
proxy_pass http://zh_lb;
include proxy_params;
}
}
url_hash 具体配置
# 按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,要配合缓存命中来使用。同一个 资源多次请求,可能会到达不同的服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时间的 浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住 了资源,再此收到请求,就可以从缓存中读取。
upstream load_pass {
hash $request_uri;#实现每个url定向到同一个后端服务器
server 10.0.0.7:80;
server 10.0.0.8:80;
server 10.0.0.9:80;
}
least_conn 最少链接数
# 把请求转发给连接数较少的后端服务器。轮询算法是把请求平均的转发给各个后端,使它们的负载大致相 同;但是,有些请求占用的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn这种方式就 可以达到更好的负载均衡效果。
upstream load_pass {
least_conn;
server 10.0.0.7:80;
server 10.0.0.8:80;
server 10.0.0.9:80;
}
面试问题
面试官:请问贵公司会话保持(session共享)是怎么做的?
-
我们从开发层面上实现
记录用户的登录状态,将登录状态保存到我们的redis服务器中(更倾向),nfs共享存储,mysql数据库 -
我们从运维层面上实现
因为开发没有写会话保持的功能,所以我们只能在nginx中使用upstream模块的ip_hash调度算法,但是
这个算法,可能会负载不均衡,有弊端... -
什么是session?
-
什么是cookie?
1.cookie是客户端浏览网站的的时候,把客户端信息以某种形式记录在浏览器上。
2.session是客户端浏览服务端的时候,服务端把客户端信息以某种形式记录在服务器上,这种记录就是Session,用来保护cookie
Nginx负载均衡后端状态
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡(和注释一样) |
backup | 预留的备份服务器(当所有机器挂了的时候就会使用) |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后, 服务暂停时间 |
max_conns | 限制最大的接收连接数 |
环境准备
角色 | 服务器web |
---|---|
down | web01 |
backup | web02 |
max_fails,fail_timeout,max_conns | web03 |
负载均衡 | lb01 |
web01 down了
[root@lb01 ~]# vim /etc/nginx/conf.d/wp_lb.conf
upstream backend {
server 10.0.0.7 down;
server 10.0.0.8;
server 10.0.0.9;
}
server {
listen 80;
server_name www.wp.com;
location / {
proxy_pass http://backend;
include proxy_params;
}
}
[root@lb01 ~]# nginx -s reload
web02 做backup
[root@lb01 ~]# vim /etc/nginx/conf.d/wp_lb.conf
upstream backend {
server 10.0.0.7 down;
server 10.0.0.8 backup;
server 10.0.0.9;
}
server {
listen 80;
server_name www.wp.com;
location / {
proxy_pass http://backend;
include proxy_params;
}
}
[root@lb01 ~]# nginx -s reload
web03,请求失败后暂停时间max_fails,fail_timeout
# 允许请求失败的次数,经过max_fails次失败后, 服务暂停时间fail_timeout。
# 需要配合proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_404 http_403;
[root@lb01 ~]# vim /etc/nginx/conf.d/wp_lb.conf
upstream backend {
server 10.0.0.7 down;
server 10.0.0.8 backup;
server 10.0.0.9 max_fails=1 fail_timeout=5s;
}
server {
listen 80;
server_name www.wp.com;
location / {
proxy_pass http://backend;
include proxy_params;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504 http_404 http_403;
}
}
[root@lb01 ~]# nginx -s reload
max_conns,接收连接数
upstream backend {
server 10.0.0.7;
server 10.0.0.8;
# 限制最大的接收连接数
server 10.0.0.9 max_conns=1;
}
...
Nginx负载均衡会话保持
在使用负载均衡的时候会遇到会话保持的问题,可通过如下方式进行解决。
1.使用nginx的ip_hash
,根据客户端的IP,将请求分配到对应的IP上
2.基于服务端的session
会话共享(NFS,MySQL,memcache,redis,file)
在解决负载均衡绘画问题,我们需要了解session
和cookie
的区别。
浏览器端存的是cookie
每次浏览器发请求到服务端时,报文头是会自动添加cookie
信息的。
服务端会查询用户的cookie
作为key去存储里找对应的value(session)
同一域名下的网站的cookie
都是一样的,所以无论几台服务器,无论请求分配到哪一台服务器上同一用户的cookie
是不变的。也就是说cookie
对应的session
也是唯一的。所以,这里只要保证多台业务服务器访问同一个共享存储服务器(NFS,MySQL,memcache,redis,file)就行了。
1.编辑配置文件
[root@web01 ~]# vim /etc/nginx/conf.d/myadmin.conf
server {
listen 80;
server_name admin.com;
root /code/phpMyAdmin-4.9.0.1-all-languages;
index index.php index.html;
access_log /var/log/nginx/admin_access.log main;
location ~.php$ {
root /code/phpMyAdmin-4.9.0.1-all-languages;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@web01 ~]# nginx -s reload
2.上传安装phpmyadmin(web02也装)
# 1.创建配置文件
[root@web01 ~]# mkdir /code
# 2.上传解压安装
[root@web01 ~]# cd /code
[root@web01 /code]# rz
[root@web01 /code]# unzip phpMyAdmin-4.9.0.1-all-languages_(1).zip
# 3.放到站点目录下
[root@web01 ~]# mv phpMyAdmin-4.9.0.1-all-languages /code/
# 4.授权站点目录
[root@web01 ~]# chown -R www.www /code/
# 5.修改代码
[root@web01 ~]# cd /code/phpMyAdmin-4.9.0.1-all-languages/
[root@web01 /code/phpMyAdmin-4.9.0.1-all-languages]# cp config.sample.inc.php config.inc.php
[root@web01 /code/phpMyAdmin-4.9.0.1-all-languages]# vim config.inc.php
...
/* Server parameters */ # 修改数据库ip
$cfg[‘Servers‘][$i][‘host‘] = ‘172.16.1.51‘;
...
# 6.配置授权
[root@web01 ~]# chown -R www.www /var/lib/php/
3.打开浏览器
admin.com
1.填写昨天用数据库创建的登入账号和密码
2.执行后打开页面
4.将web01上配置好的phpmyadmin以及nginx的配置文件推送到web02主机上
[root@web01 ~]# scp -rp /code/phpMyAdmin-4.9.0.1-all-languages 172.16.1.8:/code/
[root@web01 ~]# scp /etc/nginx/conf.d/myadmin.conf 172.16.1.8:/etc/nginx/conf.d/
5.授权
[root@web02 ~]# chown www.www -R /code/
[root@web02 ~]# chown -R www.www /var/lib/php/
6.接入负载均衡
[root@lb01 conf.d]# vim proxy_php.com.conf
upstream shuju {
server 10.0.0.7;
server 10.0.0.8;
server 10.0.0.9;
}
server {
listen 80;
server_name admin.com;
location / {
proxy_pass http://shuju;
include proxy_params;
}
}
# 检查语法
[root@lb01 conf.d]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# 重新加载
[root@lb01 conf.d]# systemctl restart nginx
使用负载均衡的轮询功能之后,会发现,如果将session保存在本地文件的话,永远都登录不上去,下面使用redis解决会话登入问题
7.使用redis解决会话登录问题
在数据库的主机上安装redis
# 1.安装redis
[root@db01 ~]# yum install redis -y
# 2.配置redis监听在172.16.1.0网段上 # 修改redis的配置文件
[root@db01 ~]# sed -i ‘/^bind/c bind 127.0.0.1 172.16.1.51‘ /etc/redis.conf
# 3.启动redis
[root@db01 ~]# systemctl start redis
[root@db01 ~]# systemctl enable redis
# 4.php配置session连接redis
# 4.1修改/etc/php.ini文件
[root@web01 ~]# vim /etc/php.ini
...
session.save_handler = redis
...
session.save_path = "tcp://172.16.1.51:6379"
;session.save_path = "tcp://172.16.1.51:6379?auth=123" #如果redis存在密码,则使用该方式
...
session.auto_start = 1
...
#5.注释php-fpm.d/www.conf里面的两条内容,否则session内容会一直写入/var/lib/php/session目录中
...
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
# 6.重启php-fpm
[root@web01 ~]# systemctl restart php-fpm
# 7.将web01上配置好的文件推送到web02
[root@web01 ~]# scp /etc/php.ini root@172.16.1.8:/etc/php.ini
[root@web01 ~]# scp /etc/php-fpm.d/www.conf root@172.16.1.8:/etc/php-fpm.d/
# 8.上web02上重启php-fpm
[root@web02 code]# systemctl restart php-fpm
# 9. redis查看数据
[root@db01 redis]# redis-cli
127.0.0.1:6379> keys *
1) "PHPREDIS_SESSION:3c17869121aa396a4c5f47708ec53d0b"
2) "PHPREDIS_SESSION:69835e2371529a213edd566a5f065f9f"
看图
以上是关于17.proxy优化模块与Nginx负载均衡后端状态的主要内容,如果未能解决你的问题,请参考以下文章