架构师论文之微服务

目录

摘要

本人所在的单位是致力于为铁路和地铁提供技术服务和解决方案的研究机构。近年来由于地铁建设的不断扩张,线网式的管理日益受到了重视,为网络化运营的前提下,应对不同线路运营公司不同专业和不同的承包厂商,多个维度的应用的快速开发和集成,以及持续的进化的难点。需要设计新的适合场景的架构。在这样的背景下,2020年初某某城市地铁公司联合腾讯作为伙伴,一起派出人员组成了联合工作组,在线网智能运维项目中,推行以微服务为主的架构设计,业主同时提出解耦各专业厂商的应用和降低运维成本的要求。本人有幸加入在工作组中,主要负责了穗腾OS的架构设计和负责轨检专业的微服务集成工作。

联合小组最终开发出来的穗腾OS平台,它依托于腾讯云的paas。功能包括:协助各厂商接入智能运维平台,支撑了微服务的全面落地。此外还包括了地铁运维数据总线和算法/组件市场等子系统。本文着重从微服务的角度展开讨论。

正文

2020年某某城市的地铁线网智能运维平台开始建设。它被赋予线网级的综合监控和协调管理。这就面临着去集成既有的、已建设完且正在运营着的地铁线。以前建设此类平台的做法是依赖业主的铁腕,要建设的平台一般在业主的组织下与一家家的专业厂商谈接口协议,再开发调试,串行的去适配各家的单体应用。最后上线的运行效果且不说,耦合紧,工期长,变数多,后期维护成本高。面对这些待解决的痛点,联合小组提出了微服务为主的建设方案,各专业厂商的微服务需要接入穗腾os平台。在本文中首先介绍一下微服务的技术,再介绍微服务在项目中的用武之地—穗腾OS平台,最后结合实践的经历,阐述一下微服务的设计,服务治理和运维以及开发工具链。

首先,微服务是由Martin fowler最早提出的。它是SOA面向服务组件模型的一种实现,但它与同为分布式的esb企业服务总线不同,在微服务中服务提供者(provider)和服务消费者(consumer)之间并无转换和中间层,是去集中化的。同时服务提供者也可能是其它微服务的消费者。它允许各微服务以各自独立的技术栈开发。要加入智能运维平台的各专业厂商要横向拆分功能,以细粒度的组件方式提供。采用轻量级的协议。穗腾OS支持了HTTP/REST和dubbo等。微服务有小独轻松的特点,小不仅指拆分后的微服务灵活和功能单一,还指微服务的开发团体以小规模为佳,一般厂商团队都在5~7人,他们是特性团队,对微服务有着全生命周期的负责,包括设计开发、测试部署和交付。这和敏捷方法所倡导的理念高度契合。除了对团队规模要求不谋而合外,敏捷方法和微服务的初衷都是快速上线,尽早获得用户的反馈。而相信读者也能看出瀑布式的过程模型也由于自身原因很难实现细粒度单元的快速,流畅的交付。独的特点体现在独立的部署和交付,每个微服务也独立运行在各自的进程空间中。轻是指微服务的API无关性和使用HTTP和REST协议。解决了典型的RPC存在的调用者耦合问题。同时能快速搭建访问资源类的应用服务。REST把资源URL标识且在规范的http协议下设计操作(post、delete、put、get)。最后松是指松耦合,易复用。在穗腾OS运行时,提供了一些厂商级的公共微服务,比如身份认证,数据字典查询等。只要厂商提出调用申请,联合工作组开通其权限,厂商通过token凭证等信息即可使用。不然,如果项目中空调、电源、网检、轨检都自己去开发认证鉴权功能,将是极大的浪费,也不符合软件工程的思想。

穗腾os平台是paas,也就是厂商微服务部署和管理平台,智能运维平台应用的支撑环境。为方便厂商的微服务开发人员上手,本人带领联合小组开发了系列的demo模板工程, Java技术栈和GO语言使用的SDK,都能指导厂商接入穗腾os云生态中。同时作为架构师,我在设计架构时,预见到了当微服务接入的服务越来越多时,对某些核心微服务的调用依赖便达到极限时,可能会出现雪崩效应,如果应用间触发链式反应,受其影响的全线智能运维平台可能都会瘫痪。除了在服务治理的容错上设计外,本人提出用专业的消息中间件来作为基础设施向有场景需求的厂商提供,我们梳理了重要的场景,尤其是聚合根或事件源角色的微服务。也规范了中间件的使用制度。小组最终采用了本人的建议选型了kafka作为中间件布设在车辆段(地面中心)和车载的网络中。从厂商应用的角度设计了角色主题的命名规则,也就是topic。以网检的topic为例,18-wangjian-01的格式。18指线路号,拼音指业务分类,最后为专业厂商的业务通道标识。这样消息的订阅者就可以有的放矢地领取消息了,避免了冲突。专业厂商获取专属于自己的业务范围的消息,这也是安全性的角度考虑。

下面从具体专业厂商的角度来讲解微服务实践。探讨微服务的设计或拆分,微服务的治理,开发工具链和运维。在指导轨检专业集成时,本人借鉴了DDD(domain driven design)中一些设计方法。事实上ddd的提出更早于微服务。它主张以业务领域设计来主导整个开发活动,这对领域模型准确性要求非常高。在此基础上,不同的界限上下文中允许出现重复的实体(事实上实体在不同子域中侧重面不同)。DDD是打通问题分析域和解决域的一种创新。正所谓,德不孤,必有邻。DDD和微服务相结合,就像如虎添翼。把单体程序垂直拆分细粒度单元时,识别子域很重要,每个子域内众多微服务围绕着一个聚合根,并由其对外接口。内部业务单一,内部细粒度单元则是职责单一,借鉴了设计类的单一职责原则SRP。轨检专业分车载机检和人工巡检。前者有人工智能算法配合激光相机的帧图采集,后者人工经验比重高,自动化程度偏低,但两个子域分立后有些重叠的部分。在ddd中一般用两种手段再细分,如果重叠部分是一些操作过程,那么抽取出来变成领域服务,一般领域服务命名是动词开头。另外情况就建模为对象。具体是建成实体对象还是值对象。可以再从数据的唯一性角度分析。在项目中,把里程纠正作为是机检和巡检都依赖的领域服务去实施的。

在子域或者说界限上下文中,有地方也分翻译成限界上下文。总之子域内业务是单一的,细粒度单元中职责是单一的,遵循SRP。如果不是这情况,那么的原因就是未达到细粒度的拆分标准,需要重新审视一下,重新分析过程。

在界限上下文中存在上游和下游微服务如何集成问题,这时ddd的建议是用分层的技巧。可以参考某些资料,理解下何为通用协议层和防腐层。一般上游对下游的接口用up通用的协议来设计,比如以rest对外资源接口。而下游去支撑上游业务流程调用时,要开发出防腐层。ACL的建设手段可以应用门面设计模式,或者设计隔离适配层。acl的设计可大可小,用来适配遗留或外部的系统接口。它的作用既保护好自身领域模型免受侵害,又确保不同域在未来保持分离。本人在指导厂商设计微服务时也给出了其他的参考意见。如下:一,根据io的类型是读密集型还是写密集型来分类拆分。二,消除循环依赖和让核心微服务不受非核心微服务的异常影响。即核心不要依赖非核心微服务。三,根据非功能属性拆分服务,比如复用性、资源一致性、部署升级频率、伸缩性等。项目中,轨检中建设加密狗的业务环节时,由于具体需求当时尚未敲定,于是把变动性最高的环节独立设计成微服务,后期时方案成熟即替即用。对于微服务应用中最核心的环节就是服务的治理问题。它包括服务的注册、负载平衡、配置中心、容错。而容错中又细分有限流、超时、隔离和熔断等特性的。在脱离穗腾os平台的生态前提下,最合适的开发工具链则是spring cloud全家桶。它作为Java语言的解决方案,可选的注册工具有euroka和noca(阿里bb开源的)。注册/配置中还有consule。配置中心可选 spring cloud config。方便在测试环境、类生产环境和真正生产环境集中管理,灵活切换各种配置文件。网关建设应用zuul。Ribbon是一种客户端的负载平衡,他和euroka可以配合使用。在容错方案中spring cloud全家桶中的hystrix结合设置阀值的技巧,能帮助微服务在高并发出现时,在核心微服务上包装断路器暂时中断服务,待高峰过去再自动恢复。断路器是用三种状态,有打开、关闭和半开,专门处理线程耗光时的调用问题。同时,也可以设置阈值来保护微服务不被恶意调用。然而在本项目中,穗腾os平台在支持主流的spring cloud微服务生态时,也支持dubbo的RPC协议。厂商的服务如果是基于spring cloud开发的,那么在部署时需要适应性的维护。包括:从euroka注册方式改造到穗腾os的注册方式。这时需要调整的是 pom.xml文件。同时配置中要禁用hystrix,以便让腾讯的容错特性来接管。这些上线前的技术支持,联合工作组都会派出人员悉心的帮助。当部署交付到穗腾OS平台后,厂商团队也渐渐感受到了微服务结合云的一些利好。比如使用穗腾os封装好的调用链追踪,可以图表化展示微服务的运行情况。因为每次对微服务的请求都记录了日志,随时都可以溯源。同时穗腾os还支持容器和虚拟机/集群两方式的部署。如果用docker容器的,推荐仓库式的运维的特性,让用过git的开发工程师立刻解锁新技能。用docker push/pop命令一键部署和拉取云上的容器。而对于运维工程师,也能轻松激活devops的流水线生态中的方案。

就像操作代码仓库一样, 用docker push/pop命令一键部署到云。这些都是降低了运维的成本,也提高了devops的生产力。

项目最终成功上线,应用于某某城市地铁18和22号线上,解决了地铁业主提出的解耦各厂商应用和降低运维成本的两个问题。同时许多优秀的算法和组件在平台上涌现和沉淀。随着穗腾os2.0的商业化推广,新的架构模式在轨道交通行业方案中占有了一席之地,更多的红利会渐渐回馈开发者,开启双赢模式。同时冷静客观的看待微服务技术,还是仍然存在有待改进的地方。比如调用的响应速度,分布式下的事务和数据一致性的方案较复杂,调用链追踪技术还要有待发展。所以说流行的架构也不是万能的,不能脱离场景而选择架构,希望同僚们理性分析需求场景,更希望大家能共同健全微服务的生态。