一文说清楚代理架构
定义
此模式用于构造解耦的分布式系统。系统中组件通过远程调用彼此交互,代理负责组件之间的通信协调。代理通常还具备日志,安全,路由,缓存,熔断等系统质量相关功能。保证系统高可用,高性能,容错性,安全等特性。
技术案例架构: Nginx,Apache Server,HAProxy,Kong,云服务商的SLB,Redis集群代理,多网合一的短信平台,Spring Cloud Gateway,Ingress Gateway等
软件系统之间很少直接连接调用,通常通过增加一层代理来实现服务发现和路由功能,代理架构是组成微服务系统中一种重要的架构。在分布式系统中,代理架构的实现组件称为网关。
代理架构自身的架构如下图,内部通常通过管道模式来实现路由,内容转化等基础功能和质量属性。

如上图,代理的基本功能包含
| 基本功能 | 描述 |
|---|---|
| 发现和路由 | 允许后端系统注册服务到网关,或者通过网关管理员配置后端系统服务。 请求将根据配置路由到后端系统,比如/order 的请求将路由到Order微服务系统,/pay 的请求将路由到Pay相关的微服务系统 |
| 内容转化 | 对调用或者响应的内容或者协议进行更改,比如HTTP调用,网关会自动在响应头里增加跨域信息。 HTTP调用通过API网关转化Dubbo 泛化调用,或者相反过程 |
| 集成后端服务 | 对外提供一个单点服务,聚合了后端多个系统的功能。使得代理后的应用看起来像一个应用。比如网关 整合后端订单和支付系统,对外提供 xxx.com/pay 和 xxx.com/oder 的URI |
| 负载均衡 | 当后端系统有多个可用实例的时候,代理将请求路由到任意一台实例,可以采取的路由策略有,随机,轮训,基于负载,基于权重等策略。此机制保证了后端系统的高可用,伸缩性,以及高性能。 |
代理架构提升了整个系统的质量属性,可以将后端系统的公共质量要求统一交给代理实现 包括:
| 质量功能 | 描述 |
|---|---|
| 错误恢复 | 当后端某实例节点暂时可不用,可以路由到可用的实例节点。当后端永久不可用,可以给与客户端响应,如提示客户端重定向到新的访问地址。 |
| 日志 | 记录访问日志。这些日志可以导出以作访问统计 |
| 熔断 | 网关禁止请求转发到后端以保护后端,这适合后端系统已经崩溃 |
| 限流 | 网关只允许少量请求转发到后端系统以保护后端,这适合后端系统已经超载 |
| 降级 | 网关对一些特定请求作降级处理以保护后端系统主要功能正常。比如某些耗费资源的请求将不在转发到后端系统,或者忽略处理系统的次要功能,比如电商系统取消积分查询,保留订单查询。 |
| 缓存 | 对相同的请求内容,网关可以直接返回缓存的内容,比如对于HTTP GET请求,根据URL地址,可以返回上次缓存的内容 |
| 安全 | 提供审计记录和查询,网关也可以供防止黑客攻击功能,基于请求的用户验证功能等。对于HTTP网关,基于SSL的HTTP,经过HTTP网关后解码后,转化为明文HTTP调用后端Web服务而无需后端服务提供SSL功能 |
| 灰度测试 | 允许识别请求方,把请求路由到测试系统。比如根据HTTP头里的某个标识判断灰度请求。 |
| 其他功能 | 代理的内部架构是流水线,因此通常网关可以自定义Filter来实现任何功能,比如Spring Cloud Gateway 允许扩展实现AbstractGatewayFilterFactory |
熔断、限流、降级将在高可用战术里详细描述.需要注意的是,大多数熔断限流的生效逻辑都依赖业务自己特点,因此需要网关后端系统自己完成(或者专门的限流中间件),而无需依靠网关。
如下是一个电信短信平台的架构,短信网关将根据不同的目的电信运营商,把统一的短信内容转发到电信运营商,并完成运行商各个协议的转化,比如转化为电信的SMGP协议,或者其他服务商自己的HTTP协议

微服务网关API gateway 则提供了服务发现以及协议转化等功能,下图系统A提供了HTTP服务,允许手机APP通过代理网关访问系统A,也允许内部系统使用Dubbo协议,通过代理网关访问系统A。

网关保证了其后端系统的高可用,如何保证代理服务自身的高可用,通常需要部署多个代理服务实例节点,并且前置一个高可用代理组件,如下是使用云厂商的SLB,保证其后的Nginx和Spring Gateway高可用。

其他方式还可以
- 最简单的方式是安装守护进程,在网关节点停止后自动重启。
- 使用Keeplived自动将请求转向可用的节点,Keepalived 基于Linux的一个内部协议,让多台服务器共享一个虚拟 IP(VIP),实现故障自动切换。
其他办法还包括让客户端重试
- 为DNS服务提供多个地址,客户端访问DNS,客户端通过DNS得到可用的代理服务器实例中的一个地址。
- 提供给客户端多个代理服务器地址,客户端访问其中一个失败,可以重试另外一个代理服务。关于重试,将在高可用战术中说明
