在今天,微服务对于包括中小企业在内的众多互联网企业来说绝对不是什么新鲜技术,各种优秀的框架、工具、方法和实践经验触手可得。然而微服务并非对所有的企业都一样“平等”、“友好”。由于不同的起跑线和启动时间,让互联网企业已借助微服务等新兴技术逐渐拉开了与传统企业在业务支撑、客户服务、产品创新等多方面的距离。对传统企业而言,怎样才是正确打开微服务的姿势,如何让业务转型发展与技术相匹配,是极为迫切需要解决的问题。 在近两年的时间里,我和同事们致力探索这一诉求的解决方案。本次把我们的实践经验与大家分享,希望对大家有所启发和帮助,更希望各位朋友能不吝赐教。 分享的内容来自在这两年中建设海信商业云平台产品的一些经验体会。这一平台产品面向的用户包括我们公司自己和商业零售领域的有一定规模的客户。 目前平台已投入生产,并支撑了包括商业中台、无人店、商业管理云平台、商用设备云等一系列云原生类产品的研发和运行。 在大家的印象中,海信就是一家传统的大型制造业企业。我们公司是海信集团IT板块的一家子公司,主要业务面向商业零售企业提供硬件+软件的信息化解决方案。 作为一家有近30年历史的IT公司,从一般概念来看我们确实需要归入传统IT企业的行列了,而我们的主要客户也很多是传统企业客户。 因此本次分享主要从传统企业落地微服务的视角展开讨论,可能有些认识不一定正确,欢迎群里大牛批评、指正。
传统企业微服务落地的挑战
谈到传统企业落地微服务,先和大家讲个段子,来自前几天和同事没事瞎扯,请大家千万别对号入座。 当时几个小伙伴说如果把微服务建设比作拳击运动,那不同类型企业的情况大致是这样: 大型互联网企业就像重量级拳手,通过自主研发、深度定制,实现极为恐怖的性能、容量、可用性等方面的攻击输出。 中小型互联网公司就像轻量级拳手,基于最新技术,打法灵活、敏捷,让人应接不暇,耳目一新。 至于传统企业,怎么说呢,好像更接近为残疾人参与拳击运动: 是变态的道德沦丧,还是身残志坚的人性光辉——这件事情是存在较大争议的。 这是因为微服务落地需要的是:
-
匹配的组织架构
-
实力雄厚的技术团队(包括开发 / 测试 / 运维)
-
清晰的业务边界
-
传统企业的原有技术团队技术与微服务技术要求不匹配 。一些企业会以原有技术团队的成员为主,参与微服务产品开发。但很多传统企业原有的IT系统甚至是使用Delphi甚至Powerbuilder编写的CS架构的产品,与目前的主流技术脱节几十年。对原有的技术人员来说,转型微服务开发,难度可想而知。当然这些陈旧系统的弊病也是传统企业切换到微服务的主要动力之一。
-
传统企业组建符合微服务要求的新技术团队的难度很大。这是另一种传统企业的组件微服务团队的思路,也是很多成功转型的传统企业的做法,但是在原有的人力资源招聘体系下,对传统企业而言,找人、识人、用人、留人没有一处不难。尤其是在二、三线城市的企业来说招不到合适的人是现实的常态。
-
交付效率问题。由于对微服务的框架、工具、架构理念都不熟悉,对项目的时间计划和资源需求评估与实施情况脱节验证,引发管理层的极大不满。
-
交付质量问题。由于设计、开发、测试、运维等方面的问题,微服务架构的产品在功能和非功能质量方面有时甚至都不如原有的老旧系统,让管理层对微服务的产品产生不信任感。
-
持续治理问题。产品上线后,虽然频繁变更,但主要原因是弥补技术复杂性引发的缺陷,反而对业务的支撑更为不足。同时,由于缺乏专业的服务治理,很多缺乏合理规划简单修补工作,往往引入更多问题,恶性循环。
-
选择并扩展适合传统企业的微服务框架。
-
针对传统企业短板提供的配套工具。
-
从标准化和自动化的角度提升开发效率和质量。
-
为服务治理打好基础,促进良性迭代和持续改进。
今天,建设微服务架构的产品,已无需从零开始。即使在两年前我们刚启动平台项目时,也有不少微服务框架可以选择了,包括Dubbo、Spring Cloud、Kubernetes等这样的人气框架。在众多框架中,我们选择以Spring Cloud为主体来建设我们平台的微服务框架。 关于Spring Cloud的介绍以及和其他框架的对比的文章在网上很多,这里也不再重复。从现在看来总体是令人满意的选择:
-
首先,Spring Cloud不仅是Java Stack的,而且是Spring的亲儿子,Spring这杆大旗的群中基础太好,懂Java和Spring的开发者应该是目前二三线城市的传统企业最容易招的人了。
-
其次,Spring Cloud+Spring Boot的方案,对Java程序员来说上手也比较容易。
-
再次,从后续发展趋势来看,Spring Cloud还是比较好的,社区热度不错,周边生态也,升级、改进与主流技术发展的趋势也是匹配的,像近期的F版本的响应式编程、Serverless的支持等。
-
各个版本都有一些坑和BUG,尤其是早期的几个版本。
-
熟悉Spring Cloud的开发和配置约定,尤其是一些潜在约定需要耗费入门开发者的大量精力,这些问题经常导致开发任务的时间评估不可信,里程碑结点无法保证等状况。
-
框架各组件对传统企业开发者而言过于松散,摸索框架组件整合的最佳实践需要投入好很多的精力。
-
对国内开发者而言,部分组件有更好的替代
-
仍不够完整,还需要引入其他组件。
-
性能影响较大,性能影响随着线程数量的增加而变大。经过测试发现对吞吐量的影响:skywalking < zipkin < pinpoint。
-
不支持Undertow的springboot。
-
Pinpoint的存储使用HBase,对于我们的技术部件来又增加了一个新的挑战。SkyWalking是基于Elasticsearch存储。
-
能够与Spirng 事务良好结合
-
支持Saga/TCC及基于消息的最终一致多种分布式事务解决方案,并易于扩展
-
具备人工干预的手段
-
框架组件管理功能的可视化,如网关、配置中心等,从而降低管理、配置的复杂性和出错率;
-
引入Elasticsearch Grafana做日志统一管理监控;
-
基于异步消息的服务Metrics信息聚合;
-
提供了分布式缓存、分布式ID生成器、分布式锁等常用的技术服务及配套SDK。
微服务的落地离不开敏捷开发、DevOps,容器化的工作。今天,实现这些目标的工具链已经基本完备、打通,拿来主义即可起到很好的效果,比如Kubernetes + Docker、持续集成、部署等。 但是,对传统企业而言微服务、敏捷、DevOps的实施的最大冲击在于对软件质量把控上。按传统研发中的质量保证体系和人员在新模式下往往无法适应。 我们在实践中认为以下的几类工具的引入对传统企业来说是有价值的: API自动化测试工具 在敏捷开发、DevOps的过程中,对传统企业来说,最具挑战的是自动化测试。原因除了原有测试管理流程的问题外,主要是测试人员大部分只具备人工测试的能力,对测试编码、工具都不熟悉。 但缺失了自动化测试,在频繁交付、发布的环境下,软件质量的控制是很难的。尤其是在微服务架构下,以前测试人员手工进行黑箱测试的模式,发现产品质量缺陷非常有限。针对这一问题,从API测试的自动化和可视化入手,是一个具有很高成本收益比的方案:
-
比界面手工测试可以覆盖更多的测试点。
-
偏向于站在用户的角度测试,对开发人员、测试人员都很有价值。
-
成本比实施自动化单元测试更低。
-
测试资产可积累重用,效益随系统复杂度同步提升。
微服务设计开发提效
实现同样功能的微服务产品比传统架构产品需要投入更多的设计、开发工作量,频繁的变更和紧迫的交付要求更是让研发团队的压力很大。 对传统企业而言,这点更为突出,甚至是时间看上去较为充足的项目,也很难在保证质量的前提下按时交付。 针对这种状况,我们认为努力方向无非是标准化和自动化。其中标准化是自动化的前提。 大多微服务标准化的讨论集中在微服务治理框架技术、访问协议等微服务间的标准化问题上。 但对开发提效而言,微服务内部实现层面标准化工作有可能会取得更显著的效果,毕竟框架已定的前提下,日复一日的主要是微服务产品的设计、拆分和各个微服务的实现工作。 确定这类标准,首先需要找到微服务的内部架构中比较稳定的功能结构单元。这是因为微服务的粒度是不稳定的。 这种不稳定性一方面体现在一个微服务架构的业务系统会存在多种拆分微服务服务的方案,另一方面随着业务系统的不断演进,每个微服务还存在进一步拆、并的可能。 这一特性本是微服务的优势,记得有人说过SOA和微服务的一个区别在于,SOA让服务重用更为便利,微服务是服务重写便利。 我们谈到的标准也必须为这种优势服务而不能成为障碍。 实践中我们认为以DDD的方法为纲,辅以大家经常提到的康威定律、AKF原则、Netflix识别原则等标准是比较合理的。 回到刚才的话题,从DDD的视角来看,我们的认为微服务中相对稳定的结构是聚合(Aggregation)。微服务会拆分、合并,但一般说来微服务的粒度是>=单一的聚合的。 因此我们将聚合视为更为稳定的业务原子,从聚合的角度去梳理我们微服务设计实现标准,包括把聚合间的访问策略、数据一致性原则、事务处理模式等设计约束规范化下来。 为了进一步提升开发者效率,我们基于Jenkins、Freemaker、Swagger都能开源工具实现了一套微服务应用开发的脚手架工具,工具有Idea插件版本和WEB版本。可以可视化完成项目代码(包括包括模型、DTO、API)、依赖配置、应用配置、接口文档、数据库脚本的自动生成工作。
面向服务治理的微服务模型化
微服务一大吸引力可能就是敏捷灵活的重构改进,从而不断满足业务转型、高效创新的企业战略。 然而实际上微服务框架、工具只能提供微服务生命周期中的基础技术支撑。微服务后续合理的重构、拆分、合并,对缺少新形态业务运营经验和服务治理经验的传统企业来说是非常困难的事情。 Gartner报道过,在超过50个服务的项目中,大于80%项目失败主因是缺少治理机制。管理大师彼得德鲁克说过,“你如果无法度量它,就无法管理它(请允许我偷换一下管理和治理的概念)”。当然,在度量前我们必须考虑对微服务进行模型化的描述。 在这一问题上,我们与哈工大的企业智能计算实验室合作进行了研究和实践,感谢哈工大给予的强有力的理论支持。让我们认识到微服务的结构化描述和模型化的潜在价值。由于时间关系,这里仅仅介绍一些服务模型的形式化定义,希望对服务模型抽象有兴趣的伙伴有所启发。 微服务构件的结构化定义 微服务构件SC =(SCID,R,DS,Config,f<sub>E</sub>,f<sub>P</sub>,f<sub>R</sub>)。 Scid为其唯一ID,R为该构件的访问规则,DS是构件的,Config为构件的个性化定制描述,fE为访问构件的解析函数,fP为构件对外提供服务的集合,fR为构件运行所需的服务集合。 微服务构件的复用度定义 构件的复用度为SCR =(fx,Ω),其中fx代表fP或fR,Ω代表所有微服务构件组成的空间。通过复用度可以描述微服务构件的应用层次高低和适应业务需求变化的能力。 原子微服务构件 SCatom = {SCID,φ,DS,φ,φ,f<sub>P</sub> , φ}。表明此服务组件是非组合且不可定制的。只能对外提供标准统一的服务。 框架微服务构件 一个SC称为框架构件SCF,当且仅当构件提供的服务的复用度为1,组件依赖服务的复用度\<1。 非框架构件我们称为业务微服务构件SCB。 基于这样的模型我们可以更好的描述服务,针对不同类型的微服务制定不同的治理策略。不仅如此,基于数学化的描述也可以进一步使用本体推演、π演算、Petri网路等服务演算手段自动化的完成一些服务治理及治理辅助工作,如智能化的服务推荐、评价、调度、扩展、拆分、组合等。
Q & A
Q:想了解下分享中提到的API自动化测试工具是基于什么实现的? A:没有脱离SpringCloud技术栈,主要使用RestTemplate和HttpClient,使用Ribbon做负载均衡。 Q:灰度发布是如何防止同一用户,有时候被路由到新版本,有时候被路由到老版本的? A:配置灰度发布路由策略,策略内容是用户和服务版本一对一的映射关系。 Q:灰度发布方案怎么处理新老版本的数据问题,比如新的版本访问的是表结构有变化的表,怎么把数据同步过来使用的,在不停机同步DB的情况下? A:灰度发布前就需要做好新版本数据准备。我们是使用Otter做的在线迁移工作,工具支持数据的转换。不过灰度发布更适合场景是升级而不是换代,适合小步快跑的交付方式。如果真的数据模型变化太大,仅仅凭借灰度框架和数据迁移工具很可能就不够了。
Kubernetes入门与进阶实战培训