欢迎访问Spring Cloud中国社区

《重新定义Spring Cloud实战》由Spring Cloud中国社区倾力打造,基于Spring Cloud的Finchley.RELEASE版本,本书内容宽度足够广、深度足够深,而且立足于生产实践,直接从生产实践出发,包含大量生产实践的配置。欢迎加微信Software_King进群答疑,国内谁在使用Spring Cloud?欢迎登记

海信商业云平台的微服务落地实践

admin · 5月前 · 2797 ·

大家好,非常高兴能有机会和大家分享海信在微服务建设方面的实践经验。

分享的内容来自在这两年中建设海信商业云平台产品的一些经验体会。这一平台产品面向的用户包括我们公司自己和商业零售领域的有一定规模的客户。

目前平台已投入生产,并支撑了了包括商业中台、无人店、商业管理云平台、商用设备云等一系列云原生类产品的研发和运行。

在大家的印象中,海信就是一家传统的大型制造业企业。我们公司是海信集团IT板块的一家子公司,主要业务面向商业零售企业提供硬件+软件的信息化解决方案。

作为一家有近30年历史的IT公司,从一般概念来看我们确实需要归入传统IT企业的行列了,而我们的主要客户也很多是传统企业客户。

因此本次分享主要从传统企业落地微服务的视角展开讨论,可能有些认识不一定正确,欢迎群里大牛批评、指正。

传统企业微服务落地的挑战

谈到传统企业落地微服务,先和大家讲个段子,来自前几天和同事没事瞎扯,请大家千万别对号入座。

当时几个小伙伴说如果把微服务建设比作拳击运动,那不同类型企业的情况大致是这样:

大型互联网企业就像重量级拳手,通过自主研发、深度定制,实现极为恐怖的性能、容量、可用性等方面的攻击输出。

中小型互联网公司就像轻量级拳手,基于最新技术,打法灵活、敏捷,让人应接不暇,耳目一新。

至于传统企业,怎么说呢,好像更接近为残疾人参与拳击运动:

是变态的道德沦丧,还是身残志坚的人性光辉——-这件事情是存在较大争议的。

这是因为微服务落地需要的是:

  1. 匹配的组织架构
  2. 实力雄厚的技术团队(包括开发 / 测试 / 运维)
  3. 清晰的业务边界

不幸的是,以上条件传统企业基本都不达标。

如果抛开企业文化、管理模式不谈的话,其中最大的阻力还是在于人:微服务对技术的要求和团队的技术能力之间存在巨大的差距。具体表现在:

  1. 传统企业的原有技术团队技术与微服务技术要求不匹配
    一些企业会以原有技术团队的成员为主,参与微服务产品开发。但很多传统企业原有的IT系统甚至是使用Delphi甚至Powerbuilder编写的CS架构的产品,与目前的主流技术脱节几十年。对原有的技术人员来说,转型微服务开发,难度可想而知。当然这些陈旧系统的弊病也是传统企业切换到微服务的主要动力之一。

  2. 传统企业组建符合微服务要求的新技术团队的难度很大
    这是另一种传统企业的组件微服务团队的思路,也是很多成功转型的传统企业的做法,但是在原有的人力资源招聘体系下,对传统企业而言,找人、识人、用人、留人没有一处不难。尤其是在二、三线城市的企业来说招不到合适的人是现实的常态。

在这样的条件下,启动的微服务研发项目,经常碰到企业高层无法接受的一些项目失败:

  1. 交付效率问题
    由于对微服务的框架、工具、架构理念都不熟悉,对项目的时间计划和资源需求评估与实施情况脱节验证,引发管理层的极大不满。

  2. 交付质量问题
    由于设计、开发、测试、运维等方面的问题,微服务架构的产品在功能和非功能质量方面有时甚至都不如原有的老旧系统,让管理层对微服务的产品产生不信任感。

  3. 持续治理问题
    产品上线后,虽然频繁变更,但主要原因是弥补技术复杂性引发的缺陷,反而对业务的支撑更为不足。同时,由于缺乏专业的服务治理,很多缺乏合理规划简单修补工作,往往引入更多问题,恶性循环。

针对这些问题,我们认为必须首先解决传统企业微服务落地的起步问题,只有起步相对相对平缓、顺畅与微服务理念无偏差,才能赢得企业对微服务技术的信心、信任和尊重。
这一目标,我们觉得以下几点工作是必须立足传统企业的实情重点做好的:

  1. 选择并扩展适合传统企业的微服务框架。
  2. 针对传统企业短板提供的配套工具。
  3. 从标准化和自动化的角度提升开发效率和质量。
  4. 为服务治理打好基础,促进良性迭代和持续改进。

微服务框架选择与扩展

今天,建设微服务架构的产品,已无需从零开始。即使在两年前我们刚启动平台项目时,也有不少微服务框架可以选择了,包括Dubbo,Spring Cloud,K8s等这样的人气框架。在众多框架中,我们选择以Spring Cloud为主体来建设我们平台的微服务框架。

关于Spring Cloud的介绍以及和其他框架的对比的文章在网上很多,这里也不再重复。从现在看来总体是令人满意的选择:

  1. 首先,Spring Cloud不仅是Java Stack的,而且是Spring的亲儿子,Spring这杆大旗的群中基础太好,懂Java和Spring的开发者应该是目前二三线城市的传统企业最容易招的人了。
  2. 其次,Spring Cloud+Spring Boot的方案,对Java程序员来说上手也比较容易。
  3. 再次,从后续发展趋势来看,Spring Cloud还是比较好的,社区热度不错,周边生态也,升级、改进与主流技术发展的趋势也是匹配的,像近期的F版本的响应式编程、Serverless的支持等。

尽管如此,Spring Cloud对于一家传统企业而言直接拿来落地,问题还是不少:

  1. 各个版本都有一些坑和BUG,尤其是早期的几个版本。
  2. 熟悉Spring Cloud的开发和配置约定,尤其是一些潜在约定需要耗费入门开发者的大量精力,这些问题经常导致开发任务的时间评估不可信,里程碑结点无法保证等状况。
  3. 框架各组件对传统企业开发者而言过于松散,摸索框架组件整合的最佳实践需要投入好很多的精力。
  4. 对国内开发者而言,部分组件有更好的替代
  5. 仍不够完整,还需要引入其他组件。

针对这些问题,我们最终做了如下的选择:

微服务框架选择

其中关键部件的选择原因如下:

API网关

不知是不是受到SOA的ESB的影响,网关几乎是传统企业最关注的组件。

最初网关选型时,我们对比过之前用过的nginx lua、以及kong、Zuul。Zuul在2核8G机器上,进行性能测试时可以达到1000RPS,与网上40k/min/cpu core的测试结果基本一致。这一结果真的在对比的产品中不算优秀,尤其是Zuul在刚启动开始的时候表现很差,原因开始Zuul需要处理一些初始化和负载均衡的事情,之后性能变好,另外,在注册中心有新服务加入时,第一次通过网关请求耗时较大。

尽管如此,我们还是选择了Zuul,因为Zuul提供的性能/单位资源能满足大部分客户的需求,另外zuul的二次定制开发很方便、与Spring Cloud其他组件的整合度也非常的高。

服务注册和配置中心

Spring Cloud支持的注册中心有Consul和Etcd、Eureka、Zookeeper等。其中选择Eureka和Consul的都比较多。两者间区别一方面在CAP原则方面的取舍,Eureka是典型的AP,Consul倾向于CP类型,也能提供较高的可用性,而且提供功能更加丰富,对异构实现的微服务也很友好,选择Consul团队的很多。

但在我们实际预研验证的时候,感觉Consul的API使用起来比较别扭,而Eureka以Spring Boot的形式封装,使用起来非常方便。

另一方面,我们认为在服务发现场景的可用性优先级更高,一致性的问题可以通过请求重试或者服务熔断将风险降低。

对于非Java Stack的微服务,Eureka可以使用Sidecar使其他服务更加方便的接入,目前也有了不少非Java的Eureka客户端,如Node.js的。这些是我们选择Eureka的原因。

配置中心:我们还是选择了Spring Cloud的Config,当时我们从易于定制开发的角度考虑是优于XDIAMAND和Disconf的。不过后来开源的Appollo是一个Config的很好替代,它所支持的配置内容和功能比较丰富,可视化做的也很棒

服务追踪

最初我们使用了Spring Cloud提供的Slueth和Zipkin Server组合,好处是集成容易。为避免Zipkin的服务重启的数据丢失问题,我们选择使用Elasticsearch进行存储,并使用消息队列进行传输。这里提一句,在1.2.5版之前sleuth的消息传送可以使用Spring Cloud Stream,1.3.0以后版本使用了stream会直接起不来boot服务,是需要直接对接Rabbit MQ或者Kafka的(Maven中直接引入pring-rabbit 或 spring-kafka依赖包)。

随着使用,后来感觉Sleuth+Zipkin调用链路关系展现实在比较单调,信息量也比较少,线程和CPU等信息需要额外查看,虽然这点从boot的监控端点可以获取,但是端点的信息不会落地,不能更好的为以后服务性能分析提供帮助。

我们尝试了其他的服务追踪工具,曾经预研并使用过pinpoint和skywalking,这两个都是对代码零侵入的。PinPoint展示的信息比较全面,支持的场景更多,但有几个问题:

  1. 性能影响较大,性能影响随着线程数量的增加而变大。经过测试发现对吞吐量的影响:skywalking < zipkin < pinpoint。
  2. 不支持Undertow的springboot。
  3. Pinpoint的存储使用hbase,对于我们的技术部件来又增加了一个新的挑战。skywalking是基于elasticsearch存储

基于上述原因,今年以来已在做skywalking对Zipkin进行替换的工作。

服务熔断

我们使用hytrix进行服务熔断和监控,熔断包括两个级别,第一级是从网关获取边缘组件的熔断,内部组件提供的熔断。第二级是来自API的熔断监控,组件中提供服务的API进行监控。在Hystrix的Dashborad进行展示,使用Turbine进行数据汇聚。

基于这样的一个基本框架,我们又做了以下几个方面的扩展:

网关功能完善和扩展

我们在Zuul的基础上,进行二次开发,提供pp和用户级权限校验、数据完整性校验以及秘钥管理、路由动态配置以及实时刷新、可重用的api接口模板、api调试和mock、api的监控和告警等功能。

API网关

配置功能场景化

增加了很多场景化的配置管理功能,包括微服务的限流策略、灰度策略配置和数据源扩容切换(数据迁移成功后数据库连接可能修改)、熔断的监控展示开关等。

我们没有使用GIT对接Config,而是使用了Mongo作为存储,因为除了配置文件外,我们还做了不少配置可视化、场景化的工作,使用Mongo做扩展更为便捷。

分布式事务支持

尤其对于企业级微服务应用而言,分布式事务绝对是无法绕开的问题。我们的对这个点的要求是:

  1. 能够与Spirng 事务良好结合
  2. 支持Saga/TCC及基于消息的最终一致多种分布式事务解决方案,并已于扩展
  3. 具备人工干预的手段

我们基于开源分布式事务框架Easytransaction,做了与Spring Cloud体系,如 config、stream等组件的整合,完善了事务处理情况的监控及处理的功能,为分布式事务提供最后的人肉防线。

其他的扩展

  1. 框架组件管理功能的可视化,如网关、配置中心等,从而降低管理、配置的复杂性和出错率;
  2. 引入Elasticsearch Grafana做日志统一管理监控;
  3. 基于异步消息的服务Metrics信息聚合;
  4. 提供了分布式缓存、分布式ID生成器、分布式锁等常用的技术服务及配套SDK

其他重要的工具

微服务的落地离不开敏捷开发、DevOps,容器化的工作。今天,实现这些目标的工具链已经基本完备、打通,拿来主义即可起到很好的效果,比如k8s+docker、持续集成、部署等。

但是,对传统企业而言微服务、敏捷、DevOps的实施的最大冲击在于对软件质量把控上。按传统研发中的质量保证体系和人员在新模式下往往无法适应。

我们在实践中认为以下的几类工具的引入对传统企业来说是有价值的:

API自动化测试工具

在敏捷开发、DevOps的过程中,对传统企业来说,最具挑战的是自动化测试。原因除了原有测试管理流程的问题外,主要是测试人员大部分只具备人工测试的能力,对测试编码、工具都不熟悉。

但缺失了自动化测试,在频繁交付、发布的环境下,软件质量的控制是很难的。尤其是在微服务架构下,以前测试人员手工进行黑箱测试的模式,发现产品质量缺陷非常有限。针对这一问题,从API测试的自动化和可视化入手,是一个具有很高成本收益比的方案:

  1. 比界面手工测试可以覆盖更多的测试点。
  2. 偏向于站在用户的角度测试,对开发人员、测试人员都很有价值
  3. 成本比实施自动化单元测试更低
  4. 测试资产可积累重用,效益随系统复杂度同步提升

下面是我们实现的API测试框架:

API测试框架

可以用界面配置的方式录入、参数化的接口,并配置测试用例。方便不熟悉编码的测试人员使用;同时这些配置的用例可以生成测试代码,让这些可视化配置测试用例和与代码编写的测试用例一样被测试框架管理,可统一计入测试覆盖等指标。

代码质量检查工具

有了包括代码静态质量、测试用例覆盖度等工具,才有可能谈到代码质量、测试质量的可见性,才有可能进一步进行针对性的管理质量。我们主要基于Sonar、jacoco实现了代码质量检查的工具:

代码质量检查工具

对传统企业而言,这一工具对推动敏捷开发模式是非常有用的。

性能测试工具

在微服务架构的研发项目,性能测试频率和强度都是传统项目所不能相提并论的。以往,一个传统团队最多用一两个专业人员、使用Loadrunner之类的测试工具测试一下服务非功能质量。这种模式在目前根本无法满足微服务研发项目的需要。微服务架构下,开发人员、测试人员在开发、单元测试、集成测试、验收测试等多个环节用不同的测试方案、满足不同的测试目标。

为此,我们对比过JMeter、Gatling、Locust等性能测试工具,由于Locust的跨平台、分布式、轻量化等优势,最终我们基于Locust实现了一套简单易用的性能测试工具。方便开发、测试人员随时随地的申请测试资源、展开性能测试。

性能测试工具

灰度发布框架

对于传统企业而言,尤其是新的质量管理体系还没有运转顺畅之前,灰度发布是敏捷发布中极为重要的功能。按照终端设备、用户等维度,从微服务、乃至接口这样的细粒度实现灰度发布是极为必要的。我们依托Spring Cloud的Zuul,Ribbon,实现了一套API、边缘服务、内部微服务的灰度发布机制。

灰度发布框架

在线数据迁移工具

在微服务架构的环境中,数据迁移需求的频率对比传统应用是极高的,同时还必须考虑减少对业务的影响。我们基于otter开源框架实现了数据迁移的场景化和易用化,实现了数据库集群扩容,灰度发布的数据迁移等场景。

微服务设计开发提效

实现同样功能的微服务产品比传统架构产品需要投入更多的设计、开发工作量,频繁的变更和紧迫的交付要求更是让研发团队的压力很大。

对传统企业而言,这点更为突出,甚至是时间看上去较为充足的项目,也很难在保证质量的前提下按时交付。

针对这种状况,我们认为努力方向无非是标准化和自动化。其中标准化是自动化的前提。

大多微服务标准化的讨论集中在微服务治理框架技术、访问协议等微服务间的标准化问题上。

但对开发提效而言,微服务内部实现层面标准化工作有可能会取得更显著的效果,毕竟框架已定的前提下,日复一日的主要是微服务产品的设计、拆分和各个微服务的实现工作。

确定这类标准,首先需要找到微服务的内部架构中比较稳定的功能结构单元。这是因为微服务的粒度是不稳定的。

这种不稳定性一方面体现在一个微服务架构的业务系统会存在多种拆分微服务服务的方案,另一方面随着业务系统的不断演进,每个微服务还存在进一步拆、并的可能。

这一特性本是微服务的优势,记得有人说过SOA和微服务的一个区别在于,SOA让服务重用更为便利,微服务是服务重写便利。

我们谈到的标准也必须为这种优势服务而不能成为障碍。

实践中我们认为以DDD的方法为纲,辅以大家经常提到的康威定律、AKF原则、Netflix识别原则等标准是比较合理的。

回到刚才的话题,从DDD的视角来看,我们的认为微服务中相对稳定的结构是聚合(Aggregation)。微服务会拆分、合并,但一般说来微服务的粒度是>=单一的聚合的。

因此我们将聚合视为更为稳定的业务原子,从聚合的角度去梳理我们微服务设计实现标准,包括把聚合间的访问策略、数据一致性原则、事务处理模式等设计约束规范化下来。

为了进一步提升开发者效率,我们基于Jenkins、Freemaker、Swagger都能开源工具实现了一套微服务应用开发的脚手架工具,工具有Idea插件版本和WEB版本。可以可视化完成项目代码(包括包括模型、DTO、API)、依赖配置、应用配置、接口文档、数据库脚本的自动生成工作。

面向服务治理的微服务模型化

微服务一大吸引力可能就是敏捷灵活的重构改进,从而不断满足业务转型、高效创新的企业战略。

然而实际上微服务框架、工具只能提供微服务生命周期中的基础技术支撑。微服务后续合理的重构、拆分、合并,对缺少新形态业务运营经验和服务治理经验的传统企业来说是非常困难的事情。

Gartner报道过,在超过50个服务的项目中,大于80%项目失败主因是缺少治理机制。管理大师彼得德鲁克说过,“你如果无法度量它,就无法管理它(请允许我偷换一下管理和治理的概念)”。当然,在度量前我们必须考虑对微服务进行模型化的描述。

在这一问题上,我们与哈工大的企业智能计算实验室合作进行了研究和实践,感谢哈工大给予的强有力的理论支持。让我们认识到微服务的结构化描述和模型化的潜在价值。由于时间关系,这里仅仅介绍一些服务模型的形式化定义,希望对服务模型抽象有兴趣的伙伴有所启发。

  1. 微服务构件的结构化定义
    微服务构件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为构件运行所需的服务集合。

  2. 微服务构件的复用度定义
    构件的复用度为SCR=(fx,Ω),其中fx代表fP或fR,Ω代表所有微服务构件组成的空间。通过复用度可以描述微服务构件的应用层次高低和适应业务需求变化的能力。

  3. 原子微服务构件
    SCatom={SCID,φ,DS, φ, φ, f<sub>P</sub> , φ}。表明此服务组件是非组合且不可定制的。只能对外提供标准统一的服务。

  4. 框架微服务构件
    一个SC称为框架构件SCF,当且仅当构件提供的服务的复用度为1,组件依赖服务的复用度<1。
    非框架构件我们称为业务微服务构件SCB。

基于这样的模型我们可以更好的描述服务,针对不同类型的微服务制定不同的治理策略。不仅如此,基于数学化的描述也可以进一步使用本体推演、π演算、Petri网路等服务演算手段自动化的完成一些服务治理及治理辅助工作,如智能化的服务推荐、评价、调度、扩展、拆分、组合等。

最后

以上是本次分享的内容,感谢大家,希望大家多提宝贵意见。对传统企业落地微服务来说,本文涉及的视角仅能说是管中窥豹,如果能对关注这个问题的朋友有些许帮助就非常欣慰了。最后欢迎各位和我就相关的问题做进一步的交流,我的微信号是ttgoding。