当前位置:网站首页>表达式引擎在转转平台的实践
表达式引擎在转转平台的实践
2022-08-01 10:52:00 【InfoQ】
一、业务背景介绍
二、工程现状
{
"label_红布林标签ID": {
"url": "红布林落地页地址",
"name": "红布林配置",
"其他字段": "省略表示"
},
"uid_帮卖用户ID_searchType_2": {
"url": "转转帮卖暗拍落地页地址",
"name": "转转帮卖暗拍配置",
},
"uid_帮卖用户ID": {
"url": "转转帮卖落地页地址",
"name": "转转帮卖配置",
},
"cateId_图书社会科学分类ID": {
"url": "图书科学类落地页地址",
"name": "图书科学类配置",
},
"cateId_图书自然科学分类ID": {
"url": "图书科学类落地页地址",
"name": "图书科学类配置",
}
}

- 每次新增一种配置维度,需要上线才能完成Key的拼接逻辑和读取逻辑,且读取的优先级硬编码。
- 已有的属性无法自由组合,如转转帮卖暗拍配置的规则为:卖家ID+搜索类型叠加,只能硬编码的方式进行拼接Key,下次的组合维度发生变化还需要开发。
- 相同业务需要维护多条配置,如图书社会科学和自然科学对应的落地页地址都是一个,按照Map的的配置方式需要配置2条、3条、甚至更多。
- 长此以往,Key的拼接和解析逻辑越来越难以维护,配置也越来越庞大。
- 每次上线只是开发拼接Key的逻辑和读取逻辑,都是重复工作,成本高,收益低。
三、方案选型
四、使用表达式引擎重构
4.1 架构设计

4.2 配置重构
[
{
"url": "红布林落地页地址",
"name": "红布林配置",
"ruleEl": "list.contains(labelList, 红布林标签ID)",
"priority": 20,
"其他字段": "省略表示"
},
{
"url": "转转帮卖暗拍落地页地址",
"name": "转转帮卖暗拍配置",
"ruleEl": "帮卖用户ID == product.userId && 2 == product.product.searchType",
"priority": 20
},
{
"url": "转转帮卖落地页地址",
"name": "转转帮卖配置",
"ruleEl": "帮卖用户ID == product.userId",
"priority": 20
},
{
"url": "游戏代练陪玩落地页地址",
"name": "游戏代练陪玩配置",
"ruleEl": "代练分类ID == product.cateId || 陪玩分类ID == product.cateId",
"priority": 20
},
]
4.3 上线小插曲
-XX:+TraceClassLoading[Loaded Script_1645773082560_152/982082822 from com.googlecode.aviator.Expression]
[Loaded Script_1645773082514_151/1163475645 from com.googlecode.aviator.Expression]
com.googlecode.aviator下的ExpressionScript_当前时间戳_一个IDpublic Object execute(final String expression, final Map<String, Object> env,
final boolean cached) {
// 1.编译表达式
Expression compiledExpression = compile(expression, cached);
if (compiledExpression != null) {
return compiledExpression.execute(env);
} else {
throw new ExpressionNotFoundException("Null compiled expression for " + expression);
}
}
public Expression compile(final String expression, final boolean cached) {
if (expression == null || expression.trim().length() == 0) {
throw new CompileExpressionErrorException("Blank expression");
}
if (cached) { // 2.缓存开启与否
FutureTask<Expression> task = this.cacheExpressions.get(expression);
if (task != null) {
return getCompiledExpression(expression, task);
}
task = new FutureTask<Expression>(new Callable<Expression>() {
@Override
public Expression call() throws Exception {
return innerCompile(expression, cached);
}
});
FutureTask<Expression> existedTask = this.cacheExpressions.putIfAbsent(expression, task);
if (existedTask == null) {
existedTask = task;
existedTask.run();
}
return getCompiledExpression(expression, existedTask);
} else {
// 3.实时编译
return innerCompile(expression, cached);
}
}
public ASMCodeGenerator(final AviatorEvaluatorInstance instance,
final AviatorClassLoader classLoader, final OutputStream traceOut, final boolean trace) {
this.classLoader = classLoader;
this.instance = instance;
this.compileEnv = new Env();
this.compileEnv.setInstance(this.instance);
// 上面打印的生成ASM的类名
this.className = "Script_" + System.currentTimeMillis() + "_" + CLASS_COUNTER.getAndIncrement();
// Auto compute frames
this.classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
visitClass();
}
4.4 重构前后对比
- 封装后的组件大量应用到列表页,首页等场景中,动态灵活的规则配置在大促618,双11期间事半功倍。
- 利用表达式内置的函数和自定义函数,避免同类需求多次开发,避免重复造轮子。
- 常规类配置需求,利用表达式引擎基本做到需求变更无上线。
五、总结和感悟
边栏推荐
- MFC implementation road map navigation system
- Promise to learn several key questions (3) the Promise - state change, execution sequence and mechanism, multitasking series, abnormal penetration, interrupt the chain of Promise
- WTM:ASP.NET Core快速开发利器!
- retired paddling
- 小程序毕设作品之微信美食菜谱小程序毕业设计成品(3)后台功能
- IntellJ IDEA如何显示换行符(line endings)
- Cross-domain network resource file download
- C语言实现!20000用4秒计算
- 小程序毕设作品之微信美食菜谱小程序毕业设计成品(4)开题报告
- NIO‘s Sword(思维,取模,推公式)
猜你喜欢
随机推荐
NIO‘s Sword(思维,取模,推公式)
MFC implementation road map navigation system
Batch大小不一定是2的n次幂!ML资深学者最新结论
昇思大模型体验平台初体验——以小模型LeNet为例
Generate certificates using KeyStore
【cartographer ros】十: 延时和误差分析
pgAdmin 4 v6.12 发布,PostgreSQL 开源图形化管理工具
Introduction to data warehouse layering (real-time data warehouse architecture)
redis6 跟着b站尚硅谷学习
C语言程序设计50例(三)(经典收藏)
Dapr 与 NestJs ,实战编写一个 Pub & Sub 装饰器
2022年7月31日--使用C#迈出第一步--使用 C# 创建具有约定、空格和注释的易读代码
Guangyu Mingdao was selected into the list of pilot demonstration projects for the development of digital economy industry in Chongqing in 2022
Why Metropolis–Hastings Works
在线GC日志分析工具——GCeasy
微信公众号授权登录后报redirect_uri参数错误的问题
关于#SQL#的问题,如何解决?
机器学习 | MATLAB实现支持向量机回归RegressionSVM参数设定
记一次 .NET 某智慧物流WCS系统CPU爆高分析
MacOS下postgresql(pgsql)数据库密码为什么不需要填写或可以乱填写









