Nginx架构四之七层负载均衡
Posted yangyanping20108
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx架构四之七层负载均衡相关的知识,希望对你有一定的参考价值。
负载均衡概念
负载均衡(Load balancing)在不同的领域有不同的概念。其基本概念是为了减轻某个或某些实体的负载,将任务通过某种策略分配到多个实体上去,实现负载在不同实体间的平衡。
七层负载均衡
七层就是基于URL等应用层信息的负载均衡。从第七层"应用层"开始,根据虚拟的url或IP,主机名接收请求,再转向相应的处理服务器。七层负载均衡器也称作七层交换机,即L7 switch(七层交换),OSI的最高层,应用层。此时,该Load Balancer能理解应用协议。如:HAProxy、nginx等。
四层负载均衡
四层就是基于IP+端口的负载均衡,是在三次负载均衡的基础上,即从第四层"传输层"开始,使用"ip+port"接收请求,再转发到对应的机器。四层负载均衡器也称作四层交换机,即L4 switch(四层交换),在OSI第4层工作,此种Load Balance不理解应用协议(如HTTP/FTP/mysql等等)。如:LVS、F5、深信服AD等。
四层负载均衡场景
以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。
实现四层负载均衡的有:
- F5:硬件负载均衡器,功能很好,但是成本很高。
- lvs:重量级的四层负载均衡软件
- haproxy:模拟四层、七层转发,较灵活
参考:负载均衡(四层) LVS
四层负载均衡特点
-
四层负载均衡仅能转发TCP/IP协议、UDP协议、通常用来转发端口,如:tcp/22、udp/53;
-
四层负载均衡可以用来解决七层负载均衡端口限制问题;(七层负载均衡最大使用65535个端口号)
-
四层负载均衡可以解决七层负载均衡高可用问题;(多台后端七层负载均衡能同时的使用)
-
四层的转发效率比七层的高得多,但仅支持tcp/ip协议,不支持http和https协议;
-
通常大并发场景通常会选择使用在七层负载前面增加四层负载均衡。
四层和七层负载均衡的区别
- 四层负载均衡数据包是在底层就进行了分发,而七层负载均衡数据包则在
最顶端进行分发,所以四层负载均衡的效率比七层负载均衡的要高。 - 四层负载均衡不识别域名,而七层负载均衡识别域名。
Nginx七层负载均衡
Nginx要实现七层负载均衡需要用到proxy_pass代理模块配置。Nginx默 认安装支持这个模块,我们不需要再做任何处理。Nginx的负载均衡是 在Nginx的反向代理基础上把用户的请求根据指定的算法分发到一组 【upstream虚拟服务池】。
upstream指令
该指令是用来定义一组服务器,它们可以是监听不同端口的服务器,并 且也可以是同时监听TCP和Unix socket的服务器。服务器可以指定不同 的权重,默认为1。
语法 | upstream name … |
---|---|
默认值 | — |
位置 | http |
server指令
该指令用来指定后端服务器的名称和一些参数,可以使用域名、IP、端
口或者unix socket。
语法 | server name [paramerters] |
---|---|
默认值 | — |
位置 | upstream |
实现流程
Nginx负载均衡
我们搭建一个测试环境,部署三个web应用,分别为serverA , serverB,serverC,并在hosts文件中配置测试域名。
127.0.0.1 www.test-nginx.com
- serverA 的访问地址
http://www.test-nginx.com:9091/web/hello
输出内容:hello,I am server A ! - serverB 的访问地址
http://www.test-nginx.com:9092/web/hello
输出内容:hello,I am server B ! - serverC 的访问地址
http://www.test-nginx.com:9093/web/hello
输出内容:hello,I am server C !
服务端设置
server
listen 9091;
server_name localhost;
default_type "text/plain;charset=utf-8";
return 200 "hello,I am server A !";
server
listen 9092;
server_name localhost;
default_type "text/plain;charset=utf-8";
return 200 "hello,I am server B !";
server
listen 9093;
server_name localhost;
default_type "text/plain;charset=utf-8";
return 200 "hello,I am server C !";
负载均衡设置
upstream myweb
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
负载均衡状态
代理服务器在负责均衡调度中的状态有以下几个:
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后, 服务暂停时间 |
max_conns | 限制最大的接收连接数 |
down
将该服务器标记为永久不可用,那么该代理服务器将不参与负载 均衡。
upstream myweb
server 127.0.0.1:9091 down;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
发送10次请求访问地址:http://www.test-nginx.com/proxy/hello,输出如下:
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
backup
将该服务器标记为备份服务器,当主服务器不可用时,将用来传 递请求。
upstream myweb
server 127.0.0.1:9091 down;
server 127.0.0.1:9092 backup;
server 127.0.0.1:9093;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
max_conns
max_conns=number:用来设置代理服务器同时活动链接的最大数量, 默认为0,表示不限制,使用该配置可以根据后端服务器处理请求的并发 量来进行设置,防止后端服务器被压垮。
max_fails和fail_timeout
max_fails=number:设置允许请求代理服务器失败的次数,默认为1。
fail_timeout=time:设置经过max_fails失败后,服务暂停的时间,默认 是10秒。
upstream myweb
server 127.0.0.1:9091 down;
server 127.0.0.1:9092 backup;
server 127.0.0.1:9093 max_fails=1 fail_timeout=10;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
负载均衡策略
介绍完Nginx负载均衡的相关指令后,我们已经能实现将用户的请求分 发到不同的服务器上,那么除了采用默认的分配方式以外,我们还能采 用什么样的负载算法?
Nginx的upstream支持如下六种方式的分配算法,分别是:轮询,加权轮询,Ip hash。下面我们对其一一进行演示。
1. 轮询(默认)
是upstream模块负载均衡默认的策略。每个请求会按时间顺序逐个分配 到不同的后端服务器。轮询不需要额外的配置。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
worker_processes 4;
events
worker_connections 1024;
http
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
keepalive_timeout 65;
#设置虚拟主机的基本信息
upstream myweb
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
location /
root html;
index index.html index.htm;
error_page 500 502 503 504 /50x.html;
location = /50x.html
root html;
发送10次请求访问地址:http://www.test-nginx.com/proxy/hello,输出如下:
hello,I am server A !
hello,I am server B !
hello,I am server C !
hello,I am server A !
hello,I am server B !
hello,I am server C !
hello,I am server A !
hello,I am server B !
hello,I am server C !
hello,I am server A !
2. 加权轮询
weight=number:用来设置服务器的权重,默认为1,权重数据越大,被 分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的 后端服务器硬件配置进行调整的,此策略比较适合服务器的硬件配 置差别比较大的情况。
upstream myweb
server 127.0.0.1:9091 weight=1;
server 127.0.0.1:9092 weight=2;
server 127.0.0.1:9093 weight=2;
发送10次请求访问地址:http://www.test-nginx.com/proxy/hello,输出如下:
hello,I am server A !
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
hello,I am server A !
hello,I am server B !
hello,I am server C !
hello,I am server B !
hello,I am server C !
3. Ip hash 算法
当对后端的多台动态应用服务器做负载均衡时,ip_hash指令能够将某个 客户端IP的请求通过哈希算法定位到同一台后端服务器上。这样,当来 自某一个IP的用户在后端Web服务器A上登录后,在访问该站点的其他 URL,能保证其访问的还是后端web服务器A。每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
upstream myweb
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
ip_hash;
发送10次请求访问地址:http://www.test-nginx.com/proxy/hello,输出如下:
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
4. least_conn
最少连接,把请求转发给连接数较少的后端服务器。轮询算法是把请求 平均的转发给各个后端,使它们的负载大致相同;但是,有些请求占用 的时间很长,会导致其所在的后端负载较高。这种情况下,least_conn 这种方式就可以达到更好的负载均衡效果。
upstream myweb
least_conn;
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
...
5. fair(第三方)
fair采用的不是内建负载均衡使用的轮换的均衡算法,而是可以根据页面 大小、加载时间长短智能的进行负载均衡。那么如何使用第三方模块的 fair负载均衡策略。需要使用nginx-upstream-fair-master 插件。
下载:nginx-upstream-fair-master。
使用./configure命令将资源添加到Nginx模块中
./configure --add-module=/Users/yangyanping/Downloads/soft/nginx-upstream-fair-master
编译,编译可能会出现如下错误,ngx_http_upstream_srv_conf_t结构中缺少 default_port
make
解决方案:
在Nginx的源码中 src/http/ngx_http_upstream.h,找到 ngx_http_upstream_srv_conf_s ,在模块中添加添加default_port属性
struct ngx_http_upstream_srv_conf_s
ngx_http_upstream_peer_t peer;
void **srv_conf;
ngx_array_t *servers; /* ngx_http_upstream_server_t */
ngx_uint_t flags;
ngx_str_t host;
u_char *file_name;
ngx_uint_t line;
in_port_t port;
in_port_t default_port;
ngx_uint_t no_port; /* unsigned no_port:1 */
#if (NGX_HTTP_UPSTREAM_ZONE)
ngx_shm_zone_t *shm_zone;
#endif
;
fair 配置
upstream myweb
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
fair;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
...
6. url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务 器,要配合缓存命中来使用。同一个资源多次请求,可能会到达不同的 服务器上,导致不必要的多次下载,缓存命中率不高,以及一些资源时 间的浪费。而使用url_hash,可以使得同一个url(也就是同一个资源请求)会到达同一台服务器,一旦缓存住了资源,再此收到请求,就可以从缓存中读取。按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。
upstream myweb
hash $request_uri;
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
.....
发送10次请求访问地址:http://www.test-nginx.com/proxy/hello,输出如下:
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
hello,I am server A !
Nginx实现热备
负载均衡的server中常见配置
upstream myweb
ip_hash;
server 127.0.0.1:9091;
server 127.0.0.1:9092 down; (down 表示当前的server暂时不参与负载)
server 127.0.0.1:9093 weight=2; (weight 默认为1.weight越大,负载的权重就越大)
server 127.0.0.1:9094 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器)
我们配置serverC端口为备份服务器,当serverA 和 serverB 都挂掉后 会自动使用备份服务器server C(9093端口),但当主服务器serverA 或serverB又启动后,在继续使用主服务器serverA 或serverB,nginx.conf配置如下:
upstream myweb
server 127.0.0.1:9091;
server 127.0.0.1:9092;
server 127.0.0.1:9093 backup;
server
listen 80;
server_name localhost;
location /proxy/
proxy_pass http://myweb/web/;
访问地址:http://www.test-nginx.com/proxy/hello 10次输出结果如下,从中可以看出请求未访问到serveC (server 127.0.0.1:9093)。
hello,I am server A !
hello,I am server B !
hello,I am server A !
hello,I am server B !
hello,I am server A !
hello,I am server B !
hello,I am server A !
hello,I am server B !
hello,I am server A !
hello,I am server B !
主动停掉server A(9091端口),再次发送10次请求,10次输出结果如下:
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
再主动停掉serverB(9092端口),再次发送10次请求,10次输出结果如下,主服务器serverA和serverB均已宕机,客户端请求都访问到备份服务器serverC。
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
hello,I am server C !
启动主服务器 serverB后,再次发送10次请求,10次输出结果如下,主服务器serverB已启动,客户端请求会优选访问主服务器,所以请求都会访问到主服务器serverB。
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
hello,I am server B !
proxy_pass详解
在Nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。
假设下面四种情况分别用 http://127.0.0.1/proxy/hello 进行访问。
- 第一种配置,代理URL:http://127.0.0.1:9091/hello
location /proxy/
proxy_pass http://127.0.0.1:9091/
- 第二种配置,代理URL:http://127.0.0.1:9091/proxy/hello
location /proxy/
proxy_pass http://127.0.0.1:9091
- 第三种配置,代理URL:http://127.0.0.1:9091/web/hello
location /proxy/
proxy_pass http://127.0.0.1:9091/web/
- 第三种配置,代理URL:http://127.0.0.1:9091/webhello
location /proxy/
proxy_pass http://127.0.0.1:9091/web
MVC测试代码
@RestController
public class HelloController
@GetMapping("/web/hello", "webhello")
public String hello()
return "hello,I am server A!";
企业运维之七层负载均衡--Haproxy
企业运维之七层负载均衡--Haproxy
1. 基础介绍
https://www.haproxy.org/
(官方网站)
https://www.haproxy.org/download/1.8/src/haproxy-1.8.14.tar.gz
(下载地址)
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架构中, 同时可以保护你的web服务器不被暴露到网络上。
HAProxy实现了一种事件驱动, 单一进程模型,此模型支持非常大的并发连接数。
第七层是 web 内容交换技术,即对访问流量的高层控制方式,通过对应用层内容的切换,将这种真正有意义的信息,结合我们对负载均衡设备的特定设置,进行服务器的选择。七层负载均衡是在四层的基础上做的,它可以根据七层的特定信息决定如何转发流量以及选择服务器实现负载均衡。
考虑到为了不造成访问流量的停滞,第七层交换技术更具优势。在接收到数据包时,它会检查Http报头,根据报头内的数据来决定将信息发送给哪台服务器,同时根据报头提供的信息判断用何种方式为个人信息或者图像视频等不同格式的内容提供服务。Http请求URL,但通过 web 内容交换技术,Http有可能请求到不同的服务器,即同一个URL请求对应了多个服务器,因为在Http发出请求时,并非建立了一个会话,而是通过负载均衡服务器建立了多个会话与真实的服务器连接。
2. 负载均衡的类型
- 无负载均衡:没有负载平衡的简单 Web 应用程序环境可能如下所示;
用户直接连接到Web服务器,在web 服务器上,没有负载平衡。如果单个Web服务器出现故障,用户将无法再访问到Web服务器。此外,如果许多用户试图同时访问服务器并且无法处理负载,他们可能会遇到缓慢的体验,或者可能根本无法连接。
- 4层负载均衡
将网络流量负载平衡到多个服务器的最简单方法是使用第4层(传输层)负载均衡。以这种方式进行负载均衡将根据 IP 范围和端口转发用户流量(即,如果请求访问web 服务器,则流量将转发到处理web 请求的后端。端口80)。
第四层交换功能的实现,也就是虚拟IP 地址( VIP) 方法,这个地址并不是与特定的计算机相连,也没有与计算机中的网络接口卡相连。它的实现过程是当数据包发送到这个VIP 地址时,通过第四层交换功能,并根据设定好的调度算法分配到一个真实的网络接口。每次TCP 请求都可以动态分配其中的一个IP 地址,从而达到负载均衡。
四层负载均衡,主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的后端服务器。
用户访问负载均衡器,负载均衡器将用户的请求转发给后端服务器的Web后端组。无论选择哪个后端服务器,都将直接响应用户的请求。通常,Web后端中的所有服务器应该提供相同的内容 - 否则用户可能会收到不一致的内容。
- 七层负载均衡
7层负载均衡是更复杂的负载均衡网络流量的方法是使用第7层(应用层)负载均衡。使用第7层允许负载均衡器根据用户请求的内容将请求转发到不同的后端服务器。这种负载均衡模式允许在同一域和端口下运行多个Web应用程序服务器。
七层负载均衡,也称为“内容交换”,主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的后端服务器。
注:一般4层 lvs 的性能好一点,但是七层 haproxy 可以做具体的策略,所以企业中一般是四层和七层负载均衡结合使用,也就是lvs->haproxy->rs。
3. Haproxy 的部署
实验环境:server1作为调度器,server2和server3作为后端的真实服务器。
3.1 Haproxy 实现负载均衡和监控
- 七层调度器是支持端口转发且自带健康检测的,首先在调度器上安装
haproxy
服务;
编辑配置文件,修改内核的最大连接数系统的最大连接数。
因为文件中的最大连接数为4000,而系统默认最大为1024。操作系统的最大允许操作数必须也做出改变。所以需要编辑/etc/security/limits.conf
文件,修改操作系统最大可操作文件数量。
[root@server1 ~]# yum install -y haproxy
[root@server1 ~]# cd /etc/haproxy/
[root@server1 haproxy]# id haproxy
uid=188(haproxy) gid=188(haproxy) groups=188(haproxy)
[root@server1 haproxy]# sysctl -a |grep file
fs.file-max = 200070
fs.file-nr = 928 0 200070
fs.xfs.filestream_centisecs = 3000
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.eth0.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
[root@server1 haproxy]# vim /etc/security/limits.conf
haproxy - nofile 4096
#在文件最后一行加入表示文件数为4096;表示对haproxy 服务用户做修改,默认为1024,-表示软硬权限一致
- 在
/etc/haproxy/
目录下,编辑haproxy.cfg
文件,内容如下
配置文件中global
表示全局配置段;defaults
表示默认配置段;
[root@server1 haproxy]# vim haproxy.cfg
60 stats uri /status #在default区域添加监控
63 frontend main *:80 #负载均衡器端采监听80端口
64 # acl url_static path_beg -i /static /images /javascript /sty lesheets
65 # acl url_static path_end -i .jpg .gif .png .css .js
66 #
67 # use_backend static if url_static
68 default_backend app #默认访问的服务器组是app组
73 #backend static
74 # balance roundrobin
75 # server static 127.0.0.1:4331 check
80 backend app
81 balance roundrobin ##轮询方式为加权轮询
82 server app1 172.25.105.2:80 check
83 server app2 172.25.105.3:80 check
[root@server1 haproxy]# systemctl start haproxy
[root@server1 haproxy]# netstat -antlp | grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10223/haproxy
此时在网页访问http://172.25.105.1/status
可以看到监控信息;
访问http://172.25.105.1/
时可以看到负载均衡现象,也可以用 curl 172.25.105.1
来测试;
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server3
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server3
此时如果关闭一个后端,haproxy 是有健康检查的,会自动识别到。
这种直接可以看到监控信息相对来说是不太安全的,可以对其加对应的验证:
[root@server1 haproxy]# vim haproxy.cfg
60 stats uri /status
61 stats auth admin:zxk
[root@server1 haproxy]# systemctl restart haproxy
此时再次访问:http://172.25.105.1/status
时便有认证;
3.2 日志采集
默认日志是存放在/var/log/messages
下,为了方便查看用户访问时产生的日志,可以编辑/etc/rsyslog.conf
文件,内容如下所示:
[root@server1 haproxy]# vim /etc/rsyslog.conf
14 # Provides UDP syslog reception
15 $ModLoad imudp #开启日志的传输格式UDP
16 $UDPServerRun 514
73 local7.* /var/log/boot.log
74 local2.* /var/log/haproxy.log
#表示local2的所有日志存放在后面的文件中
[root@server1 haproxy]# systemctl restart rsyslog
此时重启之后还没有生成日志文件/var/log/haproxy.log
,需要经过访问几次然后才会生文件。
[root@server1 haproxy]# ll /var/log/haproxy.log
-rw------- 1 root root 12222 Jul 11 22:11 /var/log/haproxy.log
[root@server1 haproxy]# tail -n3 /var/log/haproxy.log
Jul 11 22:10:49 localhost haproxy[11761]: Proxy app started.
Jul 11 22:10:54 localhost haproxy[11762]: 172.25.105.250:45398 [11/Jul/2021:22:10:54.750] main main/<STATS> -1/-1/-1/-1/0 401 262 - - PR-- 0/0/0/0/0 0/0 "GET /status HTTP/1.1"
Jul 11 22:11:11 localhost haproxy[11762]: 172.25.105.250:45400 [11/Jul/2021:22:11:11.300] main main/<STATS> 0/0/0/0/0 200 14104 - - LR-- 1/1/0/0/0 0/0 "GET /status HTTP/1.1"
3.3 调度算法
- source 算法
前面负载时,使用默认的 rr 轮询调度的算法;
修改调度算法为 source,该算法通过在静态散列表中查看源 ip 来给真正的服务器分派请求,当来源 ip 不变时,只要后端的页面还在,就不会调度的其他的页面。当 IP 不变,当后端页面找不到时才会调度到其他的页面。
[root@server1 haproxy]# vim haproxy.cfg
82 backend app
83 #balance roundrobin
84 balance source
85 server app1 172.25.105.2:80 check
86 server app2 172.25.105.3:80 check
[root@server1 haproxy]# systemctl reload haproxy
- 设置权重
对于某一个性能比较好的后端服务器,可以较多的分发一些请求;
[root@server1 haproxy]# vim haproxy.cfg
82 backend app
83 balance roundrobin
84 #balance source
85 server app1 172.25.105.2:80 check weight 2
86 server app2 172.25.105.3:80 check
[root@server1 haproxy]# vim haproxy.cfg
[root@server1 haproxy]# systemctl reload haproxy
测试时效果如下:
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server3
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server2
[root@westos ~]# curl 172.25.105.1
server3
3.5 设定备机
当后端两个服务器都挂掉之后,此时可以用备机来提示访问问题,而不是将错误的信息返回给用户;
[root@server1 haproxy]# vim haproxy.cfg
82 backend app
83 balance roundrobin
84 #balance source
85 server app1 172.25.105.2:80 check weight 2
86 server app2 172.25.105.3:80 check
87 server backup 172.25.105.1:8080 backup #本机的8080端口
[root@server1 haproxy]# vim /etc/httpd/conf/httpd.conf
#修改本机的http的默认端口为8080
41 #Listen 12.34.56.78:80
42 Listen 8080
[root@server1 haproxy]# cat /var/www/html/index.html
Sorry ! Please try again later!!
[root@server1 haproxy]# systemctl start httpd
[root@server1 haproxy]# systemctl reload haproxy
[root@server1 haproxy]# netstat -antulp| grep :80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 14612/haproxy
tcp6 0 0 :::8080 :::* LISTEN 14619/httpd
此时访问:http://172.25.105.1/status
可以看到备机信息。
此时当其他的都停掉之后,才会访问到备机,生产中备机应该只提示错误信息,让用户不在来访问。
4. Haproxy的访问控制
4.1 通过调度器访问不同后端
- 编辑
haproxy.cfg
文件,开放访问策略。
用户访问时,以/static /images /javascript /stylesheets
开头,以.jpg .gif .png .css .js
结尾的访问请求,被转到后端默认的服务器组上;否则就转发到 app 服务器组上;
[root@server1 haproxy]# vim haproxy.cfg
65 frontend main *:80
66 acl url_static path_beg -i /static /images /javascript /stylesheets
67 acl url_static path_end -i .jpg .gif .png .css .js
68
69 use_backend static if url_static
70 default_backend app
75 backend static
76 balance roundrobin
77 server static 172.25.105.3:80 check
82 backend app
83 balance roundrobin
84 server app1 172.25.105.2:80 check
[root@server1 haproxy]# systemctl reload haproxy
给server3加信息,此时在访问http://172.25.105.1/images/vim.jpg
时才能访问到图片信息;
[root@server3 ~]# mkdir /var/www/html/images
[root@server3 ~]# ls
vim.jpg
[root@server3 ~]# mv vim.jpg /var/www/html/images/
[root@server3 ~]# cd /var/www/html/images/
[root@server3 images]# ls
vim.jpg
此时在访问:http://172.25.105.1/status,可以看到static和app的信息。
测试:
默认访问的是server2
,当以image
开头以.png.jpg
开始时,才可以匹配到server3
。
4.2 用户访问黑白名单设置
- 黑名单
源地址为172.25.105.250
时,请求会被禁止;
[root@server1 haproxy]# vim haproxy.cfg
66 frontend main *:80
67 acl url_static path_beg -i /static /images /javascript /stylesheets
68 acl url_static path_end -i .jpg .gif .png .css .js
69
70 acl blacklist src 172.25.105.250 #黑名单,来源
71 block if blacklist
72
73 use_backend static if url_static
74 default_backend app
75
[root@server1 haproxy]# systemctl restart haproxy
测试:
默认访问的是后端的app当为黑名单中的用户时,会默认禁止;其他用户可以正常访问。
[root@westos ~]# curl 172.25.105.1
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
[root@server3 ~]# curl 172.25.105.1
server2
[root@server2 ~]# curl 172.25.105.1
server2
同样还除了黑名单之外还有白名单;白名单的书写和黑名单类似,只需将blacklist
换为 whitelist
即可,后面接的IP或者网段即可为白名单;访问时白名单的用户会访问到后端app,不在白名单中的用户会被禁止。
- 重定向
以上设置黑白名单之后,此时直接返回错误值,过于暴力,不够友好,可以将其错误信息重定向一个错误返回页面。
[root@server1 haproxy]# vim haproxy.cfg
66 frontend main *:80
67 acl url_static path_beg -i /static /images /javascript /stylesheets
68 acl url_static path_end -i .jpg .gif .png .css .js
69
70 acl blacklist src 172.25.105.250
71 block if blacklist
72 errorloc 403 http://172.25.105.1:8080
73
74 use_backend static if url_static
75 default_backend app
[root@server1 haproxy]# systemctl restart haproxy
测试:对于命令的测试需要加参数-I
,因为curl 默认不会显示重定向的信息;
[root@westos ~]# curl 172.25.105.1 -I
HTTP/1.1 302 Found
Cache-Control: no-cache
Content-length: 0
Location: http://172.25.0.1:8080
也可以将其重定向至别的 网站门户;
[root@server1 haproxy]# vim haproxy.cfg
66 frontend main *:80
67 acl url_static path_beg -i /static /images /javascript /stylesheets
68 acl url_static path_end -i .jpg .gif .png .css .js
69
70 acl blacklist src 172.25.105.250
71 #block if blacklist
72 #errorloc 403 http://172.25.105.1:8080
73 redirect location http://www.baidu.com if blacklist
74
75 use_backend static if url_static
76 default_backend app
77
[root@server1 haproxy]# systemctl restart haproxy
此时在用户 172.25.105.250
访问服务器时会被重定向到百度。
4.3 读写分离
将读和写分别设定到不同的 RS上,编辑haproxy.cfg
文件,然后重新编辑匹配的策略;
当匹配到写的规则时,去访问后端的static 172.25.105.3:80
;当没有匹配到写的策略时会默认访问后端的app
。
[root@server1 haproxy]# vim haproxy.cfg
66 frontend main *:80
67 acl url_static path_beg -i /static /images /javascript /stylesheets
68 acl url_static path_end -i .jpg .gif .png .css .js
74 acl write method PUT
75 acl write method POST
79 use_backend static if write
80 default_backend app
85 backend static
86 balance roundrobin
87 server static 172.25.105.3:80 check
92 backend app
93 balance roundrobin
94 #balance source
95 server app1 172.25.105.2:80 check weight 2
96 #server app2 172.25.105.3:80 check
97 server backup 172.25.105.1:8080 backup
[root@server1 haproxy]# systemctl reload haproxy
在server3上测试php 是否成功安装;
[root@server3 ~]# yum install -y php
[root@server3 images]# cd /var/www/html/
[root@server3 html]# vim index.php
[root@server3 html]# cat index.php #php的发布页面可用测试php是否安装成功。
<?php
phpinfo()
?>
[root@server3 html]# systemctl restart httpd
在RS上安装php服务,在RS的 apache 默认发布目录下,写两个php文件以实现动态的写入;建立一个上传目录,设置该目录的权限为777;
[root@server2 ~]# yum install -y php
[root@server2 ~]# systemctl restart httpd #重启apache 会自动加载php信息
[root@server2 html]# vim upload_file.php
[root@server2 html]# cat upload_file.php #上传信息控制
<?php
if ((($_FILES["file"]["type"] == "image/gif") #文件格式
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
&& ($_FILES["file"]["size"] < 2000000)) #2M内的大小
{
if ($_FILES["file"]["error"] > 0)
{
echo "Return Code: " . $_FILES["file"]["error"] . "<br />";
}
else
{
echo "Upload: " . $_FILES["file"]["name"] . "<br />";
echo "Type: " . $_FILES["file"]["type"] . "<br />";
echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";
if (file_exists("upload/" . $_FILES["file"]["name"]))
{
echo $_FILES["file"]["name"] . " already exists. ";
}
else
{
move_uploaded_file($_FILES["file"]["tmp_name"],
"upload/" . $_FILES["file"]["name"]);
echo "Stored in: " . "upload/" . $_FILES["file"]["name"];
}
}
}
else
{
echo "Invalid file";
}
?>
[root@server2 html]# cat index.php ##php的发布页面
<html>
<body>
<form action="upload_file.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id负载均衡集群LVS算法搭建NAT模式LVS架构
Nginx+keepalived实现高可用集群 #yyds干货盘点#