元数据如何驱动微服务报文架构?

随着微服务的概念逐渐被人们接受,大家都在努力将自己的应用系统向微服务框架转型。在我们研发微服务框架的时候,就发现随着服务数量的增多,服务接口定义就需要一套统一数据标准来支撑;在对服务接口做实参的时候,频繁的且重复性的赋值让人很抓狂。本文将阐明我们面临这些问题是如何解决的。

本文目录:

一、什么是报文

二、报文为什么需要规范

三、常规的报文规范

四、微服务下的报文规范面临的问题

五、元数据驱动的微服务报文

六、技术实践

一、什么是报文?

报文(message)是网络中交换与传输的数据单元,即站点一次性要发送的完整数据信息的数据块。

上面的例子可能不符合实际业务场景,只是为了举例说明。当你要预订一张机票的时候,需要向航空公司查询票务,也需要向支付机构支付票款。在每个服务之间,需要进行信息的传递和交互,这个交互信息,就是报文。

二、报文为什么需要规范

报文包含完整的数据信息,如上述报文A中的日期、地点等,或者如报文B的账号、密码等。这些信息字段都具有各自的字段属性,比如日期是年-月-日,密码长度6,需要字母和数字混合等。

这些字段属性在个人开发的场景下,字段的信息定义都是可以由自己决定,只要记忆不出现错误,信息传递也没什么问题。如果涉及协作开发,就必须在报文的格式上制订出大家共同遵守的规范,否则在应用之间将无法达成数据的通讯和交互。

上面两幅图能很形象的反映出问题的关键,协作模式中报文规范至关重要,是服务开发的基础。

三、常规的报文规范

在协作开发模式下,经常会见到报文接口规范描述文档。如银联接口:

上图银联接口截取自《中国银联银行卡联网联合技术规范V2.1-报文接口规范》

如某银行接口:

我们能发现不管是企业间还是企业内部的报文规范,大家都采用同样的方式或者说类似的方式来解决报文接口数据标准的问题。通过文档描述报文接口规范,依赖强管控能力强制执行。

四、微服务下的报文规范面临的问题

在微服务的大趋势下,系统出现形式不再以应用为单位了,最终形态将会是一个一个微小服务了。

处理相同的事情,在微服务架构下服务被拆分成多个小粒度的微服务了,报文的个数随着服务的拆分而成指数增长。

传统模式关心的是系统与系统或者说应用与应用之前的交互,通过几个文档描述就能够解决问题;而在微服务架构下,还继续通过文档的方式去描述报文规范,我相信程序猿们肯定会崩溃。

有过分布式服务框架(如dubbo)使用经验的朋友可能会想,服务接口都是通过java interface定义,参数都是java bean的,拿到接口就能开发了呀,谁还关心这样的规范啊?

上图代码是个简单的用户注册接口,通过该接口在团队内部的的确可以快速的开发,但是如果跨团队协作的情况就不那么乐观了。

图中接口里的loginName没有约定诸如是否允许中文,最大长度不能超过20,不能有特殊字符等等; password也没有约定诸如是否必须包含大小写及数字,长度为6-18等等。这些关键的信息缺失之后,我们协作开发就比较困难了,甚至会遇到在开发期和测试期都不出现问题,等到上了生产就会出现各种奇葩的问题了。

再来看一个服务实现的例子:

上图代码是一个注册接口的具体实现,主要完成了几个事情:申请开通Jira、Git同时向数据库添加一条记录。为了完成这三件事情,给参数赋值的代码就写了6行,如果参数字段多达十几个甚至几十个的时候,我相信程序猿一样会奔溃。

解决这种繁琐的赋值操作办法还是有很多的,比如将所有的java bean中相同属性定义同样的名字,然后利用java反射机制写一个通用的赋值工具类,将相同属性进行值拷贝。

但是在微服务架构下,服务就是最小的开发粒度,无法控制所有程序猿对变量名的定义都统一,这又是一个让人头痛的问题。

五、元数据驱动的微服务报文

上面提到了微服务架构下报文面临着接口规范定义及方便使用的问题,通过元数据如何解决这些问题呢?

既然报文结构规范定义是个问题,那就从规范入手解决。常规方式是通过文档描述规范通过强管控实施,因为word或者excel文档对程序猿不够友好,所以数量过多才会让程序猿崩溃,从这点入手,将文档描述的格式换成对程序猿友好的格式(如xml、yaml等)是否会好一点呢?

如上图,将word文档或者excel管理的规范数据标准,转为yaml格式定义及保存,通过yaml工具将yaml编译成Java Bean并提交资源管理库,在开发阶段,通过maven依赖将需要的元数据依赖进自己的项目。

使用元数据的时候,通过注解的方式关联到服务接口上,如下图:

在之前的用户注册的服务接口上我们添加@DataDict的注解,从注解的内容能够看出是将接口规范与接口参数绑定了,再通过编码规范检查工具(如Checkstyle)就能够通过技术手段去管控报文规范的使用。

在服务接口上已经添加了@DataDict的注解,采用常规方法,通过反射机制写一个通用赋值工具,通过相同@DataDict去mapping,这样赋值的繁琐事情也就完成了。

六、技术实践

上面已经将解决问题的关键技术和思路说清楚了,下面来看看这些在普元微服务平台中具体实践。

我们在元数据定义的部分提供了元数据管理平台,在管理平台中通过配置界面去定义报文规范,并提交元数据到集成编译环境,集成编译环境会将元数据编译成Java Bean提交资源管理库。这里强调元数据管理平台的目的是为了统一元数据的定义入口,方便企业管控。

服务接口添加注解的操作上,我们采取可视化编辑自动生成的方式。如下图:

参数赋值的操作上,我们同样采取可视化编辑自动生成的方式。如下图:

我们通过统一的开发平台将coding行为转变成可视化编辑行为来简化开发,并且做到规范约束。

本文介绍了报文的规范由来,以及微服务下报文规范面临的问题:

其一是,手工的规范文档无法在开发阶段形成规范的落实,

其次是,由于微服务架构产生的繁琐的赋值操作需求。

解决方案有几个要点:

一是将手工文档固化为可以与开发环境结合的YAML等格式文档,形成开发环境可识别的元数据。

二是通过借助工具引擎来进行基于注解的报文解析,形成报文、服务与元数据的绑定,简化和自动化赋值操作。

关于作者:

姚重阳

普元解决方方案中心架构师,6年金融行业软件产品研发工作,目前主要负责解决方案中心的产品维护和技术售前。

原文发布于微信公众号 - EAWorld(eaworld)

原文发表时间:2017-03-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android机动车

计算机网络概念和结构

11410
来自专栏TechBox

模块化与解耦简述4. 解耦与通信5. 源码推荐

31430
来自专栏韩伟的专栏

GCloud的设计目的

提高游戏服务器端逻辑的开发效率 ? 游戏服务器端有三个常用的典型功能,几乎每个游戏都要反复实现的。而这几个功能,都会符合一些最佳建模和最佳实践: 客户端拉取服...

70760
来自专栏Golang语言社区

为Go语言GC正名-2秒到1毫秒的演变史

下面我们会介绍https://www.twitch.tv视频直播网站在使用Go过程中的GC耗时演变史。 我们是视频直播系统且拥有数百万的在线用户,消息和聊天...

53750
来自专栏刘君君

Rest Notes-架构上的教训(论文部分完结)

17660
来自专栏码神联盟

【原创】 元芳,这个BUG,你怎么看?

无论是桌面应用程序、Web应用程序,还是分布式系统和嵌入式系统应用程序等,Java编程语言已经被广泛用于开发各类应用及代码中的复杂功能。 不过在编写代码时,bu...

36690
来自专栏Golang语言社区

游戏服务端究竟解决了什么问题?

当讨论到游戏服务端的时候,我们首先想到的会是什么?要回答这个问题,我们需要从游戏服务端的需求起源说起。

31540
来自专栏木子昭的博客

使用python创建跨平台的fork()炸弹

进程炸弹运行截图 这是一个用python实现的最简单的fork炸弹 import os while True: os.fuck() 但是对于win...

350100
来自专栏更流畅、简洁的软件开发方式

【角色】——分离开代码和权限需求,即实现代码和权限需求的解耦。

今天突然来了一个灵感,记录一下。以前总觉得说不清楚,看看这种表达方式是否可以说清。 两个原则:依赖接口编程,不要依赖实现编程;最小获知原则。 面向对象最重要的是...

24850
来自专栏jessetalks

前后端分离开发模式下后端质量的保证 —— 单元测试

概述   在今天, 前后端分离已经是首选的一个开发模式。这对于后端团队来说其实是一个好消息,减轻任务并且更专注。在测试方面,就更加依赖于单元测试对于API以及后...

387100

扫码关注云+社区

领取腾讯云代金券