王作敬
作者王作敬·2019-01-28 10:28
管理信息系统总监·银河证券

微服务设计二三事

字数 3081阅读 4360评论 0赞 0

作者:汪照辉 王作敬
汪照辉个人页面


最近受邀参与业务开发团队业务系统的改造,计划采用微服务架构,构建微服务应用,同时考虑建设业务中台,为其他业务团队提供共享的业务服务。业务团队还是倾向于和原来的厂商合作,但原厂商对微服务架构的理解不到位,其原产品的设计要短期内以微服务架构重构也几乎不可能,以项目的方式重构产品,对我们来说投入巨大,难以通过项目审批。同时对我们来说,时间也很珍贵,需要尽快地改造并逐步构建成服务中台,快速支撑业务的变更和创新。传统厂商的技术能力已经远远落后于实际需求,难以提出合理的方案。因此业务邀请我们架构团队一起讨论,指导其业务系统重构。前后经过多次讨论,使业务团队逐步了解了微服务架构和中台建设的思路,在讨论过程中业务开发团队提到了几个问题,现整理出来和大家共同探讨。

一、 微服务化入手

长期服务于金融行业的大部分厂商对微服务的认知还很薄弱,初始提出应用系统微服务化架构改造,基本上都是一头雾水,没有头绪,不知道该怎么入手。特别已有的业务系统,传统的构建方式,传统的数据库表设计,传统的类、方法设计等和微服务架构的设计思想完全不一样。习惯了一个操作实现一个接口,根本没有考虑过共享服务层的设计,或者叫服务中台的设计,现在要基于服务中台设计微服务并为各业务系统提供相应的接口,有点束手无策。
微服务热也让很多团队都纷纷提出转到微服务架构。一窝蜂的方式让我们觉得也是非常不可取的。在前期没有经过充分的理论研究、实践探索、经验总结学习,就匆忙的都要进行微服务化改造,势必减少微服务基础设施平台支撑能力的优化和完善及微服务设计的优化和完善的时间,或者根本没有时间去考虑优化和完善,很可能导致微服务带病上线,对后期微服务的设计和运营以及企业整个微服务架构的成功带来负面影响,甚至可能导致整个微服务架构实践的失败。
关于企业的微服务化,笔者始终不建议让厂商主导,微服务的设计和整体架构必须自己来完成。这对自身的技术实力要求是有点高,但也是企业微服务实践和中台服务建设成功的前提。厂商始终是以赢利为目的,一个项目它不可能从企业全局上去考虑微服务设计,你也不可能一下子把所有项目都交给一家公司,至多以项目边界考虑,所以很多时候还是单体系统建设思维,其设计的微服务是一个应用的微服务,而不是企业服务中台所需的微服务。厂商能做什么?按照定义好的接口去实现业务应用流程。
微服务化改造不要急于替换现有业务应用。梳理业务和数据流程后需要定义微服务和微服务接口,不是定义好一个微服务就同步替换业务应用。业务应用还可以按照原来的方式运行。改造可以一个模块一个模块来替换。比如产品中心有几十个大大小小的模块和几百个功能点,数据库表有几百张,仅存储过程就有400余个。其实产品中心的业务逻辑并不复杂,原来的系统设计建设方式导致系统复杂化。微服务化也是梳理和优化业务流程的过程。几百张表梳理之后可能保留几十张就够了,微服务实体大概也有几十个。比如说产品,可以作为一个微服务,也可以按照产品类型分拆为不同的微服务,因为不同类型的产品差别很大,属性可能几乎完全不同,比如贵金属产品和基金产品,除了产品名称和分类编号,其他属性都不一样,可以拆分为不同的微服务。贵金属产品微服务定义好之后,可以替换贵金属产品业务应用模块,这个模块用到的其他微服务有则直接使用,没有则规划定义,或者通过adapter的方式暂时代替。
这里会涉及重要的数据同步问题。微服务需要定义独立的数据模型数据存储库,和原来的业务应用系统数据库分离。那么以哪个库为主?这是我们业务开发团队纠结讨论了很久的问题。笔者的建议首先避免两个并行的库都并行写操作,读写分离(主辅分离)。以操作库为主,实时数据同步到查询库。事务一致性的问题我们下面讨论。比如贵金属产品库,所有的贵金属操作都走贵金属微服务到贵金属数据库,原来的业务系统中会包含贵金属数据,也可能会用到贵金属数据,那么就需要从贵金属库按照相应的格式实时同步到原库,保证原来应用数据的一致性。

二、 微服务接口设计

在讨论中,有人提出了这么个问题,在划分的一个微服务中,可能有几个相关表Table1、Table2、Table3,例如是父子关系表。分别定义了Table1、Table2、Table3单张表的信息查询接口API1,API2,API3,现在需要查询3张父子相关表的所有信息,是不是应该使用3个定义好的接口来实现业务层服务(组合服务)?
通常都是这么考虑的,接口复用!但我们不建议这么做。我们曾经在微服务协同时强调过链路最短原则。微服务设计时也应该这么考虑。新建接口API4并且直接实现查询逻辑,避免使用API4=API1 + API2 + API3。有人可能会说,如果某个数据库表结构变化了,那岂不是需要改多个接口?可能是的。但接口实现逻辑的变化并不影响接口。如果接口定义需要变了,就是考虑定义一个新的接口的时候了。比如说贵金属信息查询接口,数据初始可能来自于原来的产品中心库。在贵金属产品微服务构建完成之后,其数据来源调整为贵金属产品微服务库,数据来源变化了,但贵金属信息查询接口不变,对调用该接口的客户端无感透明。

三、 岗位和角色

有厂商使用领域驱动设计方法定义一个公共领域,包含员工、客户经理、组织架构、机构、岗位、角色、数据字典等等一堆不知道有什么关系的东西放在一个微服务中,而且角色和岗位是重复的定义。组织架构、角色、权限可以定义为一个独立的微服务,但通常这块可以由一个公共的支持多租户的权限中心组件支持,没必要再独立设计。岗位就是角色,不同的岗位代表不同的角色,把岗位和角色并列,不但使业务管理复杂化,也使设计实现复杂化。在角色定义里完全可以定义不同的岗位,赋予每个岗位不同的权限。可能有人会说了,这个岗位不是虚拟的角色,而是企业中的岗位,是需要保存在数据库中的一个字段。那也没问题啊,岗位和角色本来就是可以一一对应的。系统中的角色(岗位)定义并不影响实际的岗位数据。若同一个岗位可能有不同的权限,可以定义不同的虚拟岗位角色就好,比如经纪业务客户经理和资管中心的客户经理。

四、 事务一致性

客户中心有这么个需求,客户经理拜访客户后,在更新客户资料的同时可能需要记录一条拜访记录。他们纠结的是要求必须要用强一致性事务来保证数据的一致性,要么写操作都成功,要么都失败。客户和客户经理拜访记录要不要放在一个微服务里,用领域驱动设计理论划分领域,似乎有点似是而非。我们一再强调从业务应用逻辑出发,分析业务应用逻辑。我们假定没有客户拜访记录,考虑是否会影响客户。对客户其实是没有明显影响的,这个只不过记录了客户经理的活动。所以在微服务设计的时候应该分离,他们并不是强一致性的事务数据,因此也可以考虑采用消息一致性来实现。
强一致性事务通常是资金和产品的交易业务。在资金扣减的同时需要确保客户购买的产品成功。否则扣减资金成功而增加产品失败,客户会很愤怒;扣减资金失败而增加产品成功,那得赔死;所以这是强一致性的事务,比如保证要么同时成功要么失败回滚。
强一致性微服务怎么设计实现?资金和客户是不同的微服务,资金来源于资金账户,扣减资金是从资金账户中扣减,所以用到的其实是账户微服务。你不能把所有东西放到一个微服务里,因此客户和账户需要考虑设计成不同的微服务。需要考虑分布式事务处理。从强一致性事务及性能考虑可以采用分布式内存数据网格或分布式内存数据库。通常要基于实际的数据量和性能等要求选择合适的实现方式,甚至是微服务设计模型。其原则就是微服务接口不变,实现逻辑可以根据需要调整。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

0

添加新评论0 条评论

Ctrl+Enter 发表

本文隶属于专栏

最佳实践
不同的领域,都有先行者,实践者,用他们的最佳实践来加速更多企业的建设项目落地。

作者其他文章

相关文章

相关问题

相关资料

X社区推广