1. 领域驱动设计
微服务开发的首要挑战:
把大的、复杂的应用拆分为小的、自治的、可独立部署的模块。
如果没有正确的拆分,那么结果就是一堆浆糊,有着单体结构的缺点,和微服务结构的复杂度,可以称之为分布式单体。
幸运的是,Eric Evans 为领域驱动设计提出了大量的最佳实践和经验技巧,有3个核心思维:
- 开发团队要和业务部门、业务领域专家紧密合作。
- 架构师、开发人员、领域专家应该先做出战略设计:找出边界上下文、核心域、子域、上下文映射关系。
- 架构师、开发人员根据战略设计梳理出一套核心构造块:实体、值对象、聚合等等。
把一个大型系统划分为核心域、子域,再把核心域、子域映射为微服务,这样我们就可以得到一个理想的松耦合微服务体系。
2. 每个微服务一个数据库
微服务模块结构设计好了,下面一个重要问题就是怎么处理数据库,各个微服务是否共享数据库呢?
如果共享,将导致微服务之间紧耦合,违背了微服务的松耦合原则。数据库中一个小小的变动就需要各个团队同步修改。
如果每个微服务都有自己的数据库,那么微服务之间的数据交换将非常麻烦,就像打开了潘多拉魔盒,跑出一堆问题,例如在多个服务中管理事务。
所以,很多人主张共享数据库。
但是,微服务是持续的、长期的软件开发,每个微服务应该有其自己的数据库。
3. 微前端
很多后端开发者轻视前端,认为太简单。
大多数架构师也是后端出来的,在架构设计中对前端不够重视。
导致现状就是,后端模块化做的很好,而前端还是一整坨。
前端单体结构和后端单体有一样的问题,所以前端也需要进行现代化的改造。
现在的 web 技术简单、强大,例如 web 组件、Angular/React。
4. 持续交付
每个微服务可以独立部署,是微服务架构的核心优势之一。
比如你的系统包含 100 个微服务,现在有一个需要更新,那么你可以只需要发布这一个,而另外 99 个不需要动。
这就需要 CI/CD 和 DevOps,如果没有这套自动化流程的话,就像拉着手刹开法拉利。
5. 可观察性
微服务架构简化了开发,但复杂了运维。
单体结构是非常便于监控的,但在微服务架构中,服务很多,而且通常是跑在容器中,对整个系统的监控就变得非常复杂。
需要把所有容器、机器中的日志聚合到一起。
幸运的是已经有成熟的解决方案,例如,使用 ELK/Splunk 处理日志,使用 Prometheus/App Dynamics 处理监控。
还有一个比较重要的方面:调用跟踪。
微服务间会产生级联调用,为了分析系统延迟,就需要测量每个服务的延迟,Zipkin/Jaeger 提供了这个能力。