《凤凰架构》C7-分布式服务

目录

一、服务发现

二、网关路由

三、负载均衡


一、服务发现

服务发现就是动态定位服务实例地址,解决分布式环境下服务实例IP和端口可能变化的问题

1)基础概念

远程服务调用精确坐标:全限定名+端口号+服务标识,如:

order-service.default.svc.cluster.local:50051/com.example.order.OrderService/getOrderById

服务标识:与具体的应用层协议相关,包括,

  • REST的url地址
    GET http://user-service.example.com:8080/api/users/123
  • RMI的Stub类的方法
    // 接口定义
    public interface UserService extends Remote {
        User getUserById(Long id) throws RemoteException;
    }
    
    // 服务注册
    Naming.rebind("UserService", userServiceImpl)
    
    // 客户端调用
    UserService stub = (UserService) Naming.lookup("rmi://localhost/UserService");
    stub.getUserById(123L);
    
  • SOAP的WSDL中的方法
  • ……

服务发现的理解:

  1. 【UDDI】面向 Web Service (SOAP) 的服务注册和发现机制,是一种企业级服务目录,支持静态注册和集中式查询。
    
      
        http://example.com/UserService
      
    
    
  2. 【DNS】面向 网络层 的服务地址解析系统,是轻量级的服务发现方式,特别适用于容器和云原生场景。
特性 UDDI DNS
面向协议 SOAP / Web Service 任意协议(HTTP/gRPC/RPC 等)
使用方式 中心式服务注册与查找 名字解析,无需注册(K8s 自动注册)
适用场景 企业 SOA 架构,较重 微服务、容器化、Kubernetes 等
提供信息 WSDL、服务分类、调用接口、元数据 主机名 -> IP 映射
示例 查询服务接口并下载调用描述 order-service.default.svc.cluster.local 解析为 IP

2)分类与功能

服务注册方式

  1. 主动注册(Self-registration):服务启动时,自动将自己的元信息(IP、端口、服务名等)注册到注册中心。服务关闭时,自动注销(或由心跳机制检测失效)
    常见框架:Spring Cloud + Eureka、Dubbo、gRPC + Consu
  2. 被动注册(Third-party registration):由 第三方代理组件或运维系统 负责完成,服务本身不知道自己被注册了。常用于非原生支持服务发现的应用(如遗留系统、C++ 程序)
    常见场景:Kubernetes、Consul + Registrato、Envoy + Service Mesh

服务发现的扩展功能

扩展功能 用途 常见支持平台
健康检查 剔除故障节点 Eureka, Consul, Nacos
路由控制 流量分发、灰度发布 Istio, Spring Cloud Gateway
负载均衡 平衡请求流量 Ribbon, LoadBalancer, Envoy
熔断降级 提升容错能力 Hystrix, Sentinel
元数据管理 服务标签/分组 Nacos, Consul
拓扑可视化 服务依赖展示 Kiali, SkyWalking
动态配置 配置下发、统一治理 Spring Cloud Config, Nacos
权限与安全控制 服务访问限制、加密传输 Istio, Consul Connect

3)实现与算法

服务注册中心CAP

  • 【Eruka】选择AP,牺牲部分C
    节点间异步复制、新节点注册马上宣布可靠、旧节点下线靠TTL机制、Ribbon(客户端负载均衡)和Hystrix(容错框架)兜底实现故障转移/快速失败
  • 【Consul】选择CP,牺牲部分A
    多数节点写入成功后服务才注册完成

服务注册中心实现

  • 基于分布式K/V存储框架,自己开发:
    etcd的Raft算法、Zookeeper的ZAB算法、Redis的?
  • 以基础设施实现服务发现:
    CoreDNS、SkyDNS
  • 专门用于服务发现的框架/工具:
    Eruka、Consul、Nacos
工具/框架 协议/算法 服务发现专用 CAP倾向 常用生态
etcd Raft ❌ 否 CP Kubernetes
Zookeeper ZAB ❌ 否 CP Dubbo、协调器
Redis 无一致性协议 ❌ 否 AP倾向 理论可实现,但不推荐
CoreDNS DNS+etcd ✅ 是 最终一致 K8s
Eureka 自研异步 ✅ 是 AP Spring Cloud
Consul Raft ✅ 是 CP DevOps、Service Mesh
Nacos 自选(AP/CP) ✅ 是 可配置 Spring Cloud Alibaba

分布式一致性算法

算法名称 特点 应用示例 核心流程图解(简要)
Raft 易理解、Leader 选举、日志复制 etcd、Consul、TiDB、Rafter

1. Leader 选举

2. 客户端请求 → Leader

3. Leader 同步日志给 Followers

4. 大多数确认后提交并应用

Paxos 理论完备,复杂 Google Chubby、Spanner

1. Proposer 发送 Prepare

2. Acceptor 响应

3. Proposer 发送 Accept

4. Acceptor 接受,Learner 学习结果

ZAB 针对 ZooKeeper 优化,主备复制 ZooKeeper

1. Leader 选举

2. Leader 广播事务

3. Followers 同步日志

4. 确认后应用

Gossip 点对点消息传播,最终一致性 Cassandra、ScyllaDB

1. 节点随机选择邻居交换状态

2. 信息像病毒一样快速传播

3. 系统最终达成一致

VR 类似 Paxos,视图切换机制 RAMCloud、Google 实验系统

1. Leader 选举视图

2. 日志同步

3. 视图切换应对故障

Multi-Paxos 多请求优化,减少投票次数 Google Spanner

1. 选出稳定 Leader

2. Leader 处理后续请求,减少 Prepare 阶段

二、网关路由

网关 = 路由器(基础职能) + 过滤器(可选职能)

1)协议层次

负载均衡器LB网络协议层次:四层流量转发or七层流量代理

所在层级 主要机制 常见别称/模式 核心说明
数据链路层 改目的 MAC 地址 直接路由 / 单臂模式 / DSR 客户端请求由 LB 转发,响应绕过 LB 直接返回,MAC 不变,IP 不变
网络层 封装/解封装 隧道模式 / IP-in-IP / 套娃 使用 IP 隧道技术(如 GRE、VXLAN)封装原始 IP 包
修改目标 IP NAT 模式 / Full-NAT 改变目标 IP 地址,服务器响应需回到 LB 再返回客户端
传输层 改目标端口 四层负载均衡(LVS、iptables) 根据五元组或四元组分发,无感知应用协议
应用层 两个 TCP 连接 反向代理 / 应用代理 LB 与客户端、服务器分别建立 TCP 连接,能做协议解析、鉴权、缓存等

服务网关网络协议层次

目的:根据流量中的某种特征(如 IP、端口、HTTP 路径、Header 等)进行正确地路由。所以网关能够支持的网络通信协议层次会直接限制后端服务节点能够选择的服务通信方式。

层级 类型 常见代表 功能说明
四层网关 TCP 代理 Envoy TCP Proxy, Nginx stream, Kong stream 建立 TCP 链接后不解析协议内容,适合非 HTTP 应用(如 gRPC、MQ、Redis)
七层网关 应用代理 Spring Cloud Gateway, Nginx, Kong, Envoy HTTP, APISIX 解析 HTTP 请求,可做路由、鉴权、限流、日志、安全策略、API 聚合等,适合微服务网关场景

2)网络I/O

网络请求流操作的两阶段:数据从远程主机到达缓冲区数据从缓冲区复制到应用程序地址空间

I/O模型 特点
阻塞I/O 读写阻塞,线程会休眠,会带来上下文切换
非阻塞I/O 轮询检测,读写立即返回,线程不休眠,CPU占用量高
多路复用I/O 一线程监控多连接,高并发主流
信号驱动I/O 信号通知操作,when第二阶段可以开始
异步I/O 操作系统回调处理,when第二阶段已经结束

【Zuul 1】基于阻塞I/O

Zuul 2】基于Netty Service实现了异步I/O

Nginx】自行配置,可以更具环境选择不同的I/O模型

3)BFF网关

为不同前端应用(比如Web端、移动端、小程序等)提供不能的接口和网络访问协议。

区分发起者角色,每个前端(Web/iOS/小程序)对应一个独立 BFF。

三、负载均衡

1)服务器端负载均衡

【1. 客户端发起请求】
PATCH http://baidu.com/api/user/123

【2. DNS解析】
返回离用户最近的CDN节点或边缘网关(如上海机房地址)

【3. 网关转发】
上海机房的 SLB / Nginx / API 网关,将请求转发到内网用户服务 user-service 的入口

【4. 服务发现 & 负载均衡】
网关通过注册中心获取 user-service 实例列表  
→ 选择其中一个实例,如 user-service-sh-node1 进行处理

【5. 故障转移】
若 user-service-sh-node1 异常,则自动重试到 user-service-sh-node2

【6. 服务响应】
服务处理业务逻辑,返回 HTTP/1.1 200 OK + 数据体给客户端

2)客户端负载均衡

场景:请求不是从“边缘网关/SLB”来调度,而是客户端或服务A内部直接发起请求到服务B,自己选实例,不走中心化负载均衡,常用于集群内部流量消化

【1. 服务A内部发起请求】
想调用 user-service 的 /user/123 接口

【2. 服务发现】
服务A 从注册中心获取 user-service 实例列表

【3. 本地负载均衡】
使用轮询/随机/权重算法,从多个实例中选择一个,例如 user-service-sh-node2

【4. 直接请求】
服务A 直接用 RestTemplate/WebClient 调用 user-service-sh-node2 的内网地址(如:http://10.0.1.12:8080/user/123)

【5. 响应返回】
服务B 处理后返回响应,服务A内部消费,无需对外暴露

总结:客户端负载均衡器运行在服务进程内,“选节点”是本地操作没网络开销,但真正调用服务还是走网络

3)代理负载均衡

即边车代理模式,服务 A 并不直接做服务发现和负载均衡,而是通过一个部署在本机的“代理进程”(边车)来处理一切网络调用。这些代理统一完成服务发现、负载均衡、熔断限流等治理。

客户端 → 发送到代理进程 → 代理决定调用哪个服务实例 → 发出网络请求 → 返回结果

负载均衡总结

维度 服务端负载均衡(中心化) 客户端负载均衡 代理负载均衡(边车代理)
LB逻辑所在位置

远程服务器

(Nginx / SLB / API Gateway)

同一机器、同一进程

(服务内部)

同一机器、不同进程(Sidecar代理)
服务发现方式 配置服务地址,可能定时同步注册中心 客户端集成服务发现逻辑 Sidecar 拉取服务注册信息
调用路径 客户端 → 网关/负载均衡器 → 服务B 服务A → 选实例 → 直连服务B 服务A → Sidecar代理 → 服务B
开发耦合性 低:客户端只需访问公网域名 高:服务需集成LB和服务发现SDK 中:服务只需调用代理地址
治理能力 强:网关可统一配置认证、鉴权、路由、限流等 弱:每个服务自己实现限流、重试等 强:代理可集中控制限流、熔断、监控、安全等策略
转发性能 低:多跳 + 中心化节点易成为瓶颈 高:无中间跳转 中高:多一跳但代理本地通信快
部署复杂度 低:只部署中心节点,如 Nginx 中:每个服务都要集成 SDK 高:每个服务都要部署 Sidecar
代表技术 Nginx、Kong、Zuul、阿里云SLB、AWS ELB Ribbon、Feign、Spring Cloud LoadBalancer Envoy、MOSN、Istio、Linkerd
适用场景 外部请求接入统一控制、少量服务调用 服务内部调用频繁、延迟敏感 微服务架构 + Service Mesh 统一治理

4)Region和Zone

Region:地域,如华东、华北、华南。不同地域间没有内网连接,同一地域是微服务集群内流量的最大范围

Zone:可用区,如华东的上海、杭州、苏州的不同机房。同一Region的不同Zone有内网连接,流量不占用公网带宽。

  • 高可用(异地容灾):容灾非实时--》跨地域 (华东+华北) / 跨区域 
  • 高可用(异地双活):双活准实时--》跨区域 (上海+杭州)
  • 低延迟:同一区域

你可能感兴趣的:(阅读笔记,java)