nginx负载均衡
1.负载均衡如何实现流量分发
nginx如何代理多台服务器?
添加多个proxy_pass参数是行不通的,location中只能出现一次proxy_pass,不能出现多个
这时就需要⽤到nginx反向代理衍⽣的功能,负载均衡
负载均衡如何实现流量的分发:
1.需要用到两个模块:proxy_pass模块与upstream模块
2.先将相同业务的web服务器定义为⼀组upstream资源池
3.再通过proxy_pass的⽅式,代理到这⼀组upstream资源池上,即可实现负载均衡功能
4.⽤户请求负载均衡,负载均衡将请求分散的打到后端的多个web节点
2.负载均衡如何配置
例:
负载均衡:192.168.51.164
web节点1:192.168.51.163
web节点2:192.168.51.165
将客户端的请求分发到两台不同的web节点上
1.负载均衡端配置
vim /etc/nginx/conf.d/lb.conf
upstream web { #定义虚拟资源池,名称叫web,⾥⾯有两台web服务器
server 192.168.51.163:80;
server 192.168.51.165:80;
}
server {
listen 80;
server_name www.test.com;
location / {
proxy_pass http://web; #调⽤upstream资源池定义的名称
include proxy_params; #包含优化参数
}
}
nginx -t
systemctl reload nginx
2.web节点1配置
vim /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name www.test.com;
root /html;
location / {
index index.html;
}
}
#重载nginx
nginx -t
systemctl reload nginx
#准备文件
echo 'this is node1...'>/html/index.html
3.web节点2配置
vim /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name www.test.com;
root /html;
location / {
index index.html;
}
}
#重载nginx
nginx -t
systemctl reload nginx
#准备文件
echo 'this is node2....'>/html/index.html
4.查看测试结果
访问www.test.com
刷新一次,就来到了web节点2上
再刷新一次就来到了web节点1上
3.负载均衡调度算法
1.轮询:将⽤户请求调度到不同的web节点,一个节点一次,公平调度算法。(默认使用的调度算法)
upstream test {
server 192.168.10.10:80;
server 192.168.10.20:80;
}
2.加权轮询:根据后端的节点性能情况,调整他们的负载值,weight值越大,被访问的几率越大,能者多劳。
upstream test {
server 192.168.10.10:80 weight=5;
server 192.168.10.20:80 weight=3;
}
3.ip_hash: 将客户端绑定⾄某⼀个指定的后端服务节点。 ( 做会话保持 ) 不管刷新多少次都在同一个节点上
upstream test {
ip_hash;
server 192.168.10.10:80;
server 192.168.10.20:80;
}
4.least_conn: 谁的连接数少,就将请求发给谁。( 动态的调度 )
upstream test {
least_conn;
server 192.168.10.10:80;
server 192.168.10.20:80;
}
4.后端web节点在负载均衡调度中的状态
down
当后端节点状态为down表示,当前节点不启用,请求将不再发给它
backup
当作备胎,upstream资源池中所有的节点都无法使用时,它才会顶替上去
但凡有一个节点恢复正常,它都将被停掉
max_fails与fail_timeout一般这两个状态连用
例:max_fails=3 fail_timeout=10s
表示10秒内请求失败超过3次,则认定这个节点不可用
但是还会一直监控它的可用性,当检测到他可用时,还会将客户端请求发给它
max_conns
限制最多能接收多少连接
例:
upstream name {
server 192.168.51.163 down;
server 192.168.51.165;
}
例:
upstream name {
server 192.168.51.163 backup;
server 192.168.51.165;
}
例:
upstream name {
server 192.168.51.163:80 weight=5 max_fails=3 fail_timeout=10s max_conns=1000;
server 192.168.51.165:80 weight=3 max_fails=3 fail_timeout=10s max_conns=1000;
}
5.实现会话保持
存在的问题:将相同业务的后端节点加入负载均衡后,在客户端进行登录操作的时候,会发现不管在哪个节点都无法登陆
解决方案:做会话保持
1.粘性session: ip_hash 始终定向⾄某⼀个后端web节点。
2.session共享: 将session通过存储到指定⼀个位置,⽽不是存储⾄本地,后端所有节点都通过这个位置进行验证 ( redis )
1.粘性session: ip_hash 始终定向⾄某⼀个后端web节点。
2.session复制: 每次session发⽣变化时,就通过⼴播的形式通知给集群中的其他服务器,使得集群中所有节点的session⼀致。
3.session共享: 将session通过存储到指定⼀个位置,⽽不是存储⾄本地。 ( redis ) o(1)
4.session持久化:就session信息写到数据库中。 ( 例如wordpress是写到数据库。) o(N)
数据库o(N)级别,例如检索一条数据需要1秒,那么检索1000条数据,就需要1000秒
数据库o(1)级别,查一条数据需要1秒,查1000条数据也是一秒
ip_hash 做会话保持
这里使用phpmyadmin进行会话保持演示:
负载均衡:192.168.51.164
phpmyadmin节点1:192.168.51.163
phpmyadmin节点2:192.168.51.165
节点1与节点2 都按以下步骤进行配置
1.下载phpmyadmin
wget https://files.phpmyadmin.net/phpMyAdmin/5.0.2/phpMyAdmin-5.0.2-all-languages.zip
解压到指定目录
unzip phpMyAdmin-5.0.2-all-languages.zip -d /html
2.修改phpmyadmin的配置,指定程序连接数据库的IP地址
cd /html/phpMyAdmin-5.0.2-all-languages
创建配置文件
cp config.sample.inc.php config.inc.php
编辑配置文件
vim config.inc.php
/* Server parameters */
$cfg['Servers'][$i]['host'] = '192.168.xx.xxx'; #此处是数据库服务器的地址
3.配置nginx
vim /etc/nginx/conf.d/www.phpmy.com.conf
server {
listen 80;
server_name www.phpmy.com;
root /html/phpMyAdmin-5.0.2-all-languages;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
4.重载nginx
nginx -t
systemctl reload nginx
负载均衡配置
在这里做了会话保持,就会解决无法登陆的问题,但是只能访问固定的一个web节点,无法轮询
upstream web {
ip_hash; #做会话保持
server 192.168.51.163:80;
server 192.168.51.165:80;
}
server {
listen 80;
server_name www.phpmy.com;
location / {
proxy_pass http://web;
include proxy_params;
}
}
修改客户端的hosts文件
192.168.51.164 www.phpmy.com
redis来实现会话保持
redis配置
1.部署redis
yum install redis -y
2.配置redis,让别的服务器可以访问到它
vim /etc/redis.conf
bind 127.0.0.1 192.168.xx.xxx
#redis部署在哪台服务器,这里就写哪个服务器的地址192.168.xx.xxx
#让其他服务器可以通过192.168.xx.xxx来访问redis
#或者配置成允许别⼈通过192.168.xx.0/⽹段访问redis数据库也可以
3.启动redis,并将其加⼊开机⾃启动。
systemctl start redis
systemctl enable redis
netstat -lntp |grep 6379
每个web端配置
修改所有的web服务器中php的配置
1.先修改php.ini 使⽤redis⽅式存储session,然后配置redis的地址及端⼝信息
vim /etc/php.ini
[Session]
;session.save_handler = files #将默认的注释掉,使⽤ ;来进⾏注释
#新增如下两条:
session.save_handler = redis
session.save_path = "tcp://192.168.xx.xxx:6379" #redis的地址
2. vim /etc/php-fpm.d/www.conf #注释掉如下两⾏
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
3.重启php-fpm
systemctl restart php-fpm
负载均衡配置
使用轮询的机制就可以
upstream web {
server 192.168.51.163:80;
server 192.168.51.165:80;
}
server {
listen 80;
server_name www.phpmy.com;
location / {
proxy_pass http://web;
include proxy_params;
}
}
nginx -t
systemctl reload nginx
然后刷新就可以查看会话保持的效果
这里我把数据库和其中一台web节点部署在了一台服务器上了,所以显示localhost
可以看到redis中存的session
6.负载均衡根据不同设备调度至不同集群
不同的设备所访问的后端服务器不同
例:
准备环境
lb作为负载均衡,统⼀调度:
他需要根据⽤户来源的设备进行判断:
如果⽤户是⼿机端,则调度到后端192.168.51.163的8080 、8081
如果⽤户是电脑端,则调度到后端的192.168.51.165的9090、9091
web01作为⼿机端集群,多端⼝⽅式:
web1 8080: phone-8080
web2 8081: phone-8081
web02作为电脑端集群,多端⼝的⽅式:
web1 9090: pc-9090
web2 9091: pc-9091
负载均衡配置
1.编辑nginx配置文件
vim /etc/nginx/conf.d/lb.conf
upstream phone {
server 192.168.51.163:8080;
server 192.168.51.163:8081;
}
upstream pc {
server 192.168.51.165:9090;
server 192.168.51.165:9091;
}
server {
listen 80;
server_name www.agent.com;
location / {
#根据$http_user_agent参数判断,如果你是⼿机端,我们就进⼊该判断,由phone集群处理
if ( $http_user_agent ~* "iphone|android|ipad"){
proxy_pass http://phone;
}
proxy_pass http://pc; #如果不是⼿机端,则直接由pc集群处理
include proxy_params;
}
}
2.重载nginx
nginx -t
systemctl reload nginx
手机web端配置
1.准备文件
mkdir web_8080
mkdir web_8081
echo 'phone-8080'> /html/web_8080/index.html
echo 'phone-8081'> /html/web_8081/index.html
2.编辑nginx配置文件
vim /etc/nginx/conf.d/www.agent.com.conf
server {
listen 8080;
server_name www.agent.com;
root /html/web_8080;
location / {
index index.html;
}
}
server {
listen 8081;
server_name www.agent.com;
root /html/web_8081;
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
电脑web端配置
1.准备文件
mkdir web_9090
mkdir web_9091
echo pc-9090'> /html/web_9090/index.html
echo 'pc-9091'> /html/web_9091/index.html
2.编辑nginx配置文件
vim /etc/nginx/conf.d/www.agent.com.conf
server {
listen 9090;
server_name www.agent.com;
root /html/web_9090;
location / {
index index.html;
}
}
server {
listen 9091;
server_name www.agent.com;
root /html/web_9091;
location / {
index index.html;
}
}
3.重载nginx
nginx -t
systemctl reload nginx
查看效果
手机端访问:
电脑端访问: