怎样在测试环境使用线上数据验证新功能

1,570 阅读6分钟

正常我们在做项目时,通常都会有多个环境,本地开发环境,日常测试环境,预发环境,正式环境等等。

一般各个环境之间除了代码一致之外,其他的或多或少都会有一定的差异,例如配置信息,数据库信息等,其中最大的差异就是项目实际运行过程中产生的各种数据。

那我们怎样才能打造一个和线上环境尽可能相同的测试环境呢,我相信应该没人会愿意直接到线上环境去验证自己修改的 bug,或者新增的功能吧。

即便是实在没办法只能到线上环境去验证时,也是会分批切流,例如先切10%的流量到新发布的环境中,验证修改或新增的功能有没有问题,如果有问题就可以直接将流量切回去,对发布的代码进行回滚,没有问题的话再慢慢的发布其他的机器。

但是如果我们能够拿线上环境的数据在日常环境中预先验证一遍,那岂不是更好?说到底就是让正式环境中的数据能够在测试环境中走一遍,能够发现一些问题,比如一些算法的阈值调优等等。

怎样获得线上环境的真实数据

下面我将通过一个实际的例子介绍一种将线上环境的数据切到日常环境的方法,只是介绍一种思路,大家也可能有更好的方法,只要适合自己就是最好的方法。

但是并不是所有的项目都能够将线上环境的真实数据拿下来的,比如一些涉密数据,一些金融类数据,或者是一些敏感的数据,这里只针对那些可以直接拿真实数据到测试环境做 “仿真” 测试的项目。

我们做的一个项目是对各种设备采集到的数据进行处理,其中涉及到多种算法以及策略模型,我们需要在系统运行的过程中修改一些阈值,在算法升级时需要对算法进行验证,这时我们就需要重新跑一遍历史数据,查看实际的结果,如果我们能将线上的一些历史数据拿到日常环境,那将会事半功倍。

我们的设备是将数据直接上报到 metaq 中,系统对 metaq 进行监听,但是线上和日常环境的网络是隔离的。

从数据源直接切数据

我们的设备是在设备网,他是可以选择将数据发送到线上环境还是日常环境的,我最初的想法是能否通过修改设备的配置来将数据切到日常环境去,但是很快就否认了该方法,原因有两点:

一,设备配置修改繁琐并且需要一台一台的修改

二,数据切到日常环境后,线上环境的数据就停了

1.jpg

通过网关转发数据

设备实际上是先将数据发到 connector,然后由 connector 将数据写入 metaq 的,connector 就相当于一个网关,那能否通过 connector 将写入线上 metaq 的数据也写一份到日常环境的 metaq 呢?

2.jpg

如果能从这一层来做转发的话是最简单的,但是 connector 是所有设备的接入层,承载了所有设备的数据通讯,他是一个通用的模块,不会为我们加入这种定制需求的。并且代码不在我们这边,即便在我们这边,对 connector 进行改造的成本也是不小的,代价和收益不对等。

通过中间人转发

其实我们最原始的需求就是将线上 metaq 中的消息,原封不动的转发一份到日常环境的 metaq 中。

相信使用过 blink (阿里内部基于 flink 开发的框架) 的人,看到这样的需求会很不屑,因为这对于 blink 来说,这就是一条语句的事:insert into A select * from B

但麻烦的是线上 metaq 和日常的 metaq 是隔离的,网络是不通的,线上的 blink 可以访问到线上的 metaq 但是访问不到日常的 metaq,反之亦然。

那我们就需要有一个线上和日常环境都能够访问得到的地方,并且能够将数据存储起来,后面通过这个中间人进行数据的转发。

3.jpg

使用过阿里云 sls 的人都知道,sls 是一套可以运行在多种网络环境中的日志分析服务,这里我们选择在公网上创建一个 project,例如叫:tmp-data-hub,这样的话,线上和日常环境都可以访问到该 project。

4.jpg

那么有了这个中间人,我们就可以直接创建 blink 任务来进行数据转移了。

将线上 metaq 数据写入 sls

首先我们要在线上环境创建一个 blink 任务,将我们的目标 metaq 中的数据查询出来写入到 sls 中,代码很简单,大致如下所示:

-- 目标数据源:metaq
create table target_metaq (obj VARCHAR) with (
  type = 'metaq',
  topic = 'xxx',
  pullIntervalMs = '100',
  consumerGroup = 'xxx',
  tag = 'xxx',
  fieldDelimiter = ',',
  columnErrorDebug = 'true'
);

-- 中间人:sls
create table tmp_data_hub (obj VARCHAR) WITH (
    type = 'sls',
    endPoint = 'xxx',
    accessId = 'xxx',
    accessKey = 'xxx',
    project = 'xxx',
    logStore = 'xxx'
);

insert
  into tmp_data_hub
select
  obj
from
  target_metaq;

检查无误后,就可以将任务上线了,之后启动任务,过一段时间到 sls 中查看是否有数据进来,如果有那说明我们创建的 blink 任务是正确的。

将 sls 数据写入日常 metaq

接下来就是将 sls 中的临时数据写入日常的 metaq 了,这一步跟上面一样,只是需要到日常环境中创建 blink 任务,代码也相似,不同的是这里是要从 sls 中查数据,然后插入到日常的 metaq 中,这里不再赘述了。

通过中间人转发的方式是最简单的,现有的业务不受任何影响,不要写一行代码,唯一的缺陷是需要创建一个 sls 的 project,并且需要创建两个 blink 任务,这都是需要资源的。

总结

本文介绍了为什么要在测试环境使用线上数据进行功能的验证,然后介绍了几种获得线上真实数据的方法,最后选择了一种最简单,改造最小的方法。

欢迎关注「逅弈逐码」

欢迎关注「逅弈逐码」