负载均衡

Posted givenchy_yzl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了负载均衡相关的知识,希望对你有一定的参考价值。

⼀、nginx反向代理与正向代理
正向代理与反向代理区别:
1.代理的服务对象不⼀样
2.正向代理服务的对象是客户端,为客户端服务
3.反向代理服务的对象是服务端,为服务端服务

⼆、Nginx⽀持的协议
1.http
2.https
3.websocket
4.tcp/ip
5.rtmp
6.pop/imap
在这里插入图片描述
三、Nginx配置代理
1.代理的语法

Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
location /name/ {
 proxy_pass http://127.0.0.1/remote/;
}

2.配置nginx

server {
    listen 80;
    server_name proxy.linux.com;
 
    location / {
        proxy_pass http://172.16.1.7:80;
        prxoy_set_header Host $http_host;
    }
}
#代理优化的参数
[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;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
location {
 proxy_pass http://172.16.1.7:80;
 include proxy_params;
}

四、Nginx负载均衡
#注意:代理只能代理⼀台机器
nginx做代理,⼀个location可以做⼀个代理

1.为什么做负载均衡
(1)当我们的Web服务器直接⾯向⽤户,往往要承载⼤量并发请求,单台服务器难以负荷,我使⽤多台Web服务器组成集群,前端使⽤Nginx负载均衡,将请求分散的打到我们的后端服务器集群中,实现负载的分发。那么会⼤⼤提升系统的吞吐率、请求性能、⾼容灾(2)往往我们接触的最多的是SLB(Server Load Balance)负载均衡,实现最多的也是SLB、那么SLB它的调度节点和服务节点通常是在⼀个地域⾥⾯。那么它在这个⼩的逻辑地域⾥⾯决定了他对部分服务的实时性、响应性是⾮常好的。
(3)所以说当海量⽤户请求过来以后,它同样是请求调度节点,调度节点将⽤户的请求转发给后端对应的服务节点,服务节点处理完请求后在转发给调度节点,调度节点最后响应给⽤户节点。这样也能实现⼀个均衡的作⽤,那么Nginx则是⼀个典型的SLB

2.负载均衡的叫法
负载均衡
负载
Load Balance
LB

3.公有云中负载叫法
SLB 阿⾥云负载均衡
LB ⻘云负载均衡
CLB 腾讯云负载均衡
ULB ucloud负载均衡

4.常⻅的负载均衡软件
Nginx #在1.9版本之前只能做七层,1.9版本之后既能做七层,也能做四层负载均衡
Haproxy #既能做四层,也能做七层负载均衡
LVS #只能做四层负载均衡
#LVS是最快的负载均衡软件,其他两个软件需要将请求发送到服务再转发到后端,LVS不⽤到服务,它相当于将服务器变成了负载均衡,直接转发请求

5.负载均衡类型
#四层负载均衡
所谓四层负载均衡指的是OSI七层模型中的传输层,那么传输层Nginx已经能⽀持TCP/IP的控制,所以只需要对客户端的请求进⾏TCP/IP协议的包转发就可以实现负载均衡,那么它的好处是性能⾮常快、只需要底层进⾏应⽤处理,⽽不需要进⾏⼀些复杂的逻辑。
#七层负载均衡
七层负载均衡它是在应⽤层,那么它可以完成很多应⽤⽅⾯的协议请求,⽐如我们说的http应⽤的负载均衡,它可以实现http信息的改写、头信息的改写、安全应⽤规则控制、URL匹配规则控制、以及转发、rewrite等等的规则,所以在应⽤层的服务⾥⾯,我们可以做的内容就更多,那么Nginx则是⼀个典型的七层负载均衡SLB

#四层负载与七层负载区别
四层负载均衡数据包在底层就进⾏了分发,⽽七层负载均衡数据包则是在最顶层进⾏分发、由此可以看
出,七层负载均衡效率没有四负载均衡⾼。
但七层负载均衡更贴近于服务,如:http协议就是七层协议,我们可以⽤Nginx可以作会话保持,URL
路径规则匹配、head头改写等等,这些是四层负载均衡⽆法实现的。
注意:四层负载均衡不识别域名,七层负载均衡识别域名

五、Nginx负载均衡配置
Nginx要实现负载均衡需要⽤到proxy_pass代理模块配置.
Nginx负载均衡与Nginx代理不同地⽅在于,Nginx的⼀个location仅能代理⼀台服务器,⽽Nginx负载均衡则是将客户端请求代理转发⾄⼀组upstream虚拟服务池.

1.负载均衡配置语法 ngx_http_upstream_module

#语法:
Syntax: upstream name { ... }
Default: —
Context: http


upstream backend {
    server backend1.example.com;
    server backend2.example.com;
}

server {
    listen 80;
    server_name www.linux.com
    location / {
        proxy_pass http://backend;
    }
}

2.环境准备
在这里插入图片描述
3.web01准备站点

[root@web01 conf.d]# vim node.conf
server {
    listen 80;
    server_name node.linux.com;
    location / {
        root /code/node;
        inde index.html;
    }
}

[root@web01 conf.d]# mkdir /code/node
[root@web01 conf.d]# echo "我是web01......" > /code/node/index.html
[root@web01 conf.d]# systemctl restart nginx

4.web02准备站点

[root@web02 conf.d]# vim node.conf
server {
    charset 'utf-8';
    listen 80;
    server_name node.linux.com;
    location / {
        root /code/node;
        index index.html;
    }
}

[root@web02 conf.d]# mkdir /code/node
[root@web02 conf.d]# echo "我是web02......" > /code/node/index.html
[root@web02 conf.d]# systemctl restart nginx

5.配置负载均衡配置⽂件

[root@lb01 conf.d]# vim node_proxy.conf
upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
}
server {
    listen 80;
    server_name node.linux.com;
    location / {
        proxy_pass http://node;
        include proxy_params;
    }
}

#检查include⽂件是否存在
[root@lb01 conf.d]# ll /etc/nginx/proxy_params
-rw-r--r-- 1 root root 275 Feb 28 15:24 /etc/nginx/proxy_params
[root@lb01 conf.d]# systemctl restart nginx

6.配置优化⽂件

[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;
proxy_connect_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;

7.访问页面测试

8.负载均衡常⻅问题
如果后台服务连接超时,Nginx是本身是有机制的,如果出现⼀个节点down掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、502、500,这个时候你需要加⼀个负载均衡的设置,如下:
proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404
意思是,当其中⼀台返回错误码404,500…等错误时,可以分配到下⼀台服务器程序继续处理,提⾼平台访问成功率。

server {
    listen 80;
    server_name node.linux.com;
    location / {
        proxy_pass http://node;
        proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    }
}

六、nginx 调度算法
在这里插入图片描述
1.轮询配置⽅法

upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
}

2.加权轮询配置⽅法

#访问根据配置的权重⽐例进⾏分配
upstream node {
    server 172.16.1.7:80 weight=5;
    server 172.16.1.8:80 weight=1; 
}

3.ip_hash的配置⽅法

#根据访问的来源IP分配⾄同⼀台服务器
upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    ip_hash;
}
#经常使⽤这种⽅式进⾏会话保持

七、nginx负载均衡状态
在这里插入图片描述
1.down状态配置测试

upstream node {
 #不参与负载均衡任何调度,⼀般停机维护或者上线的时候使⽤
    server 172.16.1.7:80 down;
    server 172.16.1.8:80;
}

2.backup状态配置测试

upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80 backup;
}

3.访问错误状态

upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80 max_fails=3 fail_timeout 10s;
}

4.max_conns限制最⼤连接数状态配置

upstream node {
    server 172.16.1.7:80;
    server 172.16.1.8:80 max_conns=120; 
 }

⼋、nginx健康检查模块(扩展了解)

[root@lb01 ~]# yum install -y gcc glibc gcc-c++ pcre-devel openssl-devel
patch
[root@lb01 ~]# wget http://nginx.org/download/nginx-1.14.2.tar.gz
[root@lb01 ~]# wget
https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip
[root@lb01 ~]# tar xf nginx-1.14.2.tar.gz
[root@lb01 ~]# unzip master.zip
[root@lb01 ~]# cd nginx-1.14.2/
[root@lb01 nginx-1.14.2]# patch -p1 <../nginx_upstream_check_modulemaster/check_1.14.0+.patch

./configure --prefix=/data/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/data/nginx/nginx.conf --error-log-path=/data/log/nginx/error.log --http-log-path=/data/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --
with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --
with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module -
-with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --
with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --
with-stream_realip_module --with-stream_ssl_module --withstream_ssl_preread_module --add-module=/root/nginx_upstream_check_module-master --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -
fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecordgcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-
z,now -pie'
[root@lb01 nginx-1.14.2]# make && make install
[root@lb01 nginx-1.14.2]# vim /etc/nginx/conf.d/proxy.conf
upstream web {
    server 10.0.0.7;
    server 10.0.0.8;
    check interval=3000 rise=1 fall=2 timeout=1000;
}
server {
    listen 80;
    server_name proxy.linux.com;
    location / {
        proxy_pass http://web;
        proxy_set_header host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
    }
    location /upstream_check {
        check_status;
    }
}

九、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.配置Nginx

[root@web01 conf.d]# cat php.conf
server {
    listen 80;
    server_name php.yzl.com;
    root /code/phpMyAdmin-4.8.4-all-languages;

    location / {
        index index.php index.html;
    }

    location ~ \\.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}
[root@web01 conf.d]# systemctl restart nginx

2.安装phpmyadmin (web01和web02上都装)

[root@web01 conf.d]# cd /code
[root@web01 code]# wget https://files.phpmyadmin.net/phpMyAdmin/4.8.4/phpMyAdmin-4.8.4-all-languages.zip
[root@web01 code]# unzip phpMyAdmin-4.8.4-all-languages.zip

3.配置phpmyadmin连接远程的数据库

[root@web01 code]# cd phpMyAdmin-4.8.4-all-languages/
[root@web01 phpMyAdmin-4.8.4-all-languages]# cp config.sample.inc.php config.inc.php
[root@web01 phpMyAdmin-4.8.4-all-languages]# vim config.inc.php
/* Server parameters */
$cfg['Servers'][$i]['host'] = '172.16.1.51';

4.配置授权

[root@web01 conf.d]# chown -R www.www /var/lib/php/
[root@web01 phpMyAdmin-4.8.4-all-languages]# ll /var/lib/php/session/
总用量 4
-rw-------. 1 www www 2424 8月  21 18:41 sess_e96b27a6a628be47745a10a36e2fcd5a

5.将web01上配置好的phpmyadmin以及nginx的配置文件推送到web02主机上

[root@web01 code]# scp -rp  phpMyAdmin-4.8.4-all-languages root@172.16.1.8:/code/
[root@web01 code]# scp /etc/nginx/conf.d/php.conf  root@172.16.1.8:/etc/nginx/conf.d/

6.在web02上重载Nginx服务

[root@web02 code]# systemctl restart nginx

7.授权

[root@web02 code]# chown -R www.www /var/lib/php/

8.接入负载均衡

[root@lb01 conf.d]# vim proxy_php.com.conf 
upstream php {
        server 172.16.1.7:80;
        server 172.16.1.8:80;
}
server {
        listen 80;
        server_name php.yzl.com;
        location / {
                proxy_pass http://php;
                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解决会话登录问题
1.安装redis内存数据库

[root@db01 ~]# yum install redis -y

2.配置redis监听在172.16.1.0网段上

[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

#1.修改/etc/php.ini文件
[root@web ~]# 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

#2.注释 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

5.重启php-fpm

[root@web01 code]# systemctl restart php-fpm
[root@web02 code]# systemctl restart php-fpm

6.将web01上配置好的文件推送到web02

[root@web01 code]# scp /etc/php.ini root@172.16.1.8:/etc/php.ini  
[root@web01 code]# scp /etc/php-fpm.d/www.conf root@172.16.1.8:/etc/php-fpm.d/www.conf 

7.redis查看数据

[root@db01 redis]# redis-cli
127.0.0.1:6379> keys *
1) "PHPREDIS_SESSION:1365eaf0490be9315496cb7382965954"

以上是关于负载均衡的主要内容,如果未能解决你的问题,请参考以下文章

几种简单的负载均衡算法及其Java代码实现

用 Java 代码实现负载均衡的五种常见算法

CFS任务的负载均衡(框架篇)

几种简单的负载均衡算法及其Java代码实现

负载均衡,分布式,集群的理解,多台服务器代码如何同步

Nginx负载均衡