服务治理包括服务发现、负载均衡、限流、熔断、超时、重试、服务追踪等。
服务发现
服务发现是指使用注册中心记录分布式系统中的全部服务的信息,以便让其他服务快速找到已注册的服务。
服务发现需要具有服务注册、服务查找、服务健康检查和服务变更通知等功能。
服务发现可以使环境与配置之间的关系完全透明化。应用无须以硬编码或配置文件的方式提供网络地址和端口号。而可以通过服务名称来查找和使用服务。
DNS是最早的服务发现。
提供一个高可用且网络位置稳定的服务注册中心是常见的服务发现解决方案。
CAP定理
高可用
服务发现注册中心对比
zookeeper | eureka | etcd | consul | |
---|---|---|---|---|
一致性协议 | zab | 自研 | raft | raft |
cap | cp | ap | cp | ap |
健康检查 | 临时节点 | 连接心跳 | ttl | 服务状态、内存、磁盘 |
客户端 | java、c | java、python、restful | grpc | http、dns |
功能 | 服务发现、kv存储、分布式选举、分布式锁 | 服务发现 | 服务发现、kv存储 | 服务发现、kv存储 |
典型案例 | dubbo | spring cloud | k8s | docker、swarm |
与注册中心的契合 | 中 | 高 | 低 | 高 |
负载均衡
负载均衡是实现系统高可用、网络流量疏导和扩容的重要手段。负载均衡的本质是通过合理的算法将请求分摊到多个服务节点。
DNS是最早的负载均衡,
服务端负载均衡
- 四层负载均衡
四层负载均衡是基于ip地址和端口号进行负载均衡。
四层负载均衡通过修改报文中的目标地址和端口,将请求转发至合适的应用服务器。以tcp为例,负载均衡服务器在接收到第一个来自客户端的syn请求后,即通过负载均衡算法选择合适的应用服务器,然后将报文中的目标ip地址修改为真实的后端应用服务器的ip地址,并将请求直接转发至该服务器。因此tcp通过三次握手建立的连接是由客户端与真实应用服务器端直接建立的,负载均衡服务器在这种情况下仅作为路由器进行转发。
F5和LVS是常见的四层负载均衡产品。 - 七层负载均衡
七层负载均衡是基于url和请求头等应用层信息进行负载均衡。
仍然以tcp为例,负载均衡服务器需要先通过三次握手分别与所代理的服务器和客户端建立连接,然后才解析客户端发送的应用层报文,并且将报文中的特定字段作为负载均衡算法的输入,以此为依据选择合适的应用服务器。
nginx是常用的七层负载均衡产品。
服务端的负载均衡方案在服务器列表不经常变化的情况下是不存在问题。
客户端负载均衡
客户端负载均衡的最佳实践是与服务发现配合使用。
客户端负载均衡相对于服务端负载均衡减少了一次转发。但客户端与服务端变为网状交叉访问,使得连接数量增加。
客户端 | 应用服务 | ||
---|---|---|---|
> | 修改报头+源地址 | 转发 > | |
> | 创建两个独立tcp连接 | 代理 > |
服务端负载均衡多用于网站前端和后端交互、应用与数据库交互等场景。
客户端负载均衡长用于应用后端服务之间的调用。
限流
限流能够平滑网络上的突发流量,以此保护后端的服务节点不被流量洪峰冲垮。限流通过对一个时间窗口内的请求流量进行限速来实施对系统的保护。
限流后的操作有三种情况,拒绝服务、排队服务和应用降价。
限流算法
- 计数器限流算法
主要用于限制服务端资源,即数据库连接池和线程池。 - 漏桶算法
流出速率固定,即控制应用服务器向其他应用服务器发送请求的速率。主要用于控制其他系统的回调洪峰。 - 令牌桶算法
使用一个存放固定容量令牌的桶,按照固定速率向桶中添加令牌,有服务需要处理的话,需要先拿到一个令牌。
令牌桶允许一定程度的流量突发。
限流方案
- 客户端限流
guava类库中的rateLimiter类。 - 服务端限流
中间件 tomcat、dubbo。数据库。zuul。 - 接入端限流
四层负载均衡器会无差别限流,七层负载均衡可根据业务灵活调整。
openResty是基于ng的lua的高性能web平台。
以上三种方案一起实现分布式。
限流的维度和粒度
- 限流的维度可理解为用于限流的关键字段。
- 限流粒度分为集群粒度、服务粒度和接口粒度。
熔断
熔断的目的是在流量过载的情况下禁止客户端对服务端的访问。
限流是允许部分流量通过。熔断是完全禁止客户端访问后端服务。都是防止流量洪峰压垮整个集群。
熔断也可以防止连锁失效。
熔断器模式:关闭状态、开启状态和版开启状态。
网友评论