系统架构之负载均衡

Posted CodeFlight

tags:

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

系统架构之负载均衡

7 层负载均衡,对应的是 http 的 7 层协议
4 层负载均衡对应的是 tcp 的 4 层协议
nginx 现在也支持 4 层协议

核心概念

二层负载均衡

通过改写报文的目标 MAC 地址为上游服务器 MAC 地址,源 IP 地址和目标 IP 地址是没有变的,负载均衡服务器和真实服务器共享同一个 VIP,如LVS DR工作模式

三层负载均衡

一般采用虚拟 IP 地址方式,外部对虚拟的 IP 地址请求,负载均衡接收后分配后端实际的 IP 地址响应。(即一个 ip 对一个 ip 的转发, 端口全放开)

四层负载均衡

根据端口将报文转发到上游服务器(不同的 IP 地址 + 端口),如 LVS NAT 模式、HaProxy

在三次负载均衡的基础上,即从第四层“传输层”开始, ****使用“虚拟 ip + port”接收请求,再转发到对应的机器****。四层通过虚拟 IP + 端口接收请求,然后再分配到真实的服务器

七层负载均衡

是根据端口号和应用层协议如 HTTP 协议的主机名、URL,转发报文到上游服务器(不同的 IP 地址+端口),如 HaProxy、Nginx

LVS DR 工作模式

工作在数据链路层,LVS 和上游服务器共享同一个 VIP,通过改写报文的目标 MAC 地址为上游服务器 MAC 地址实现负载均衡,上游服务器直接响应报文到客户端,不经过 LVS,从而提升性能

但是 LVS 和上游服务器必须在同一个子网,为了解决跨子网问题而又不影响负载性能,可以选择在 LVS 后边挂 HaProxy,通过四层到七层负载均衡器 HaProxy 集群来解决跨网和性能问题

DNS + LVS + NGINX + REAL-SERVER 四层负载均衡

负载均衡要素

  • 上游服务器配置:使用 upstream server 配置上游服务器
  • 负载均衡算法:配置多个上游服务器时的负载均衡机制
  • 失败重试机制:配置当超时或上游服务器不存活时,是否需要重试其他上游服务器
  • 服务器心跳检查:上游服务器的健康检查

总结其俩就是,负载均衡、故障转移、失败重试、容错、健康检查

上游服务器配置

upstream backend {
    server [ip]:[port] [weight=1];
}

负载均衡算法

  • round-robin
  • ip_hash
  • hash key [consistent]
  • least_conn
upstream backend {
    # round-robin
    # ip_hash
    # hash key [consistent]
    # least_conn
    server [ip]:[port] [weight=1];
}

失败重试

upstream backend {
    server [ip]:[port] [weight=1] max_fails=2 fail_timeout=10s;
}

通过配置上游服务器的 max_fails 和 fail_timeout,来指定每个上游服务器,当 fail_timeout 时间内失败了 max_fails 次请求,则认为该上游服务器不可用/不存活,然后将摘掉该上游服务器,fail_timeout 时间后会再次将该服务器加入到存活上游服务器列表进行重试

location /test {
    proxy_connect_timeout 5s;
    proxy_read_timeout 5s;
    proxy_send_timeout 5s;
    # 遇到配置错误时,会重试下一台上游服务器
    proxy_next_upstream error timeout;
    proxy_next_upstream_timeout 10s;
    proxy_next_upstream_tries 2;
    proxy_pass http://backend;
    add_header upstream_addr $upstream_addr
}

健康检查

Nginx 对上游服务器的健康检查默认采用的是惰性策略,可以使用 nginx_upstream_check_module 模块来进行主动健康检查

TCP检查

upstream backend {
    server 192.168.1.1:8090 weight=1;
    check interval=3000 rise=1 fall=3 timeout=2000 type=tcp;
}
  • interval: 检测间隔时间
  • fall:检测失败多少次后,上游服务器被标识为不存活
  • rise:检测充公多少次后,上游服务器被标识为存活,并可以处理请求
  • timeout:检测请求超时时间配置

HTTP 检查

upstream backend {
    server 192.168.1.1:8090 weight=1;
    check interval=3000 rise=1 fall=3 timeout=2000 type=http
    check_http_send "HEAD /status HTTP/1.0\\r\\n\\r\\n";
    check_http_expect_alive http_2xx http_3xx;
}
  • check_http_send:即检查时发的 HTTP 请求内容
  • check_http_expect_alive:当上游服务器返回匹配的响应状态码时,则认为上游服务器存活

备份上游服务器

upstream backend {
    server [ip]:[port] [weight=1];
    server [ip]:[port] [weight=1] backup;
}

使用场景:对上游服务器进行压测时,要摘掉一些上游服务器进行压测,但是为了保险起见会配置一些后备上游服务器,当压测的上游服务器都挂掉时,流量可以转发到备用上游服务器,从而不影响用户请求处理

不可用上游服务器

upstream backend {
    server [ip]:[port] [weight=1];
    server [ip]:[port] [weight=1] down;
}

长连接

upstream backend {
    server [ip]:[port] [weight=1];
    server [ip]:[port] [weight=1] backup;
    keepalive 100;
}
location / {
    # 支持keep-alive
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_pass http://backend;
}

如果是http/1.0,则需要配置发送“Connection: Keep-Alive”请求头

建议

  • 空闲连接池太小,链接不够用,需要不断建链接
  • 空闲链接池太大,空闲链接太多,还没有使用就超时

建议对于小报文开启长连接

HTTP 反向代理

# 全局配置(proxy cache)
proxy_buffering on;
proxy_buffer_size 4;
proxy_buffers 512 4k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_cache_lock on;
proxy_cache_lock_timeout 200ms;
proxy_temp_path /tmpfs/proxy_temp;
proxy_cache_path /tmp/fs/proxy_cache levels=1:2 keys_zone=cache:512m inactive=5m max_size=8g;
proxy_connect_timeout 3s;
proxy_read_timeout 5s;
proxy_send_timeout 5;
# location 配置
# 请求上游服务器使用 GET 方法(不管请求是什么方法)
proxy_method GET;
# 不给上游服务器传递请求体
proxy_pass_request_body off;
# 不给上游服务器传递请求头
proxy_pass_request_headers off;
# 设置上游服务器的哪些响应头不发送给客户端
proxy_hide_header Vary;
# 支持 keep-alive
proxy_http_version 1.1;
proxy_set_header Connect "";
# 给上游服务器传递 Referer、Cookie 和 Host(按需传递)
proxy_set_header Referer $http_referer;
proxy_set_header Coolie $http_cookie;
proxy_set_header Host web.c.3.local;
proxy_pass http://backend /$1$is_args$args;
# gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 16 16k;
gzip_http_version 1.0;
gzip_proxied any;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css application/xml;
gzip_vary on;

对于内容型响应建议开启 gzip,gzip_comp_lever 压缩级别要根据实际压测来决定(带宽和吞度量之间的抉择)

HTTP 动态负载均衡

Nginx 四层负载均衡

./configure --prefix=/usr/servers --with-stream
stream {
    upstream mysql_backend {
        ......
    }
    server {
        ......
    }
}

ref: 亿级流量网站架构核心技术

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

大型网站系统架构实践http层负载均衡之haproxy实践篇

Linux架构之Nginx 七层负载均衡

高性能负载均衡之分类架构

应用架构设计之学习路线

玩转Linux系统之搭建Nginx+Tomcat群集实现负载均衡

系统架构——负载均衡整理总结