WEB端开关系统 - wugy0103/myBlog GitHub Wiki

WEB端开关系统

背景说明:互联网产品经常存在产品升级优化、重构的情况,但并不是每一次的升级优化都能获得较好的效果,为了能够在线上验证产品的优化效果和进行数据采集分析,不修改业务代码直接线上进行异常功能下线,所以需要设计一个开关系统。

方案1:使用Json文件配置方式达到开关效果。

思路

把需要验证效果的需求记录成一个开关,配置到JSON配置文件里放在公用webserver端,用户访问页面的时候,通过接口拉取JSON文件根据JSON数据进行业务判断。

业务流程图

switch

webserver实现

新建一个给现有所有的web端提供API的webserver,达到修改一份json文件所有前端系统都可以应用上的效果。

鉴于团队后期将会使用egg来当webserver层,所以这里也使用融合了团队的一些库的egg-demo来搭建。

1.通过ssh://[email protected]:10022/tantu-web/egg-demo.git拉取egg-demo,根据readme运行;

2.引用egg-validate 插件。

// app/config/plugin.js exports.validate = { enable: true, package: 'egg-validate', };

3.新建路由

// app/router.js
module.exports = app => {
  const { router, controller } = app;
  router.get('/api/switch/getjson', controller.switch.getjson);
};

4.新建controller

// app/controller/switch.js
'use strict';
const Controller = require('egg').Controller;
 
class SwitchController extends Controller {
  async getjson() {
   const ctx = this.ctx;
    // 调用 service 获取switch数据
    const data = await ctx.service.switch.getjson();
    // 设置响应体和状态码
    ctx.body = data;
    ctx.status = 201;
  }
}
module.exports = SwitchController;

5.新建service编写业务代码(读取json文件)

// app/service/switch.js
const Service = require('egg').Service;
const path = require('path'); // 系统路径模块
const fs = require('fs'); // 文件模块
 
class SwitchService extends Service {
 
  async getjson() {
    const file = path.join(__dirname, '/../public/data/switch.json');
    const filedata = fs.readFileSync(file, 'utf-8');
    return JSON.parse(filedata);
 
  }
 
}
 
module.exports = SwitchService;

最后发布上线后设置指定域名跨域,各前端系统即可通过访问${domain}/api/switch/getjson即可获取开关配置。

用户端使用

/*根据id获取开关*/
let getSwitchState = (switchId) => {
    ........//根据configs判断,返回开关结果
}
 
/*各业务使用流程*/
if (getSwitchState("100023") == 1)
{
    //开,添加处理
    ......
} else
{
    //关,添加处理
    .....
} 

JSON开关配置如下(详情页改版为例)

{
    "version": "v1.0.0",
    "switchs": {
        "201810130001": {
            "switchId": "201810130001",
            "switchCode": "TANTU-SW-WEB-DETAIL-0001",
            "switchName": "DetailPageSW",
            "switchDes": "商品详情页新旧版页面切换开关",
            "switchState": 1,
            "switchDefState": 0,
            "whitelist": [],
            "platforms": {
                "mobile": {
                    "IOS": {
                       "zzc": {
                            "configs": [
                                {
                                    "sysVersions": [
                                        {
                                            "start": "19",
                                            "end": "xxx"
                                        }
                                    ],
                                    "appVersions": [
                                        {
                                            "start": "5.3.0",
                                            "end": "xxx"
                                        }
                                    ],
                                    "channels": [
                                        "zuzuCheJenkinsBuild"
                                    ],
                                    "deviceType": [
                                        "all"
                                    ]
                                }
                            ]
                       },
                       "tantutravel": {
 
                       },
                       "tantumap": {
 
                       },
                       "wechat": {
 
                       },
                       "browser": {
 
                       }
                    },
                    "Android": {
 
                    }
                },
                "pc": {
                    "configs": [
                        {
                            "engine": [
                                {
                                    "name": "Trident",
                                    "start": "19",
                                    "end": "xxx"
                                }
                            ],
                            "channels": [
                                "zuzuCheJenkinsBuild"
                            ]
 
                        }
                    ]
                }
            }
        }
    }
}

字段详情

变量名称 类型 备注 eg switchId string 开关id 201810130001 switchCode string 开关编码 TANTU-SW-WEB-DETAIL-0001 switchName string 开关名称 DetailPageSW switchDes string 开关描述 商品详情页新旧版页面切换开关 switchState int 当前开关状态(0:关、1:开) 1 switchDefState int 开关默认状态(0:关、1:开) 0 whitelist Array 白名单列表(pc端为服务代码,m端为muid) {xxx} platforms Object 开关起作用的平台端(mobile,pc) {"mobile":{...}, "pc":{...}} platforms.mobile[sysType] Object m端的系统类型(iOS, Android) {"iOS" : {...}} platforms.mobile[sysType][app] m端的app类型(zzc,tantutravel,tantumap,wechat,aliplay,browser) {"zzc" : {...}} platforms.mobile[sysType][app].configs Array m端开关生效配置 [] ...configs[0].channels Array 渠道来源 ["xxx", "xxx"] ...configs[0].deviceType Array 指定设备类型屏幕 ["all"] ...configs[0].sysVersions Array 设备系统版本范围

Android取值:19(Android4.0), 20(Android5.0), 21(android 5.1), 22(android 5.1.x), 23(android 6.0), 24(android 7.0), 25(android 7.1), 26(android 8.0)...

iOS取值: 8、9、10、11...

[{"start" : "8", "end" : "11"}] ...configs[0].sysVersions.start String 最小值 8 ...configs[0].sysVersions.end String 最大值,xxx表示无限大 xxx ...configs[0].appVersions Array app版本范围,格式跟sysVersions一致 [{"start" : "5.2.1", "end" : "5.2.29"}] platforms.pc.configs Array pc端开关生效配置 [{},{}] platforms.pc.configs[0].engine Array 浏览器的内核配置 [{ "name": "Trident", "start": "19", "end": "xxx" }] platforms.pc.configs[0].engine[0].name String 浏览器的内核名字(Trident,Gecko,Presto,Webkit,Blink) "name": "Trident" platforms.pc.configs[0].engine[0].start String 浏览器的内核版本最小值 8 .platforms.pc.configs[0].engine[0].end String 浏览器的内核版本最大值,xxx表示无限大 xxx