服务视图
微服务的服务视图
2002 年左右,亚马逊 CEO 贝佐斯就在亚马逊内部强制推行了以下六项原则:
- 所有团队开发的程序模块都要通过 Service 接口将数据与功能开放出来。
- 团队间程序模块的信息通信都要通过上述接口。
- 除上述通信方式外,其他方式一概不允许使用:不能直接连接程序,不能直接读取其他团队的数据库,不能使用共享内存模式,不能使用他人模块的内部入口等。
- 任何技术都可以使用,比如 HTTP、Corba、发布/订阅、自定义的网络协议等。
- 所有的 Service 接口,毫无例外,都必须从骨子里到表面上被设计成能对外界开放的。也就是说,团队必须做好规划与设计,以便未来把接口开放给全世界的程序员。
- 不按照以上要求做的人会被炒鱿鱼。
想象一个向消费者提供产品信息的分布式系统。如下图,这个服务由 7 个微服务组成,从 A 到 G。A 服务存储了用户的个人信息。B 服务存储用户的登录账户信息,如用户上一次登录的时间和访问了什么信息。C 服务是关于产品信息的。D 服务作为 API 网关处理所有来自外部的接口访问。
- 请求首先进入 D 服务,即 API 服务;
- D 服务本身并没有所有需要的信息,所以它进一步请求 C 服务和 F 服务以获取必要的数据;
- C 服务和 F 服务也同时都需要更多的信息来满足请求,于是 C 服务请求 A 服务,F 服务请求了 B 服务和 G 服务;
- A 服务也需要访问 B 服务,B 服务需要访问 E 服务,同时 G 服务也需要访问 E 服务;
- 对 D 服务的一个请求,扩散到了整个微服务架构里。而且当所有依赖的服务没有返回或者超时之前,API 不会向手机 App 返回响应。
在简单的系统中我们能够根据功能来对服务进行划分,而对于大型复杂系统,则会根据 Facade 接口、应用服务、领域服务和基础服务等层划分,然后各层服务协同配合,为外部提供服务。
值得一提的是,在每个具体的服务内部,我们又可以划分为接口层,应用层,领域层以及基础(数据)层等不同的层次。
接口服务
接口服务位于用户接口层,用于处理用户发送的 Restful 请求和解析用户输入的配置文件等,并将信息传递给应用层。
应用服务
应用服务位于应用层。用来表述应用和用户行为,负责服务的组合、编排和转发,负责处理业务用例的执行顺序以及结果的拼装。应用层的服务包括应用服务和领域事件相关服务。
应用服务可对微服务内的领域服务以及微服务外的应用服务进行组合和编排,或者对基础层如文件、缓存等数据直接操作形成应用服务,对外提供粗粒度的服务。领域事件服务包括两类:领域事件的发布和订阅。通过事件总线和消息队列实现异步数据传输,实现微服务之间的解耦。
领域服务
领域服务位于领域层,为完成领域中跨实体或值对象的操作转换而封装的服务,领域服务以与实体和值对象相同的方式参与实施过程。领域服务对同一个实体的一个或多个方法进行组合和封装,或对多个不同实体的操作进行组合或编排,对外暴露成领域服务。领域服务封装了核心的业务逻辑。实体自身的行为在实体类内部实现,向上封装成领域服务暴露。
- 为隐藏领域层的业务逻辑实现,所有领域方法和服务等均须通过领域服务对外暴露。
- 为实现微服务内聚合之间的解耦,原则上禁止跨聚合的领域服务调用和跨聚合的数据相互关联。
基础服务
基础服务位于基础层。为各层提供资源服务(如数据库、缓存等),实现各层的解耦,降低外部资源变化对业务逻辑的影响。基础服务主要为仓储服务,通过依赖反转的方式为各层提供基础资源服务,领域服务和应用服务调用仓储服务接口,利用仓储实现持久化数据对象或直接访问基础资源。