QLExpress规则引擎实例

本文介绍阿里开源的QLExpress规则引擎,演示如何使用其在Java中实现灵活的业务逻辑控制,如新用户赠送优惠券或积分,以及发送短信通知等功能。通过修改规则描述即可调整业务流程,无需改动代码。

what is QLExpress

QLExpress是阿里开源的一个规则引擎,对java支持良好,具体描述及用法直接移步github:https://github.com/alibaba/QLExpress

just do it!

github中对基本用法已经描述很清楚,此处不再赘述,我们直接通过一个入门案例来帮忙理解,

fisrt

我们先来看一段java伪代码

if(新用户) {
  赠送优惠券;
} else {
  赠送积分;
}
if(有手机号){
  发送短信;
}

我们代码中都会出现类似的逻辑,如果此时我想要修改为新用户增送积分,否则赠送优惠券呢,这时候就需要修改if-else,此时我们可以使用规则引擎来轻松实现逻辑,并通过修改规则引擎描述就可以直接修改功能,咋做嘞,往下瞅~

show you code

package com.qlexpress.demo;

import com.ql.util.express.DefaultContext;
import com.ql.util.express.ExpressRunner;

public class Test {

    public static void main(String[] args) throws Exception {
        ExpressRunner runner = new ExpressRunner();

//      如果 新用户 赠送代金券  否则  赠送积分
//      如果 有手机号  发送短信

//      定义逻辑
        runner.addOperatorWithAlias("如果", "if", null);
        runner.addOperatorWithAlias("则", "then", null);
        runner.addOperatorWithAlias("否则", "else", null);

//      定义执行方法
        runner.addFunctionOfClassMethod("赠送优惠券", Test.class.getName(),
                "sendCoupon", new Class[]{Integer.class}, null);
        runner.addFunctionOfClassMethod("赠送积分", Test.class.getName(),
                "sendIntegral", new Class[]{Integer.class}, null);
        runner.addFunctionOfServiceMethod("发送短信", new Test(), "sendMsg",
                new String[]{"String"}, null);

//      定义逻辑
        runner.addFunctionOfServiceMethod("是否新用户", new Test(), "isNewAcct",
                new Class[]{Integer.class}, null);
        runner.addFunctionOfServiceMethod("是否有手机号", new Test(), "isMobile",
                new Class[]{Integer.class}, null);

        String exp = "如果  (是否新用户(1)) 则 { 赠送优惠券(1)} 否则 { 赠送积分(1)} 如果 (是否有手机号(1)) 则 {发送短信(\"欢迎您哦\")}";
        DefaultContext<String, Object> context = new DefaultContext<String, Object>();
        Object execute = runner.execute(exp, context, null, false, false, null);
        System.out.println(execute);

    }

    public static void sendCoupon(Integer num) {
        System.out.println("赠送优惠券啦:" + num);
    }

    public static void sendIntegral(Integer num) {
        System.out.println("赠送积分啦:" + num);
    }

    public String sendMsg(String msg) {
        System.out.println("发送短信啦:" + msg);
        return msg;
    }

    public boolean isNewAcct(Integer userType) {
        if (userType == 1) {
            return true;
        } else {
            return false;
        }
    }

    public boolean isMobile(Integer mobileType) {
        if (mobileType == 1) {
            return true;
        } else {
            return false;
        }
    }
}

end

案例中规则为:

如果  (是否新用户(1)) 则 { 赠送优惠券(1)} 否则 { 赠送积分(1)} 如果 (是否有手机号(1)) 则 {发送短信(\"欢迎您哦\")}

如果此时我要修改,我可以直接修改语句为:

如果  (是否新用户(2)) 则 { 赠送优惠券(1)} 否则 { 赠送积分(1)} 如果 (是否有手机号(1)) 则 {发送短信(\"欢迎您哦\")}

如果把这个规则直接作为配置化,只要语句符合规则,直接修改就ok了。

<think>我们正在讨论微服务架构下如何集中管理QLExpress规则。结合之前的安全讨论,规则管理需要兼顾安全性和可维护性。 核心思路:建立规则中心服务,实现规则的统一管理、发布和安全控制。 具体方案如下: ### 一、架构设计 1. **规则中心微服务** 创建独立服务管理所有规则,提供: - 规则版本控制(Git集成) - 规则语法校验 - 权限管理(RBAC) - 审计日志 2. **服务依赖关系** ```mermaid graph LR A[业务服务A] -->|HTTP/GRPC| R[规则中心] B[业务服务B] --> R C[管理后台] --> R ``` ### 二、关键实现 3. **规则存储模型** 数据库设计示例: ```sql CREATE TABLE rules ( id BIGINT PRIMARY KEY, rule_key VARCHAR(50) UNIQUE, -- 规则唯一标识 content TEXT NOT NULL, -- 规则脚本 version INT DEFAULT 1, -- 版本号 status TINYINT(1), -- 1启用 0禁用 creator VARCHAR(32), create_time TIMESTAMP, sign CHAR(64) -- 数字签名 ); ``` 4. **规则加载接口** 业务服务通过接口获取规则: ```java // 规则中心客户端 @FeignClient(name = "rule-center") public interface RuleClient { @GetMapping("/rules/{key}") RuleDTO getRule(@PathVariable String key); } // 使用方业务服务 @Service public class ApprovalService { @Autowired RuleClient ruleClient; public boolean checkBudget(long amount) { RuleDTO rule = ruleClient.getRule("BUDGET_RULE"); // 初始化QLExpress ExpressRunner runner = new ExpressRunner(); // ... 安全配置(参考之前的安全措施) // 执行规则 return (Boolean)runner.execute(rule.getContent(), context); } } ``` 5. **本地缓存优化** 使用Caffeine缓存规则减少网络调用: ```java @Cacheable(value = "rules", key = "#key") public RuleDTO getRuleCacheable(String key) { return ruleClient.getRule(key); } ``` ### 三、安全增强 6. **传输加密** - 规则中心启用HTTPS - 敏感字段使用AES加密存储 7. **访问控制** 基于OAuth2的权限验证: ```yaml # 规则中心配置 security: oauth2: resourceserver: jwt: issuer-uri: https://auth-server/ ``` 8. **规则签名验证** 业务服务加载规则后验证签名: ```java public boolean verifyRule(RuleDTO rule) { String calcSign = SHA256Util.sign(rule.getContent()); return calcSign.equals(rule.getSign()); } ``` ### 四、管理功能 9. **版本灰度发布** 通过标签实现部分服务启用新规则: ```sql UPDATE service_rule SET rule_version = 3 WHERE service_tag IN ('canary-group'); ``` 10. **监控看板** 集成Prometheus监控规则执行: ```java // 注册指标 Counter counter = Counter.build() .name("qlexpress_rule_exec_count") .labelNames("rule_key") .register(); // 执行时记录 counter.labels(ruleKey).inc(); ``` ### 最佳实践 - **规则分类存储**:按业务域划分规则库(如:finance_rules, hr_rules) - **自动化测试**:规则发布前执行单元测试 - **紧急禁用开关**:手动降级有问题的规则 > 该方案实现: > - 统一管理:避免规则分散在代码中 > - 动态更新:实时生效无需重启服务 > - 安全可控:集成多层防护机制[^1] > - 性能保障:本地缓存+批量接口 --- §§相关问题§§ 1. 规则中心如何实现高可用架构? 2. 如何设计QLExpress规则的自动化测试框架? 3. 微服务环境下规则变更如何通知客户端? 4. 规则中心与配置中心(如Nacos)有何区别? </think># 微服务架构下的QLExpress规则集中管理方法 在微服务架构中实现QLExpress规则的集中管理,需要解决规则存储、分发、版本控制和权限管理等关键问题。以下是完整的解决方案: ## 一、架构设计 ```mermaid graph TD A[规则管理中心] -->|发布/更新| B[规则存储库] B -->|推送| C[规则分发服务] C -->|分发| D[服务A] C -->|分发| E[服务B] C -->|分发| F[服务C] D -->|运行时加载| G[QLExpress执行引擎] E -->|运行时加载| G F -->|运行时加载| G H[管理控制台] -->|管理操作| A ``` ## 二、核心组件实现 ### 1. 规则管理中心服务 ```java @RestController @RequestMapping("/rules") public class RuleController { @PostMapping public ResponseEntity<Void> createRule(@RequestBody RuleDTO rule) { // 保存规则到中央存储库 ruleRepository.save(rule); // 触发规则分发 distributionService.distribute(rule); return ResponseEntity.ok().build(); } @GetMapping("/{service}/{key}") public RuleDTO getRule(@PathVariable String service, @PathVariable String key) { return ruleRepository.findByServiceAndKey(service, key); } } ``` ### 2. 规则存储库设计 ```sql CREATE TABLE ql_rules ( id BIGINT PRIMARY KEY AUTO_INCREMENT, rule_key VARCHAR(50) NOT NULL, -- 规则唯一标识 service_name VARCHAR(50) NOT NULL, -- 所属微服务 content TEXT NOT NULL, -- 规则脚本 version INT NOT NULL DEFAULT 1, status TINYINT(1) NOT NULL DEFAULT 0, -- 0:草稿 1:生效 2:禁用 creator VARCHAR(50) NOT NULL, create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP, update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, signature VARCHAR(64) NOT NULL, -- 规则签名 UNIQUE KEY uniq_key_service (rule_key, service_name) ); ``` ### 3. 规则分发服务 ```java @Service public class RuleDistributionService { @Autowired private ServiceDiscoveryClient discoveryClient; @Autowired private RestTemplate restTemplate; public void distribute(RuleDTO rule) { // 1. 获取所有需要此规则的微服务实例 List<ServiceInstance> instances = discoveryClient.getInstances(rule.getServiceName()); // 2. 异步推送到各个实例 instances.forEach(instance -> { String url = "http://" + instance.getHost() + ":" + instance.getPort() + "/rules/update"; restTemplate.postForObject(url, rule, Void.class); }); } } ``` ## 三、客户端集成方案 ### 1. 规则加载器 ```java @Component public class RuleLoader { @Autowired private RuleClient ruleClient; // 连接到规则中心 private Map<String, ExpressRunner> runners = new ConcurrentHashMap<>(); @Scheduled(fixedDelay = 300000) // 每5分钟同步一次 public void syncRules() { List<RuleDTO> rules = ruleClient.getRulesForService(serviceName); rules.forEach(this::loadRule); } private void loadRule(RuleDTO rule) { ExpressRunner runner = new ExpressRunner(); // 安全配置(参考之前的防护措施) runner.addOperatorWithAlias("大于", ">", "$1 > $2"); runner.addBlackOperator("System"); // 加载脚本 runner.addMacro(rule.getKey(), rule.getContent()); runners.put(rule.getKey(), runner); } public Object execute(String ruleKey, Map<String, Object> context) { ExpressRunner runner = runners.get(ruleKey); if (runner == null) throw new RuleNotFoundException(ruleKey); return runner.execute(ruleKey, context, null, true, false); } } ``` ### 2. 客户端配置 ```yaml # application.yml ql-rules: center: url: http://rule-center-service refresh-interval: 300000 # 5分钟 service-name: approval-service ``` ## 四、安全加固措施 1. **传输安全** ```java // 规则签名验证 public boolean verifySignature(RuleDTO rule) { String calculated = DigestUtils.sha256Hex(rule.getContent()); return calculated.equals(rule.getSignature()); } ``` 2. **细粒度权限控制** ```java @PreAuthorize("hasPermission(#rule.serviceName, 'RULE_WRITE')") @PostMapping public ResponseEntity<Void> updateRule(@RequestBody RuleDTO rule) { // 更新逻辑 } ``` 3. **规则沙箱隔离** ```java ExpressRunner runner = new ExpressRunner(true, true); runner.setSandBoxMode(new RuleSandbox()); // 自定义沙箱策略 public class RuleSandbox implements ISandbox { @Override public boolean exitSandbox(String feature) { return !feature.contains("System"); // 禁止系统操作 } } ``` ## 五、高级管理功能 ### 1. 规则版本管理 ```mermaid gitGraph commit id: "v1.0" commit id: "v1.1" branch feature-rule checkout feature-rule commit id: "新规则" checkout main merge feature-rule id: "v1.2" ``` ### 2. 灰度发布机制 ```java // 规则分发服务扩展 public void distribute(RuleDTO rule, String... serviceGroups) { List<ServiceInstance> instances = discoveryClient.getInstances(rule.getServiceName()) .stream() .filter(instance -> inGroup(instance, serviceGroups)) .collect(Collectors.toList()); // 分发到筛选后的实例 } ``` ### 3. 监控与审计 ```java @Aspect @Component public class RuleAuditAspect { @Around("execution(* com..RuleLoader.execute(..))") public Object auditRuleExecution(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); long duration = System.currentTimeMillis() - start; // 记录审计日志 auditService.log( joinPoint.getArgs()[0], // ruleKey joinPoint.getArgs()[1], // context duration, result ); return result; } } ``` ## 六、最佳实践建议 1. **规则分类存储** - 按业务域划分规则库(如:财务规则、HR规则) - 按敏感级别设置不同安全策略 2. **双重验证机制** ```java // 客户端双重验证 public void loadRule(RuleDTO rule) { if (!verifySignature(rule)) throw new SecurityException(); if (!validateSyntax(rule)) throw new RuleSyntaxException(); // 加载规则 } ``` 3. **熔断降级策略** ```java @HystrixCommand(fallbackMethod = "fallbackRule") public Object executeRule(String key, Map<String, Object> context) { return ruleLoader.execute(key, context); } private Object fallbackRule(String key, Map<String, Object> context) { // 返回默认审批结果或缓存结果 } ``` 4. **性能优化建议** - 使用本地缓存减少网络请求 - 预编译高频使用规则 - 批量获取规则接口 > 该方案通过集中化管理实现了: > - 统一规则存储与版本控制 > - 安全可靠的规则分发机制 > - 细粒度的权限管理体系 > - 高效的运行时执行环境[^1] ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值