-
Notifications
You must be signed in to change notification settings - Fork 148
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
59ceeb3
commit a1ad335
Showing
19 changed files
with
537 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# LVS | ||
|
||
LVS 有如下的组成部分: | ||
|
||
- Direct Server(以下简称 DS):前端暴露给客户端进行负载均衡的服务器。 | ||
|
||
- Virtual Ip 地址(以下简称 VIP):DS 暴露出去的 IP 地址,做为客户端请求的地址。 | ||
|
||
- Direct Ip 地址(以下简称 DIP):DS 用于与 Real Server 交互的 IP 地址。 | ||
|
||
- Real Server(以下简称 RS):后端真正进行工作的服务器,可以横向扩展。 | ||
|
||
- Real IP 地址(以下简称 RIP):RS 的地址。 | ||
|
||
- Client IP 地址(以下简称 CIP):Client 的地址。 | ||
|
||
![](https://tva3.sinaimg.cn/large/007DFXDhgy1g5us7zazn4j30ly0f03zb.jpg) | ||
|
||
客户端进行请求时,流程如下: | ||
|
||
- 使用 VIP 地址访问 DS,此时的地址二元组为<src:CIP,dst:VIP>。 | ||
|
||
- DS 根据自己的负载均衡算法,选择一个 RS 将请求转发过去,在转发过去的时候,修改请求的源 IP 地址为 DIP 地址,让 RS 看上去认为是 DS 在访问它,此时的地址二元组为<src:DIP,dst:RIP A>。 | ||
|
||
- RS 处理并且应答该请求,这个回报的源地址为 RS 的 RIP 地址,目的地址为 DIP 地址,此时的地址二元组为<src:RIP A,dst:DIP>。 | ||
|
||
- DS 在收到该应答包之后,将报文应答客户端,此时修改应答报文的源地址为 VIP 地址,目的地址为 CIP 地址,此时的地址二元组为<src:VIP,dst:CIP>。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# 负载均衡 | ||
|
||
为了解决应用实例的可扩展、可用性、安全性问题,在不同的应用实例间分配传入的流量,需要依赖于一些负载均衡解决方案。我们常见的负载均衡会分以下几层进行部署: | ||
|
||
- 二层负载均衡会通过一个虚拟 MAC 地址接收请求,然后再分配到真实的 MAC 地址; | ||
|
||
- 三层负载均衡会通过一个虚拟 IP 地址接收请求,然后再分配到真实的 IP 地址; | ||
|
||
- 四层通过虚拟 IP 与端口接收请求,然后再分配到真实的服务器; | ||
|
||
- 七层通过虚拟的 URL 或主机名接收请求,然后再分配到真实的服务器。 | ||
|
||
最为常用的是四层负载均衡与七层负载均衡。四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。而所谓七层负载均衡,也称为内容交换,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。比如公有云 AWS ELB 提供了两种类型的负载均衡器: | ||
|
||
- Classic 负载均衡器,可基于应用程序或网络级信息路由流量,适用于在多个 EC2 实例之间进行简单的流量负载均衡 | ||
|
||
- 应用程序负载均衡器,可基于包括请求内容的高级应用程序级信息路由流量,适用于需要高级路由功能、微服务和基于容器的架构的应用程序。应用程序负载均衡器可将流量路由至多个服务,也可在同一 EC2 实例的多个端口之间进行负载均衡 | ||
|
||
# Links | ||
|
||
- https://zhuanlan.zhihu.com/p/36054372 |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# 基于 Go 的简单负载均衡 | ||
|
||
# Links | ||
|
||
- https://mp.weixin.qq.com/s/4MsiS6xEnJo66ZQESePzTQ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# Load Balancing | 负载均衡 | ||
|
||
## 负载均衡算法 | ||
|
||
常用的负载均衡算法有:轮询,随机,最少链接,源地址哈希,加权等方式。 | ||
|
||
| 方式 | 优点 | 缺点 | | ||
| ---------- | ------------------------------------------------------------------------ | -------------------------------------------- | | ||
| 随机 | 简单 | 不适合机器配置不同的场景 | | ||
| 轮询 | 每台服务器的请求数目相同 | 服务器压力不一样,不适合服务器配置不同的情况 | | ||
| 最少连接 | 根据服务器当前的请求处理情况,动态分配 | 算法实现相对复杂,需要监控服务器请求连接数 | | ||
| 源地址哈希 | 将来自同一 IP 地址的请求,同一会话期内,转发到相同的服务器;实现会话粘滞 | 目标服务器宕机后,会话会丢失 | | ||
| 加权 | 根据权重,调节转发到后端服务器的请求数目 | 使用相对复杂 | | ||
|
||
### 轮询 | ||
|
||
将所有请求依次分发到每台服务器上,适合服务器硬件配置相同的场景。 | ||
|
||
### 随机 | ||
|
||
请求随机分配到各个服务器。 | ||
|
||
### 最少连接 | ||
|
||
将请求分配到连接数最少的服务器(目前处理请求最少的服务器)。 | ||
|
||
### Hash | 源地址哈希 | ||
|
||
根据 IP 地址进行 Hash 计算,得到 IP 地址。 | ||
|
||
### 加权 | ||
|
||
在轮询,随机,最少连接,Hash 等算法的基础上,通过加权的方式,进行负载服务器分配。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# 负载均衡分层 | ||
|
||
前文我们提及,负载均衡可以部署在二层、三层、四层与七层等不同的网络层,而实际应用中,我们常常会进行 IP 层、HTTP 层与应用层的负载均衡。 | ||
|
||
# IP 层负载均衡 | ||
|
||
以常见的 TCP 为例,负载均衡设备在接收到第一个来自客户端的 SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中的目标 IP 地址进行修改(改为后端服务器 IP),直接转发给该服务器。TCP 的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。 | ||
|
||
该层负载均衡的特点如下: | ||
|
||
1、抗负载能力强、是工作在网络 4 层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的; | ||
|
||
2、配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率; | ||
|
||
3、工作稳定,自身有完整的双机热备方案,如 LVS+Keepalived 和 LVS+Heartbeat,不过我们在项目实施中用得最多的还是 LVS/DR+Keepalived; | ||
|
||
4、无流量,保证了均衡器 IO 的性能不会收到大流量的影响; | ||
|
||
5、应用范围比较广,可以对所有应用做负载均衡; | ||
|
||
6、软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是 Nginx/HAProxy+Keepalived 的优势所在。 | ||
|
||
7、如果是网站应用比较庞大的话,实施 LVS/DR+Keepalived 起来就比较复杂了,特别后面有 Windows Server 应用的机器的话,如果实施及配置还有维护过程就比较复杂了,相对而言,Nginx/HAProxy+Keepalived 就简单多了。 | ||
|
||
![](https://tva3.sinaimg.cn/large/007DFXDhgy1g5us7zazn4j30ly0f03zb.jpg) | ||
|
||
客户端进行请求时,流程如下: | ||
|
||
- 使用 VIP 地址访问 DS,此时的地址二元组为<src:CIP,dst:VIP>。 | ||
|
||
- DS 根据自己的负载均衡算法,选择一个 RS 将请求转发过去,在转发过去的时候,修改请求的源 IP 地址为 DIP 地址,让 RS 看上去认为是 DS 在访问它,此时的地址二元组为<src:DIP,dst:RIP A>。 | ||
|
||
- RS 处理并且应答该请求,这个回报的源地址为 RS 的 RIP 地址,目的地址为 DIP 地址,此时的地址二元组为<src:RIP A,dst:DIP>。 | ||
|
||
- DS 在收到该应答包之后,将报文应答客户端,此时修改应答报文的源地址为 VIP 地址,目的地址为 CIP 地址,此时的地址二元组为<src:VIP,dst:CIP>。 | ||
|
||
# HTTP 层负载均衡 | ||
|
||
以常见的 TCP 为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(TCP 三次握手)后,才可能接收到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立 TCP 连接。所以从这个技术原理上来看,七层负载均衡明显地对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。 | ||
|
||
七层应用负载均衡的好处,是使得整个网络更“智能化”, 例如访问一个网站的用户流量,可以通过七层的方式,将对图片类的请求转发到特定的图片服务器并可以使用缓存技术;将对文字类的请求可以转发到特定的文字服务器并可以使用压缩技术。当然这只是七层应用的一个小案例,从技术原理上,这种方式可以对客户端的请求和服务器的响应进行任意意义上的修改,极大的提升了应用系统在网络层的灵活性。很多在后台(例如 Nginx 或者 Apache )上部署的功能可以前移到负载均衡设备上,例如客户请求中的 Header 重写,服务器响应中的关键字过滤或者内容插入等功能。 | ||
|
||
七层负载均衡在安全性方面也有一定的考量,以网络中最常见的 SYN Flood 攻击,即黑客控制众多源客户端,使用虚假 IP 地址对同一目标发送 SYN 攻击,通常这种攻击会大量发送 SYN 报文,耗尽服务器上的相关资源,以达到 Denial of Service(DoS) 的目的。从技术原理上也可以看出,四层模式下这些 SYN 攻击都会被转发到后端的服务器上。而七层模式下这些 SYN 攻击自然在负载均衡设备上就截止,不会影响后台服务器的正常运营。另外负载均衡设备可以在七层层面设定多种策略,过滤特定报文,例如 SQL Injection 等应用层面的特定攻击手段,从应用层面进一步提高系统整体安全。现在的 7 层负载均衡,主要还是着重于应用广泛的 HTTP 协议,所以其应用范围主要是众多的网站或者内部信息平台等基于 B/S 开发的系统。4 层负载均衡则对应其他 TCP 应用,例如基于 C/S 开发的 ERP 等系统。 | ||
|
||
以常见的 Nginx 服务器为例,七层负载均衡的特性在于: | ||
|
||
1、工作在网络的七层之上,可以针对 http 应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比 HAProxy 更为强大和灵活; | ||
|
||
2、Nginx 对网络的依赖非常小,理论上能 ping 通就就能进行负载功能,这个也是它的优势所在; | ||
|
||
3、Nginx 安装和配置比较简单,测试起来比较方便; | ||
|
||
4、也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量; | ||
|
||
5、Nginx 可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持 url 来检测; | ||
|
||
6、Nginx 仅能支持 http 和 Email,这样就在适用范围上面小很多,这个它的弱势; | ||
|
||
7、Nginx 不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的 Web 应用服务器。LNMP 现在也是非常流行的 web 架构,大有和以前最流行的 LAMP 架构分庭抗争之势,在高流量的环境中也有很好的效果。 | ||
|
||
8、Nginx 现在作为 Web 反向加速缓存越来越成熟了,速度比传统的 Squid 服务器更快。 | ||
|
||
此时一个提供七层 HTTP 访问接口的服务架构大体是这样的: | ||
|
||
![](https://tva2.sinaimg.cn/large/007DFXDhgy1g5us9afmd7j30qo0e4q3t.jpg) | ||
|
||
# 应用层负载均衡 | ||
|
||
在实际的部署中,我们往往又会在 HTTP 层之上架设专属的应用层负载均衡,其特性在于: | ||
|
||
HAProxy 的特点是: | ||
|
||
1、HAProxy 是支持虚拟主机的,以前有朋友说这个不支持虚拟主机,我这里特此更正一下。 | ||
|
||
2、能够补充 Nginx 的一些缺点比如 Session 的保持,Cookie 的引导等工作 | ||
|
||
3、支持 url 检测后端的服务器出问题的检测会有很好的帮助。 | ||
|
||
4、它跟 LVS 一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲 HAProxy 更会比 Nginx 有更出色的负载均衡速度,在并发处理上也是优于 Nginx 的。 | ||
|
||
5、HAProxy 可以对 Mysql 读进行负载均衡,对后端的 MySQL 节点进行检测和负载均衡,不过在后端的 MySQL slaves 数量超过 10 台时性能不如 LVS,所以我向大家推荐 LVS+Keepalived。 | ||
|
||
6、HAProxy 的算法现在也越来越多了,具体有如下 8 种: | ||
|
||
- roundrobin,表示简单的轮询,这个不多说,这个是负载均衡基本都具备的; | ||
- static-rr,表示根据权重,建议关注; | ||
- leastconn,表示最少连接者先处理,建议关注; | ||
- ource,表示根据请求源 IP,这个跟 Nginx 的 IP_hash 机制类似,我们用其作为解决 session 问题的一种方法,建议关注; | ||
- ri,表示根据请求的 URI; | ||
- rl_param,表示根据请求的 URl 参数 'balance url_param' requires an URL parameter name; | ||
- hdr(name),表示根据 HTTP 请求头来锁定每一次 HTTP 请求; | ||
- rdp-cookie(name),表示根据据 cookie(name) 来锁定并哈希每一次 TCP 请求。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
# 基于 Kong 的微服务网关架构 | ||
|
||
Kong = OpenResty + Nginx,我们可以直接在 Docker 上启动 Kong 实例: | ||
|
||
```sh | ||
# 使用 Postgres 作为数据存储 | ||
$ docker run -d --name kong-database \ | ||
-p 5432:5432 \ | ||
-e "POSTGRES_USER=kong" \ | ||
-e "POSTGRES_DB=kong" \ | ||
postgres:9.4 | ||
|
||
# 进行数据库迁移 | ||
$ docker run --rm \ | ||
--link kong-database:kong-database \ | ||
-e "KONG_DATABASE=postgres" \ | ||
-e "KONG_PG_HOST=kong-database" \ | ||
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ | ||
kong:latest kong migrations up | ||
|
||
# 启动 Kong | ||
$ docker run -d --name kong \ | ||
--link kong-database:kong-database \ | ||
-e "KONG_DATABASE=postgres" \ | ||
-e "KONG_PG_HOST=kong-database" \ | ||
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \ | ||
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ | ||
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ | ||
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ | ||
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ | ||
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \ | ||
-e "KONG_ADMIN_LISTEN_SSL=0.0.0.0:8444" \ | ||
-p 8000:8000 \ | ||
-p 8443:8443 \ | ||
-p 8001:8001 \ | ||
-p 8444:8444 \ | ||
kong:latest | ||
|
||
# 判断 Kong 是否启动成功 | ||
$ curl -i http://localhost:8001/ | ||
|
||
|
||
# 使用 Konga 作为界面化管理 | ||
# Admin login: admin | password: adminadminadmin | ||
$ docker run -p 1337:1337 \ | ||
--link kong:kong \ | ||
--name konga \ | ||
-e "NODE_ENV=production" \ | ||
pantsel/konga | ||
``` | ||
|
||
Kong 使用的各个端口的作用依次为: | ||
:8000 on which Kong listens for incoming HTTP traffic from your clients, and forwards it to your upstream services. | ||
:8443 on which Kong listens for incoming HTTPS traffic. This port has a similar behavior as the :8000 port, except that it expects HTTPS traffic only. This port can be disabled via the configuration file. | ||
:8001 on which the Admin API used to configure Kong listens. | ||
:8444 on which the Admin API listens for HTTPS traffic. | ||
Kong 启动完毕后,可以在 Konga 或者直接以 API 请求的方式注册与消费 API: | ||
|
||
```sh | ||
# 注册新的 API | ||
$ curl -i -X POST \ | ||
--url http://localhost:8001/apis/ \ | ||
--data 'name=example-api' \ | ||
--data 'hosts=example.com' \ | ||
--data 'upstream_url=http://mockbin.org' | ||
|
||
# 添加插件 | ||
$ curl -i -X POST \ | ||
--url http://localhost:8001/apis/example-api/plugins/ \ | ||
--data 'name=rate-limiting' \ | ||
--data 'config.minute=100' | ||
|
||
# 尝试进行访问 | ||
$ curl -i -X GET \ | ||
--url http://localhost:8000/ \ | ||
--header 'Host: example.com' | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
# DeepStream |
Oops, something went wrong.