灰度的好处不多说了,跟UAT的区别就是引用大量的实际用户。灰度其实可以区分为:产端的灰度,后端的灰度,前后端一起的灰度。灰度最大的问题就是流量的分发+隔离。前端是静态资源的分离,动态请求的分发。前端可以分为,APP内的灰度,依赖APP的功能达到配置化的灰度l;外发H5的灰度,无依赖的生存环境,需要借助nginx做到流量的分发。当前端将流量,分发到后端,后端需要具备环境的隔离。

java灰度测试什么意思 怎么获得灰度测试资格_java灰度测试什么意思

 

1.非外发的H5

工作原理(canary=gray):

客户端会到“https://canary.XX.com/canaryandroid.json”这个地址去读取用户是否符合灰度的规则和那些域名需要启用灰度引流的白名单,在APP启动时会根据读取参数判断用户是否满足灰度引流规则,满足则进行后续h5引流操作;

针对h5的白名单域名引流分为2部分:①判断加载h5页面的链接是否匹配域名白名单,如果匹配则在请求h5页面的请求头中加入灰度标识,后续h5的非静态资源请求将h5都带入这个灰度标识(都由h5自行处理,前端至插入标识);②get请求(静态资源)当h5对后端发起网络请求时,客户端会对请求进行来就同时根据白名单和请求方式(get、post、others…)来进行劫持,如果是get请求同时匹配白名单则有客户端代为请求后端数据(在请求链接中加入白名单标识参数)然后将请求的结构返回给h5;非get请求一律不处理;

java灰度测试什么意思 怎么获得灰度测试资格_java灰度测试什么意思_02

2.外发的H5

H5不能自己去识别是否灰度,所以需要nginx来帮忙识别。nginx可以识别header(proxy_set_header)、cookie($http_cookie)

java灰度测试什么意思 怎么获得灰度测试资格_灰度发布_03

后端:

一、主要解决数据库的共用问题。

  1. 数据隔离:就是产线上运行两套代码,同一套库的情况下可以数据隔离,互不影响。常规想法,那我运行两套数据库,进行双写?这个不仅是资源的浪费、维护也很痛苦。所以,可以分析一下现在问题,在已经兼容老数据的情况下,那么如果可以区分数据是由灰度应用完成的,那么后来的操作也由灰度上的应用继续完成就没有问题了,所以我们可以给灰度应用产线的数据打标、对数据进行隔离。
  2. 依赖回调(消息、接口)的发送方无灰度(外发的例如:银行):对于只有回调的,需要补充调度。
  3. 调度:隔离
  4. 共库:数据上不区分灰度、产线。

假设我们要处理交易的数据隔离:

实现的方式 :

  1. 在交易涉及的表入库时,新增处理机器的标识 :hd及prod.
  2. SQL拦截处理:

使用mybatis拦截器,进行SQL拦截。改动较少,不需要在每个查询的地方增加区分的代码,避免入侵业务。比如我们这次要做的处理:是在SQL执行之前,根据当前机器的run _env属性,增加过滤条件。

简单说明:

mybatis提供了一个Interceptor接口,方便扩展所需的操作,拦截要做的就是实现这个接口。

他包含以下三个方法,本次主要对intercept做实现,获取到执行SQL后,与当天机器的run_env属性比较后增加SQL条件。

  Object intercept(Invocation invocation)

  Object plugin(Object target)

  void setProperties(Properties properties)

 

public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        //通过MetaObject优雅访问对象的属性,这里是访问statementHandler的属性;:MetaObject是Mybatis提供的一个用于方便、
        //优雅访问对象属性的对象,通过它可以简化代码、不需要try/catch各种reflect异常,同时它支持对JavaBean、Collection、Map三种类型对象的操作。
        MetaObject metaObject = MetaObject
                .forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                        new DefaultReflectorFactory());
        //先拦截到RoutingStatementHandler,里面有个StatementHandler类型的delegate变量,其实现类是BaseStatementHandler,然后就到BaseStatementHandler的成员变量mappedStatement
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        //id为执行的mapper方法的全路径名,如com.uv.dao.UserMapper.insertUser
        String id = mappedStatement.getId();
        //sql语句类型 select、delete、insert、update
        String sqlCommandType = mappedStatement.getSqlCommandType().toString();

        BoundSql boundSql = statementHandler.getBoundSql();
        //获取到原始sql语句
        String sql = boundSql.getSql();
        //本次的主要逻辑
        String runEnvString=OpsUtil.getOpsValue("run_env");
        String[] runEnvList =runEnvString.split("_");
        String mSql = sql;
        if(("hd").equals(runEnvList[0])) {
             mSql = sql + " and  run_env ='"+runEnvList[0]+"'";
        }
        //通过反射修改sql语句
        Field field = boundSql.getClass().getDeclaredField("sql");
        field.setAccessible(true);
        field.set(boundSql, mSql);

        return invocation.proceed();
    }

 二、回调问题:

有些交易不可避免的会使用到第三方的接口,第三方一般来说,我们默认为没有对接灰度。

  1. 回调处理:

消息若由灰度的应用发送,收到的应用也是灰度的,是环境隔离的,因此是不受影响的。若是类似银行商城中的下单流程,则银行返回支付结果时,是返回到产线,则需要特殊处理。

第一种处理方式:无业务入侵,推荐使用

回调时,查询被拦截,带有hd标识不处理。等待灰度的高频调单处理,处理时按回调消息发送至灰度的回调,更新灰度的数据。

java灰度测试什么意思 怎么获得灰度测试资格_h5_04

第二种处理方式:入侵式,还以订单为例。如无特殊需求,不推荐

 

例如:订单简单处理,可将canaryGrey拼接在订单号上,银行收银台返回时自然带回。复杂点使用单独参数传递。壹钱包在网关(openApi)解密完成时,按原报文是否标记引流。

java灰度测试什么意思 怎么获得灰度测试资格_java灰度测试什么意思_05

 

监控

灰度的用户,也是正式的用户。相对应的评估相关的灰度流程,加强监控。一个是系统层面的:错误率、吞吐量、延迟和CPU内存消耗等指标。另一个如果样本足够,也需要提提供PV、UV等业务指标,方便产品业务的后续决策。