一个基于 Dubbo 的微服务改造实践

微服务的理论已经够多,今天不妨看一个实战案例。

写在前面

基于微服务或者 SOA 的自动化测试系统每个公司都有自己的特有的,我今天就主要介绍一下,我们研发的一套 mock 测试系统。

目前面临的问题

1、测试人员面临的测试问题

我公司目前用的是基于 Dubbo 的微服务改造,服务之间的调用链路冗长,每个服务又是单独的团队在维护,每个团队又在不断的演进和维护各个服务,那么对测试人员将是非常大的挑战。

测试人员每次进行功能测试的时候,测试用例每次都需要重新写一遍,无法将测试用例的数据沉淀,尤其是做自动化测试的时候,测试人员准备测试数据就需要很长时间,效率非常低。

目前接口自动化测试框架也多种多样,testng,junit,Fitnesse 等,但都需要测试人员具备测试代码编写能力,如果要做好和手工接口测试一样效果的自动化测试更是需要大量的代码堆积,后期维护代码成本非常大。因此做成简单配置用例流,无需编写测试代码的系统是更贴合实际工作要求。

举个例子:拿互联网支付系统来说,某个团队新增了支付交易的需求,这时候要进行测试,测试人员除了要测试支付交易需求本身是否正确,同时也要结合上下游的服务整体进行回归测试,这时候开发人员往往在支付交易系统中采用“硬编码”的方式对上下游的系统进行“挡板”,如果测试人员对测试数据有所调整那么“挡板”也要跟着调整,同时在项目正式上线的时候,如果开发人员没有将“挡板”程序去除干净,将面临严重的线上问题。

2、测试人员如何验证数据

接口返回值

通过肉眼分析比对接口返回值的内容,判断业务逻辑正确性。

数据库验证

测试接口的输入值需要通过手工编写数据库 SQL 查询获取,接口调用完成后,需要通过大量的 SQL 验证数据库值的正确性。

日志验证

通过返回值和数据库不能确保代码走到了预期的逻辑,只能通过肉眼观察日志确认代码的实际运行逻辑

测试报告

人工记录用例结果,人工编写报告,耗时耗力,难以准确定位代码问题

Mock 模拟系统的产生

业务系统调用众多其他系统完成功能逻辑,而想要得到其他系统接口的特定输出,需要做相应的运营配置,增加很多的沟通成本;甚至偶发性 bug 只能在特定的环境状况下复现,只能作为不可测的逻辑。

以风控系统为例,如果业务系统需要测试某个商编某个商品类别下的累积限额,需要风控的同事配合不断修改限额阈值,目前的情况是多个业务系统都在接入风控,配合测试的人力成本和时间成本是很高的。为此设计了挡板模拟系统,其功能结构如下:

针对测试人员测试用例数据无法沉淀和复用的问题,我们将采用“用例与日志锚点库”方案:

用例库的建立可以实现对以往测试规则的记录与复用,改变每次回归测试都要重复编写用例与准备数据的现状。

日志锚点库是对代码执行流程的有效验证,除了可以应用在测试环境中,还可基于大数据日志中心对生产代码的运行做日常监控。

交易与支付系统业务逻辑复杂,靠人脑和文档记忆功能关系难免疏漏,而用例库和日志锚点库会随着业务的变更测试而随即维护,是一部活文档。

Mock 系统的技术方案

1、系统的功能点

说明: 上图罗列了整个 Mock 测试系统的功能点有哪些,共分为:配置接口数据、创建测试用例、创建测试集、创建测试计划、执行测试计划以及生成测试报告等大功能。

配置接口数据界面图

创建测试用例配置图

挡板请求路由配置图

测试执行结果

2、系统的功能流程图

说明:依据上下文环境,利用工厂类动态注入 spring 对远程接口的依赖,保持线上与测试的代码一致。在测试环境中,通过 mock 系统管理端,可以随时调整请求的流向,“指哪打哪”。

说明:执行某项测试用例, 利用 mock 将被测试接口与底层依赖接口隔离开来,可以方便的模拟数据,并监控输入输出。用例执行完毕后,使用返回断言、SQL 查询、日志标记等多种手段验证。

Dubbo 的 Mock 功能

1、Dubbo 的 Mock 使用

Dubbo 自带的 Mock 功能首先是为了做服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过 Mock 数据返回授权失败。

我们从官网上举一个例子来说明:

我们可以在期望的 reference 标签上加一个 mock="force",就可以将当前服务设置为 mock。但是设置完 mock 属性后还没有结束,需要有一个 Mock 类对应我们的服务接口类。

规则如下:

接口名 + Mock 后缀,服务接口调用失败 Mock 实现类,该 Mock 类必须有一个无参构造函数。

对应到 com.foo.BarService 的话,则创建 BarServiceMock 类。

经过以上设置后,当调用 BarService 进行远程调用的话,直接请求到 BarServiceMock 类上面进行模拟测试。

2、Dubbo Mock 的原理解析

在 dubbo 的配置文件中

可以看到如下配置列表:

我们可以看到配置文件中实际上有五大路由策略:

AvailableCluster: 获取可用的调用。遍历所有 Invokers 判断 Invoker.isAvalible, 只要一个有为 true 直接调用返回,不管成不成功。

BroadcastCluster: 广播调用。遍历所有 Invokers, 逐个调用每个调用 catch 住异常不影响其他 invoker 调用。

FailbackCluster: 失败自动恢复, 对于 invoker 调用失败, 后台记录失败请求,任务定时重发, 通常用于通知。

FailfastCluster: 快速失败,只发起一次调用,失败立即保错,通常用于非幂等性操作。

FailoverCluster: 失败转移,当出现失败,重试其它服务器,通常用于读操作,但重试会带来更长延迟。

Dubbo 中默认使用的是 FailoverCluster 策略,而在实际执行的过程中是 FailoverCluster 会被先被注入到 MockClusterWrapper 中,过程就是:

MockClusterWrapper 内部会创建一个 MockClusterInvoker 对象。实际创建是封装了 FailoverClusterInvoker 的 MockClusterInvoker,这样就成功地在 Invoker 之中植入了 Mock 机制。

我们来看 MockClusterInvoker 的内部实现:

如果在没有配置之中没有设置 mock,那么直接把方法调用转发给实际的 Invoker(也就是 FailoverClusterInvoker)。

如果配置了强制执行 Mock,比如发生服务降级,那么直接按照配置执行 mock 之后返回。

如果是其它的情况,比如只是配置的是 mock=fail:return null,那么就是在正常的调用出现异常的时候按照配置执行 mock。

3、Dubbo Mock 的适用场景

Dubbo 的 Mock 功能主要是为了做服务降级而使用的,服务提供方在客户端执行容错逻辑,在出现 RpcException(比如网络失败,超时等) 时进行容错,然后执行降级 Mock 逻辑。自身并不适合做 Mock 测试系统。

自动化 Mock 系统的实现

1、Mock 系统的简单用例图

2、Mock 系统的架构图

为了基于 Dubbo 实现 Mock 功能,需要对 Dubbo 源码进行一些必要的修改,通过上面的架构图我们可以看到,实际上我们正是利用了 Dubbo 的 Filter chain 过滤器链这一机制实现的,为了方便大家更好的理解,下面将简单介绍一下 Dubbo 的 Filter 机制。

 Dubbo 的 Filter 原理分析

Filter:是一种递归的链式调用,用来在远程调用真正执行的前后加入一些逻辑,跟 aop 的拦截器 servlet 中 filter 概念一样的。

Filter 接口定义:

Filter 的实现类需要打上 @Activate 注解, @Activate 的 group 属性是个 string 数组,我们可以通过这个属性来指定这个 filter 是在 consumer, provider 还是两者情况下激活,所谓激活就是能够被获取,组成 filter 链。

关于 SPI 的详细介绍请大家参考我之前写的另一篇文章:

http://www.jianshu.com/p/46aa69643c97

ProtocolFilterWrapper:在服务的暴露与引用的过程中根据 KEY 是 PROVIDER 还是 CONSUMER 来构建服务提供者与消费者的调用过滤器链,Filter 最终都要被封装到 Wrapper 中的。

构建 filter 链,当我们获取激活的 filter 集合后就通过 ProtocolFilterWrapper 类中的 buildInvokerChain 方法来构建。

 Mock 流程介绍

注:我们在中新加了自定义的“env=test”这样的属性配置用来标明当前环境是测试的还是正式的,用户每次通过 Dubbo 请求的远程服务的时候,都会首先经过我们自定义的 Filter,我们自定义的 Filter 会首先判断当前的环境是 test 还是正式,如果是 test 的环境则直接访问 Mock 配置中心获取提前配置好的 Mock 数据并封装成用户定义的 Response 对象返回。

3、Mock 系统的配置中心

Mock 配置中心就是用户将 mock 数据与应用环境建立关系的系统,整个系统就像一个工作流引擎:

环境设置 ->应用名称设置 ->挡板规则设置 ->Facade 服务接口设置 ->方法规则设置

环境设置

注:如果尚未映射来源 IP 地址到环境,则点击环境列表导航链接,进入环境列表页面,点击添加,输入源 IP 及环境名,点击确定按钮,实现源 IP 到所设环境的映射。每个用户都可以建立属于自己的测试环境。

应用名称设置

注:创建所使用系统的应用名称,Mock 配置中心默认使用中的名称作为应用名称。

挡板规则

注:每一个挡板规则都是由一个环境名称和应用名称组成的唯一挡板,在挡板设置中选择环境名称和应用名称,并且设置挡板的有效状态。

Facade 规则

注:每一个 Facade 就是一个 Dubbo 的服务接口类,在这里将自己的 Facade 名称与全路径与挡板名称对应,以标识哪些 Facade 服务接口类是属于哪个挡板的。

方法规则

注:方法规则是用来设置每个 Facade 中的需要 mock 的方法的,可以对不同的方法设置方法执行时间、方法抛出的异常等等。

4、Mock 系统的其他功能

由于不少应用项目开发完后想对其进行单独压测,而很多时候应用系统和其他业务系统形成了依赖关系,如果不布署其他应用系统则无法完成压测,为了更好的支持性能测试组进行挡板压测,Mock 系统支持压测功能,而 Mock 系统自身也可以达到单台服务器 1000TPS 以上(8C8G)。

欢迎工作一到五年的Java工程师朋友们加入Java程序员开发: 854393687

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容