1. 根据微服务框架 Dubbo 的架构图,画出 Dubbo 进行一次微服务调用的时序图
组件图如下:
时序图:
说明:客户端请求服务端的服务,服务端获取到服务程序以后,逐层按照请求顺序返回;客户端内部组件也是按照顺序逐层返回到服务框架客户端,服务框架客户端最后执行获取到的服务代码。
简化的描述如下:
- 服务提供者 注册到 服务注册中心,把服务映射到服务提供者列表;
- 服务消费者程序,调用服务接口;
- 接口访问代理获取到服务消费者调用的接口;
- 服务框架客户端,调用服务提供者列表找到服务提供者;
- 负载均衡策略分配一个服务给服务框架客户端;
- 远程通讯模块与客户端建立连接;
- 远程通信模块,调用 服务调用线程;
- 服务调用线程 请求服务提供者程序, 服务提供者程序返回服务的 class 给服务调用线程;
- 服务调用线程 返回 class 给远程通讯模块;
- 远程通讯模块 返回 class 给 服务框架客户端, 服务框架客户端 用 class 创建对象,调用里面的方法即可。
2. 关于微服务架构(中台架构、领域驱动设计、组件设计原则),你有什么样的思考和认识?
最重要的是需求
最重要的是需求。
微服务架构解决方案就是拆分,将模块独立部署,降低系统耦合性:
- 纵向拆分:将一个大应用拆分为多个小应用,如果新增业务较为独立,那么就直接将其设计部署为一个独立的 Web 应用系统。
- 横向拆分:将复用的业务拆分出来,独立部署为微服务,新增业务只需要调用这些微服务即可快速搭建一个应用系统。
微服务框架,都是基于Web Service 与企业级分布式服务演化而来。
所以核心架构都没变。
- Service Provider: 服务提供者
- Service Requester:服务消费者,客户端
- Service Broker:服务注册中心。服务提供者注册服务到服务注册中心;服务消费者从服务注册中心请求服务,服务注册中心调用服务提供者,最终把结果返回给服务消费者。
微服务框架需求
对于大型互联网系统,除了 Web Service 所规范的服务注册与发现,服务调用等标准功能,还需要微服务框架能够支持:
- 失效转移(Fail Over): 对于大型网站的微服务而言,即使是很少访问的简单服务,也需要集群部署,同时微服务框架还需要支持服务提供者的失效转移机制,以实现服务高可用。
- 负载均衡:对于集群部署的服务提供者,服务请求者可以使用加权轮询等手段访问,使服务提供者集群实现负载均衡。
- 高效的远程通信: 对于大型网站,核心服务每天的调用次数会达到数以亿计,如果没有高效的远程通信手段,服务调用可能会成为整个系统性能的瓶颈。
- 对应用最少侵入: 网站技术是为业务服务服务的,是否使用微服务需要根据业务发展规划,微服务也需要渐进式的演化,甚至会出现反复,即使用了微服务后又退回到集中式部署,微服务框架需要支持这种渐进式演化和反复。当然服务模块本身需要支持可集中式部署,也可分布式部署。
- 版本管理:为了应对快速变化的需求,服务版本升级不可避免,如果仅仅是服务实现升级,那么这种升级对服务请求者而言是透明的,无需关注。但是如果服务的访问接口发生变化,就需要服务请求者和服务提供者同时升级才不会导致服务器调用失败。企业应用系统可以申请停机维护,同时升级接口,而网站服务不可能中断,需要服务提供者先升级接口,并同时提供历史版本的服务供请求者调用,当请求者访问接口升级后才可以关闭历史版本服务。(阿里的对升级以后服务维护半年,半年以后就下线。)
微服务架构实践
- 业务先行,先理顺业务边界和依赖,技术是手段而不是目的。
- 先有独立的模块,后有分布式的服务。
- 业务耦合严重,逻辑复杂多变的系统进行微服务重构要谨慎。
- 要搞清楚实施微服务的目的是什么,业务复用?开发边界清晰?分布式集群提升性能?
命令与查询职责隔离 (CQRS)
在服务接口层面将查询(读操作) 与命令 (写操作) 隔离,实现服务层的读写分离。
- 更清晰的领域模型;
- 针对读写分别优化,实现更好的性能;
- 查询服务不会修改数据,更好地保护数据。
事件溯源
将用户请求处理过程中的每次状态变化都记录到事件日志中,并按时间序列进行持久化存储。
- 利用事件溯源,可以精确复现任何用户状态,进行复核审计。
- 利用事件溯源,可以有效监控用户状态变化,并在此基础上实现分布式事务。
断路器
当某个服务出现故障,响应延迟或者失败率增加,继续调用这个服务会导致调用者请求阻塞,资源消耗增加,进而出现服务器级联失效,这种情况下使用断路器阻断对故障服务的调用。
- 断路器三种状态:关闭,打开,半开。
服务重试及调用超时
上游调用者超时时间要大于下游调用者超时时间之和。