Java架构师成长直通车:LVS+Nginx实现高可用集群

Coding Alan 5年前 (2020-01-01) 7792次浏览 0个评论 扫描二维码

LVS+Nginx实现高可用集群

主从复制高可用Redis集群

Redis缓存雪崩,穿透

常见问题

LVS+Nginx实现高可用集群

Nginx(engine x)是一个高性能的 HTTP 和反向代理web 服务器,同时也提供 IMAP/POP3/SMTP服务。

  • 反向代理
  • 通过配置文件实现集群和负载均衡
  • 静态资源虚拟化

常见服务器

  • MS IIS                        asp.net
  • Weblogic、Jboss       传统行业 ERP/物流/金融/电信
  • Tomcat、Jetty            J2EE
  • Apache、Nginx           静态服务、反向代理
  • Netty                           高性能服务器编程

Java架构师成长直通车:LVS+Nginx实现高可用集群

来源:Netcraft

安装 Nginx(CentOS)

Nginx HTTP服务知识大全

Nginx 核心知识

命令解释
–prefix指定nginx安装目录
–pid-path指向nginx的pid
–lock-path锁定安装文件,防止被恶意篡改或误操作
–error-log错误日志
–http-log-pathhttp日志
–with-http_gzip_static_module启用gzip模块,在线实时压缩输出数据流
–http-client-body-temp-path设定客户端请求的临时目录
–http-proxy-temp-path设定http代理临时目录
–http-fastcgi-temp-path设定fastcgi临时目录
–http-uwsgi-temp-path设定uwsgi临时目录
–http-scgi-temp-path设定scgi临时目录

Nginx 的进程模型

  • master 进程:主进程
  • worker 进程:工作进程

Java架构师成长直通车:LVS+Nginx实现高可用集群

Nginx 事件处理

使用了多路径复用器,在出现了阻塞时一个 worker 可以处理多个客户端请求

nginx.conf 配置结构

BIO:同步阻塞

NIO:同步非阻塞

AIO:异步非阻塞

nginx.conf 核心配置文件

参数名参数意义
$remote_addr客户端ip
$remote_user远程客户端用户名,一般为:’-’
$time_local通用日志格式的本地时间,例13/May/2019:08:30:23 +0800
$request请求方法,例 GET, POST
$status响应状态码,例200
$body_bytes_send响应内容字节数
$http_referer进入页面的前一个链接
$http_user_agent用户代理,可判定访问所使用的浏览器、客户端
$http_x_forwarded_for通过代理服务器来记录客户端的ip

静态文件两种配置方式(其中 xxx 为服务器中/home 下的静态文件目录名):

gzip 压缩配置示例

location的匹配规则

Hosts 文件管理工具(兼容多平台):SwitchHosts,通过它可避免手动去编辑系统 hosts 文件

Nginx 的跨域

CORS(Cross-Origin Resource Sharing)

解决跨域的方案Jsonp, SpingBoot Cors, Nginx

Nginx静态资源防盗链

Java架构师成长直通车:LVS+Nginx实现高可用集群

负载均衡

四层负载均衡

  • F5硬负载均衡(基于硬件)
  • LVS四层负载均衡
  • HAProxy 四层负载均衡
  • Nginx 四层负载均衡

七层负载均衡

  • Nginx 七层负载均衡
  • HAProxy 七层负载均衡
  •  Apache 七层负载均衡

DNS地域负载均衡

层级名称说明
第七层应用层与用户行为交互
第六层表示层定义数据格式以及数据加密
第五层会话层创建、管理以及销毁会话
第四层传输层创建、管理请求端到响应端(端到端)的连接
第三层网络层请求端的IP地址
第二层数据链路层提供介质访问与链路管理
第一层物理层传输介质,物理媒介

集群配置

本地集群可使用多台虚拟机,或直接在单台Linux机器上使用 Docker

我们连续启动了3个Docker

Jmeter

下载链接:https://jmeter.apache.org/download_jmeter.cgi

下载后 Windows 双击 jmeter.bat,macOS双击 jmeter 执行文件即可打开可视化窗口

1、测试计划>线程组:配置线程(用户)数和循环次数

2、线程组>采样器>HTTP 请求:配置请求的域名、端口等

3、测试计划>监听器:添加查看结果树聚合报告用表格查看结果

着重对比单机和集群的异常率(聚合报告),以了解所能负载的用户数,一般超过20%即超出了异常极限

负载均衡 – 轮询、权重

负载均衡默认使用轮询,平均逐一分配给集群内的服务器;可通过配置来设置加权轮询

upstream指令参数

更多内容参见:官方文档,其中各参数的配置方法同上述的 weight,以下设置均位于 upstream 中

  • max_conns
    限制一台服务器的最大连接数,在有多个 worker 进程时因共享内存实际会超出
    默认为0,不做任何限制
    通过将 worker 设置为1,使用 Jmeter 可进行测试(线程组Ramp-Up 时间设置为0)
    示例:server 172.17.0.2:8080 max_conns=2;
  • slow_start
    让服务器缓慢加入集群,配合 weight 使用,当前仅适用于商业版
    示例:server 172.17.0.4:8080 weight=5 slow_start=60s;
  • down
    标识服务器为不可用
    示例:server 172.17.0.2:8080 down;
  • backup
    标识服务器为备用服务器,在主服务器都挂掉时启用
    示例:server 172.17.0.2:8080 backup;
  • max_fails
    fail_timeout所设置时间内失败尝试次数,默认值为1,若达到失败尝试上限次数,则判定为宕机
  • fail_timeout
    配合 max_fails 使用,默认为10秒,对判定为宕机的服务在达到 fail_timeout 的时长后会重新尝试连接
    示例:server 172.17.0.2:8080 backup max_fails=2 fail_timout=10s;

keepalive吞吐量,用于设置长连接处理的数量

示例:keepalive 32;

对于 http,还应进行如下设置(location 内):

负载均衡 – ip_hash

hash 算法:用户ip哈希对服务端节点数取模获取下标:

hash(ip) % node_counts = index

数据库分表哈希算法同理,如将 ip 替换为 pid

配置:

nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c

根据以上 Nginx 的源码文件可以分析出 ip_hash实际上取的是 IP 的前3段,因此通过内网(如hash( 192 168 1 ))将访问同一台主机。

注意:使用 ip_hash 如果有服务器出现故障不能直接移除,而是应将其标记为 down

一致性哈希算法

ip_hash 在有节点宕机时节点数就会发生变化,自然所有下标也即访问的主机也会发生变化 。这样用户会丢失原有的 session,缓存无效,基于这一缺点引入了一致性哈希算法。

Java架构师成长直通车:LVS+Nginx实现高可用集群

一致性哈希算法在0到232-1之间,根据用户和服务器节点的哈希值按顺时针就近原则决定用户所访问的服务器节点,这样不论是增加服务器节点还是减少服务器节点,都只有少数用户受到影响,并且依然保持相同的原则。

负载均衡 – url_hash,least_conn

url_hash 是根据请求 url 进行哈希,然后与节点数取模得出下标

hash(url) % node_counts = index

url_hash 在 url 发生变化时(如请求链接后多一个/)请求的服务器就会发生变化

least_conn 是最小连接数,实际含义是将请求发送到 连接数/权重 值最小的服务器上,以避免有些服务器节点出现闲置的状况:

缓存

  • 静态资源缓存浏览器
    expires 指令
  • 上游服务器资源缓存到 Nginx端

Nginx配置SSL(HTTPS)

首先要确定 Nginx有没安装了ssl 模块

配置示例

动静分离

  • 分布式
  • 前后端解耦
  • 静态归 Nginx
  • 接口服务化

静态数据:css/js/html/images/audios/videos/…

动态数据:得到的响应可能会和上一次不同

实现方式

  • CDN:将静态资源放到第三方CDN 平台
  • Nginx:将静态资源放到 Nginx 服务器或上游集群服务器

动静分离的问题

  • 跨域
    • SpringBoot
    • Nginx
    • Jsonp
  • 分布式会话
    • 分布式缓存中间件Redis

Nginx高可用HA

主、备 Nginx

Keepalived:

  • 解决单点故障
  • 组件免费
  • 可以实现高可用HA机制
  • 基于VRRP协议(Virtual Router Redundancy Protocol)
    • 解决内网单机故障的路由协议
    • 构建有多个路由器 MASTER BACKUP
    • 虚拟 IP – VIP(Virtual IP Address)

Keepalived安装

下载地址:keepalived.org

以当前版本2.0.19为例:

主要配置

启动和关闭服务

本地测试可通过绑定hosts 文件指向虚拟 IP 地址,备服参照主服配置,state 设置为BACKUP、权重设置低于主服务器即可

编写检测脚本/etc/keepalived/check_nginx_alive_or_not.sh,在 Nginx 中断时自动启动服务:

添加配置

Keepalived 双主热备

以上使用的Keepalived 双机主备一个主要的缺点是在MASTER 运行正常的情况下,从服务器将保持闲置的状态,因此让我们来了解一下双主热备,即互为主备:

通过设置多个虚拟 IP 并使用 DNS 轮询的方式实现(阿里、腾讯等平台的域名解析中均可将A记录如 www 解析到不同域名并设置权重)

配置类似前面,将原有的配置拷贝一份,比如在备用服务器上再使用另一个虚拟 IP 配置其为主服务器:

相应地原主服务器也需要再进行一份备用服务器的配置

Java架构师成长直通车:LVS+Nginx实现高可用集群

LVS负载均衡

  • Linux Virtual Server
  • 章文嵩博士主导的开源负载均衡项目
  • LVS(ipvs)已被集成到 Linux 内核中
  • 负载均衡调度器(四层)

官方网站:http://linux-vs.org/

为什么要使用LVS+Nginx?

  • LVS基于四层,工作效率高
  • 单个 Nginx 承受压力有限,需要集群
  • LVS 充当 Nginx集群的调度者
  • Nginx 接受请求来回,LVS 可以只接受不响应

LVS 的三种模式

  • NAT
    请求通过 LVS,响应通过 LVS
  • TUN
    请求(上行)经过 LVS,响应(下行)不经过 LVS,每个节点必须要有网卡,节点对公网暴露
  • DR(Direct Routing)
    请求经过 LVS,响应通过路由,推荐使用Java架构师成长直通车:LVS+Nginx实现高可用集群

LVS DR模式搭建

服务器示例如图所示

VIP:虚拟 IP

RIP:真实服务器 IP

注:云服务器需购买负载均衡或虚拟 IP 才可实现配置, Nginx 服务器配置对应本地回环(lo)的原因是其处理响应

LVS-DR模式的其它配置

arp-ignore:ARP 响应级别(处理请求)

  • 0:只要本机配置了 ip,就能响应请求
  • 1:请求的目标地址到达对应的网络接口,才会响应请求

推荐配置为1

arp-announce:ARP通告行为(返回响应)

  • 0:本地上任何网络接口都向外通告,所有的网卡都能接收到通告
  • 1:尽可能避免本网卡与不匹配的目标进行通告
  • 2:只在本网卡通告

推荐配置为2

LVS配置

-A:添加集群
-t:tcp协议
ip地址:设定集群的访问ip,也就是LVS的虚拟ip
-s:设置负载均衡的算法,rr表示轮询
-p:设置连接持久化的时间,默认300秒
-a:添加真实服务器
-r:真实服务器的ip地址
-g:设定DR模式

Keepalived+LVS高可用

在主备 LVS 服务器上安装 Keepalived,方法参见上方Keepalived安装

以上即实现了高可用的 LVS+Keepalived 方案

LVS 负载均衡算法

静态算法

根据 LVS 自有固定算法分发用户请求

1、轮询(Round Robin – rr):平均分配请求(同 Nginx的轮询)

2、加权轮询(Weight Round Robin – wrr): 按照权重比例分配用户请求,权重越高,分配请求越多(同 Nginx 的权重)

3、源地址散列(Source Hash – sh):同 IP 用户由相同 RS 处理(同 Nginx 的 ip_hash)

4、目标地址散列(Destination Hash – dh):根据不同 url 请求不同的 RS(同 Nginx的 url_hash)

动态算法

根据流量或服务器压力不同分配用户请求

1、最小连接数(Least Connections – lc):将请求分配给连接最小的服务器

2、 加权最小连接数(Weight Least Connections – wlc):用数值表示服务器处理性能,将请求分发到性能好且空闲的服务器

3、 最短期望延迟(Shortest Expected Delay – sed):是一种特殊的 wlc 算法,将请求交给运算结果最小的服务器,设服务器 A、B、C的权重为1、2、3,计算方式如下:

  • A: (1+1)/1=2
  • B: (1+2)/2=3/2
  • C: (1+3)/3=4/3

4、 最少队列调试(Never Queue = nq):如有 RS 的连接数等于0,直接将请求分配过去,无需排队等待运算

注:RS(Real Server)

LVS 最常使用的负载均衡算法为 wlc 或 wrr

官方文档

 

常见问题

1、nginx: [error] open() “/var/run/nginx/nginx.pid” failed (2: No such file or directory)

2、nginx: [error] invalid PID number “” in “/var/run/nginx/nginx.pid”

3、默认 Docker 容器中没有 vi 等编辑器,可进行安装,也可在宿主机执行如下命令,然后根据返回的路径编辑容器中的文件

4、*** WARNING – this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.

 

喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址