1 微服务设计背景
在系统设计之初,业务并没特别复杂, 采取单一架构即能确保快速开发快速上线. 然而随着业务需求越来越多, 这种集中式开发就严重拖慢了整体效率. 每一次新增或者修改功能都会涉及老的代码或者说涉及到其它系统的代码, 导致开发和测试周期变长, 并且发布的时候影响线上业务. 开发人员,测试人员以及发布人员都需要小心翼翼才能确保线上功能正常. 这和一个快速发展的公司节奏严重相悖, 在互联网时代很容易被淘汰.
出于以上考虑,公司规划逐步去优化系统架构来适应需求的快速变更. 容易想到的就是组件化然后是多服务, 多服务更加独立, 在人员以及程序上更显得独立, 相互之间影响比较小, 开发上更能聚焦, 发布也可以最小化. 然而如何拆分服务, 服务之间应该如何通信, 监控系统应该如何设计, 以及人员组织结构应该如何安排, 都与以前集中模式不一样, 需要谨慎的去规划.
这篇文章我从微服务的几个方面去分别展开去详细解释.
2 微服务概念
参考James Lewis对微服务的定义: 简而言之,微服务架构风格[1]这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。
在谈设计风格时候一般从构件,连接件, 以及这些构件和连接件之间的拓扑关系来分析. 从构件上来看, 组成微服务的各个构件是通过业务来划分的各个服务. 连接件通常是通过http这样的api相互通信, 或者独立设计一个消息事件系统来解耦各个服务之间的依赖, 例如kafka来连接生产者和消费者之间的通信. 这样设计的好处是各个服务相互之间低耦合, 每个服务的开发可以采取不同的语言, 发布更新的时候只要保持对外接口不变可以独立发布, 各个流程都相对更聚焦.
然而各个服务之间组成的拓扑关系就容易形成网状,出现问题不好排查, 比如其中一个服务宕机可能会导致整个服务的雪崩, 因为每个服务都可能会直接或者间接依赖到它. 如何设计出可扩展、高可用、容错性强的服务变得很重要, 另外也更加需要良好的监控系统, 监控每个业务流程的在各个服务的执行步骤, 方便定位线上问题.
微服务带来好处的同时也提出来了相应的挑战.作为一个架构师更应看到微服务所需要的这些质量属性.
3 微服务之企业文化
借用《软件系统架构:使用视点和视角与利益相关者合作》,里面提到的理念也是这样说:系统架构的目标是解决利益相关者的关注点。利益相关者的关注点是有可能冲突的,比如管理层(可管理性)vs 技术方(性能),业务方(多快好省)vs 技术方(可靠稳定).反过来讲, 一个企业的组织沟通方式一定程度上决定了架构的风格, 如果违背这个组织沟通方式, 搭建起来的架构导致效率并不高.
正如康威定律所说“设计系统的组织,其产生的设计和架构等价于组织间的沟通结构”.如果团队按照职能分, 比如数据库团队、业务后端团队、业务前端团队、测试团队, 那么一个业务就要涉及多个团队的协调, 如果公司文化导致团队之间壁垒比较深, 那么甩锅现象会屡见不鲜, 开发效率也会大打折扣, 冲突也是家常便饭. 如果团队按照业务功能来分, 部门之间的壁垒就会被打破, 相对来说各个部门之间扯皮的事情就会少很多.
然而现实中更多的是按照职能来划分.按照业务功能来划分, 要么要求一个人有很强的技能, 能在前后端、测试、发布等流程都非常熟悉, 要么公司提供一个类似中台的平台, 非常方便开发人员来开发、发布、测试等. 按照职能来划分, 相对责任更明确, 对程序员要求相对更少一点, 同时我认为相对重要的是职能上来划分方便管理, 公司结构相对稳定, 不至于出现一个人出了问题而影响了整体.
从利弊来看,各有好处也各有不好的地方, 很多企业往往会采用两者结合的方式来解决. 对于变化不大的功能还是按照职能来划分, 对于变化较多的业务, 可以采取临时抽取各个部门的人员组成一个小组, 最好是让他们自己能积极参加. 变化不大的基础功能部门提供方便开发人员的稳定接口或者提供能够自动发布的平台给开发人员, 通过自动化以及稳定性减少部门之间的沟通消耗. 当然公司的绩效考核方式就不能统一以职能划分的模式来评估, 根据不同的需要采取灵活的评估. 一个良好的绩效考核模式要反映企业倡导的组织结构模式, 否则长久不下去.
4 微服务之容错设计
微服务概念中,各个组件是通过restful api相互通信, 这就造成了一个服务出现问题, 可能会引发其它服务不可用. 通常有很多机制来保证服务的可用性, 例如超时机制, 限流,降级,延迟处理, 熔断可以处理这些情况.
从调用方来看可以采取一些简单的措施,比如设置超时机制. 超时是主动设置一个超时时间, 如果在指定时间内被调用的服务还没返回, 就主动放弃, 防止被依赖的服务影响.
如果想在调用方采取相对智能的方式,调用方也可以采取熔断机制, 调用方监控服务的状态, 如果在一段时间内服务状态不可用, 就降级为本地接口来服务, 过一段时间检测服务恢复了, 就可以恢复服务.
在被调用方,可以根据自己的能力来设置最大上限, 如果超过上限就拒绝服务. 限流是用来防止请求超过了服务处理的上限导致服务不可用而采取的一定措施, 通常有时间窗口、漏桶、令牌方式来限制流量. 或者在服务前架设类似nginx的容器来限速.
被调用方除了可以采取限流来避免服务不可用,也可以采取服务降级的模式, 比如只提供核心服务或者只提供vip用户的服务.
除了调用方和被调用方可以采取策略外,也可以引入一个中间层来缓存消息, 避免生产者服务的消息直接打入消费者的服务. 例如常见的公司会利用kafka来消峰.
5 微服务之其它问题
微服务还有很多设计层面的问题可以讨论,比如采取什么样的通信方式比较好, 数据集中管理还是分布式管理, 如何监控微服务的状态, 如何设计高可用、可扩展、一致性的服务. 后面可以详细谈谈. 不过我想强调一点的是, 架构师在关注性能、高可用等质量属性的同时, 设计也应该注重是否容易理解, 是否方便后续维护以及调试和成本问题. 好的设计师是在考虑各方利益的情况, 做出的一个取舍, 也许设计师有的时候更多是做政治选择问题, 政治利益决定了架构的走向. 有点想远了, 目前做好技术上的事情, 政治选项交给他人来决定.
6 引用
https://www.javazhiyin.com/38827.html//容错隔离
https://my.oschina.net/yu120/blog/1790398 //降级
https://my.oschina.net/yu120/blog/1790398 //降级
https://juejin.im/post/5ad05373518825619d4d2f00 //熔断的原因
https://www.infoq.cn/article/every-architect-should-study-conway-law //康威定律
https://mp.weixin.qq.com/s?__biz=MjM5MjEwNTEzOQ==&mid=401500724&idx=1&sn=4e42fa2ffcd5732ae044fe6a387a1cc3#rd%E3%80%82%E5%A4%9A%E4%BA%A4%E6%B5%81%EF%BD%9E // James Lewis微服务讲解
网友评论