flyingnet 2019-06-28
微服务实战(一):落地微服务架构到直销系统(什么是微服务)
网上有很多关于微服务的文章,从不同的维度对微服务进行了相关的讲述;有些高屋建瓴,有些涉及细节,有些侧重理论,有些侧重代码,都是非常不错的了解微服务的文章。
我们这个系列的文章的维度主要是实战落地,也就是我们在平常工作以及产品开发过程中,考虑为什么选择微服务架构风格,以及如何将微服务的架构风格落地到我们实际的一个大健康行业直销电商系统的主要过程。本文涉及有少量理论的部分,主要是架构与实现的层面,让大家真正对微服务能了解、能认识、能实现。
本系列文章从“DDD实战进阶第一波”系列继续。如果你对我们落地的系统的需求以及DDD不是特别了解的话,建议你先查看我们DDD实战进阶第一波的文章,因为DDD是微服务架构风格的一个重要组成部分,而且本系列的需求和代码会紧接着DDD实战进阶第一波。
微服务这几年很火。其实一种概念或一种架构风格的兴起,一定有它背后的原因。我们在这里不讲所谓高大上的理由,而是讲我经过将近18年的软件设计与开发工作,在有选择性的成功使用了微服务架构风格的体会。
微服务架构风格的兴起,主要是因为客户对现代化的产品和系统的需要,对软件开发本身提出了更高的要求。
1.服务独立性:
一个系统通常在设计时,架构师(或项目经理)会根据对需求的理解划分为设计上的多个界限上下文,每个界限上下文包含本界限上下文需要的领域模型。在实际开发过程中,会主要出现以下几个问题:
a.多小组并行开发:在一个大型系统中,界限上下文会分给不同的开发小组进行开发。有些界限上下文之间在业务上有依赖关系,但我们在技术上也做了依赖。比如订单界限上下文依赖产品界限上下文或客户界限上下文,这样通常要先实现被依赖的对象或功能(至少要先定义出来),才做依赖它的功能,影响开发的效率。
b.部署与运行的问题:因为存在依赖关系,所以被依赖界限上下文的组件发生变化时,该组件还要更新到依赖它的界限上下文中,管理复杂。而且一旦被依赖的界限上下文出现问题,依赖它的界限上下文也会出现问题。服务独立部署到不同的主机或Docker上因为存在引用,也会对管理和部署上带来障碍。
c.技术选择的问题:因为技术上存在依赖关系(通常是通过引用),所以多个小组采用的技术通常是相同的。但在某些情况下,界限上下文应该选用最适合它的技术,而且界限上下文之间也不应该通过Restful风格的接口互相访问。
2.高性能大并发:
现代的互联网应用,需要支持大量用户的并发访问操作,传统的经典开发方式,会主要出现以下几个问题:
a.用例接口的直接暴露:通常我们会将功能暴露成接口,而接口通过调用应用服务(应用服务协调仓储和逻辑)完成用例功能,如果逻辑复杂,数据库访问负载大,特别该用例通过事务同时操作多个数据访问上下文,速度会很慢,很长时间才给前端返回结果,如果用户多,该问题会被放大。
b.查询的问题:一个界限上下文除了用例的功能,通常我们会有很多查询的功能提供给用户。通常我们会将一个界限上下文的所有功能都做到一个Api项目中,另外业务和查询使用的模型是同一个,这样也会影响性能。
3.事件溯源与最终一致性:
在大并发的系统中,我们不能使用事务来保证强一致性,因为这样会影响性能,我们应该采用多界限上下文的最终一致性来保证数据的正确。
a.传统的经典开发方式,无法实现最终一致性的主要原因是没有记录一个对象变化历史的事件信息,所以当我们在通过非事务同时更新多个界限上下文的数据时,当需要回滚先更新界限上下文的对象数据时,不知道该对象的历史状态,也就没办法还原。
b.业务单据的历史修改信息:通常在业务系统中,我们有需求需要知道一个对象(比如一张单据)的历史修改记录时,因为没有记录事件数据,所以无法很好的跟踪对象的历史变化状态。
4.服务的高可用行:
现在对服务的高可用要求越来越高,我们应该尽量保证应用提供的服务可用,否则会丢失用户,造成业务损失。服务的高可用通常会由于以下两个方面原因引起:
a.数据库服务或数据库down掉、数据访问网络连接中断。
b.WebApi网络地址不可用、WebApi访问负载大、对用户的请求响应异常。
为了解决上述的开发过程、部署过程以及运行过程中的问题,我们需要一种新的架构风格来指导产品的开发、部署与运行。这种架构风格就是微服务。微服务架构风格提出以下几个要求来解决上述问题,并应对用户与市场对我们的产品与软件提出的更高的要求。
1.通过构建EDA(事件驱动的架构)并结合消息总线,解决服务独立性的问题。
2.通过构建CQRS(命令查询职责分离的架构)并结合消息总线,解决大并发高性能的问题。
3.通过构建Event存储与还原的机制,实现事件溯源,解决最终一致性的问题,也解决业务上有对象历史状态获取需求。
4.通过数据库产品本身高可用行,弹性访问实现数据访问高可用;通过实现WebApi负载平衡、重试与断路器、Api网关与服务中心等方式,实现WebApi的高可用。
因此,我对微服务的定义是:微服务是一种架构风格,它旨在通过将一个大系统分解成多个小系统(DDD中的界限上下文),并通过一系列的架构建议,解决服务独立性、性能、事件溯源与最终一致、高可用性的需求,最终使多个界限上下文能够相互协作,组合成一个为用户提供高质量的服务的大系统。
本系列文章涉及到的技术包括C#、Asp.net core、EF core、RabbitMq、Ocelot、Consul、Docker等。
本系列文章通过直销系统的实际案例,最终将实现如下的两个总体架构图,并将直销系统的业务连接到它们。
QQ讨论群:309287205
微服务实战视频请关注微信公众号:msshcj