《分布式服务框架原理与实践》阅读笔记3
服务调用
分布式框架中,引入NIO 带来的好处:
1.所有的I/O 操作都是非阻塞的,避免有限的I/O线程因为网络,对方处理慢等原因被阻塞。
2.多路复用的Reactor 线程模型:基于Linux 的epoll 和 Selector ,一个I/O 线程可以并行处理成百上千条链路,解决了传统同步I/O通信线程膨胀的问题。NIO 只解决了通信层面的异步问题,跟服务调用的异步没有必然关系,也就是说,即便采用 了传统的BIO通信,依然可以实现异步服务调用,只不过通信效率和可靠性比较差而已。
异步服务调用相比于同步服务调用有两个优点:
1.化串行为并行,提升服务调用效率,减少业务线程阻塞时间
2.化同步为异步,避免业务线程阻塞。
并行服务调用的目标主要有两个:
1.降低业务E2E时延
2.提升整个系统的吞吐量
解决串行调用效率低的问题,有两个解决方案:
1.异步服务调用
2.并行服务调用
泛化调用:泛化引用/泛化实现。
泛化引用主要用于客户端没有API接口及数据模型的场景,参数及返回值中的所有POJO 均用Map 表示,通常用于框架集成,比如实现一个通用的服务测试框架。
泛化实现主要用于服务端没有API接口及数据模型的场景,参数及返回值中的所有POJO 均用Map 表示,通常用于框架集成,比如实现一个通用的远程服务Mock 框架。
服务注册中心
如何有效的管理服务订阅/发布,避免硬编码地址信息是分布式服务框架需要解决的一个问题。通过将服务统一管理起来,可以有效地优化内部应用对服务发布/使用的流程和管理,服务注册中心就是专门用来管理服务订阅/发布的配置管理节点。
服务注册中心:服务注册中心是分布式服务框架的目录服务器,相比于传统的目录服务器,它有如下几个特点:
1.高HA:支持数据持久化,支持集群
2.数据一致性问题:集群中所有的客户端应该看到同一份数据,不能出现读或者写数据不一致。
3.数据变更主动推送:当注册中心的数据发生变更时(增加,删除,修改)需要能够及时将变化的数据通知给客户端。
关键功能特性设计:当服务越来越多,服务URL配置管理变得困难,F5等硬件负载均衡器的单点压力越来越大。此时需要一个服务注册中心,动态的注册和发现服务,使服务的地址透明。
微服务调用原理:
1.服务提供者在启动时,根据服务发布文件中配置的服务发布信息向注册中心注册自己提供的服务
2.服务消费者在启动时,根据消费者配置文件中配置的服务消费信息向注册中心订阅自己所需要的服务,消费者刷新本地缓存的路由表
3.注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心主动推送变更数据给消费者,消费者刷新本地缓存的路由表
4.服务消费者从本地缓存的服务提供者地址列表中,基于负载均衡算法选择一台服务提供者进行调用。
提供CRUD接口:客户端连接服务注册中心后,需要能够对服务注册中心的数据进行操作,通常需要用到如下几种操作:
1.查询接口:查询系统当前发布的服务信息和订阅 的消费者信息
2.修改接口:修改已经发布的服务属性或者消费者属性,通常用于运行态的服务治理。
3.新增接口:发布或者订阅新的服务
4.删除接口:去注册已经发布的服务,或者消费者取消订阅关系。
安全加固:服务注册中心需要进行安全加固,安全加固主要设计两部分:
1.链路的安全性
2.数据的安全性
链路的安全性指的是服务注册中心对客户端连接进行安全认证,认证策略非常多,最简单的就是基于IP地址的黑名单校验,更加复杂的有基于用户名+密码的认证,或者基于密钥+数字认证。认证失败,则关闭链路,拒绝客户端连接。
数据的安全性主要针对服务注册中心的数据进行权限控制:
1.非授权客户端既不能读取也不能写入数据
2.普通运维人员只能读取数据,不能修改数据
3.管理员既可以读取也可以修改数据
4.不同的服务目录可以设置不同的访问权限,例如消费者只能查看它所在机房的服务。
订阅发布机制:服务注册中心需要支持服务的订阅发布,对于服务提供者,可以根据服务名等信息动态发布服务;对于消费者,可以根据订阅关系主动获得服务发布者的地址信息等。
订阅发布机制还有一个比较重要的机制就是对变化监听和主动推送能力:
1.消费者可以监听一个或多个服务目录,当目录名称,内容发生变更变更时,消费者可以实时的获得变更的数据或者变更后的结果。
2.服务提供者可以发布一个或多个服务,动态修改服务名称,服务内容等,可以主动将修改后的数据或者修改后的结果推送给所有监听此服务目录的消费者。
3.订阅发布机制具有如下几个优点:
1.透明化路由:服务提供者和消费者相互解耦,服务提供者位置透明,消费者不需要再硬编码服务提供者地址。
2.服务健康状态检测:服务注册中心可以实时检测发布服务的质量,如果服务提供者宕机,由服务注册中心实时通知消费者。
3.弹性伸缩能力(动态发现):应用在云端部署之后,由于VM 资源占用率过高,动态伸展出一个新的服务提供者,服务注册中心会将新的服务提供者地址信息推送给消费者,消费者刷新本地路由表之后可以访问新的服务提供者,实现服务的弹性伸缩。
可靠性:服务注册中心需要支持对等集群,任意一台宕机后,服务都能自动切换到其他正常的服务注册中心。如果服务注册中心全部宕机,只影响新的服务注册,已发布服务的下线,不影响服务的正常运行和调用,消费者可以依靠本地缓存的服务路由表进行路由。服务提供者的健康状态检测也由服务注册中心负责检测。服务注册中心通过长连接心跳检测服务提供者的存在。服务提供者宕机,注册中心将立即推送服务下线事件通知消费者,消费者下线的服务提供者地址从缓存的路由表删除,新接入的消息将不再路由到故障节点,实现实时故障隔离。
基于Zookeeper 的服务注册统一设计:统一命名服务,状态同步服务,集群管理,分布式应用统一配置等。
服务健康状态:基于zookeeper客户端和服务端的长连接和会话超时控制机制,可以非常方便的实现服务健康状态检测。在zookeeper中,客户端和服务端建立连接后,会话随之建立,生产一个全局唯一session ID 。服务器端和客户端之间维持的是一个长连接,在session_timeout 周期内,服务器会检测与客户端的链路是否正常。正常情况下,session 会一直有效,并且ZK集群所有机器上都保存这个session 信息。在出现网络或者其他问题的情况下(客户端宕机,网络闪断),如果客户端与之前连接的zookeeper server 断链了,此时客户端会主动在地址列表中选择新的地址进行连接。
如果ZK 客户端宕机,或者网络出现故障,超过了session_timeout 后服务端仍然没有收到客户端的心跳消息,服务器认为这个session 已经结束了。ZK 中,很多数据和状态都是和会话绑定的,一旦会话失效,那么ZK就开始清除和这个会话有关的信息,包括这个会话创建的临时节点和注册的所有watcher。
对等集群防止单点故障:
zookeeper 集群通常由2N+1台server 组成,每台Server 都直到彼此的存在,每台server 都维护内存状态镜像以及持久化存储的事务日志和快照,对于2N+1台server,只要有n+1台server 可用,整个集群就保持可用。
系统启动时,集群中的server 会选举出一台server为leader,其他的就作为follower,接着由follower 来服务client 的请求,对于不改变系统一致性状态的读操作,由follower 的本地内存数据库直接给client 返回结果;对于会改变系统状态的更新操作,则交由leader进行提议投票,超过半数通过后返回结果给client。zookeeper 集群管理的核心是源自广播,这个机制保证了各个server之间的数据同步,实现这个机制的协议叫做zab 协议。Zab 协议有两种模式,他们分别为恢复模式和广播模式。当服务启动或者在leader 崩溃后,zab 就进入了恢复模式,当leader 被选举出来,且大多数server完成了和leader 的状态同步后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。
一旦leader 已经和多数的follower 进行了状态同步后,她就可以开始广播消息了,即进入广播状态。此时当一台server加入zookeeper服务中时,它会在恢复模式下启动,发现leader并和leader 进行状态同步。待到同步结束,它也参与消息广播。zookeeper 服务一直维持在广播状态,直到leader 崩溃了和leader失去了大部分的follower 支持。
变更通知机制:服务提供者将服务注册信息保存在zookeeper 的某个目录节点上,消费者监控服务配置信息状态,一旦配置信息发生变化。