背景
公司使用drools规则引擎过程中,一个规则文件中差不多10个rule,每一次访问都需要耗费800M内存,导致频繁GC,同时classloader实例数每构建一次都会增加,导致nonHeap区内存占用量跟着递增,导致比较频繁的fullGC(此时老年代使用率还不到10%)。当并发量稍微大一点服务就会挂掉。

原因
规则文件加入drools的时候需要解析编译,每访问一次接口都导致规则解析编译一次,经过监控测试发现800M内存和classloader递增问题就是在解析过程中产生的

解决思路
解决问题的本质是缓存已经解析的规则对象,避免重复加载。

缓存以后注意点

  • 缓存淘汰策略
  • 当规则文件发生变化的时候,要及时更新缓存

用到的技术:drools+Guava
建议用Caffeine替代Guava,我这里是公司规定使用Guava,所以代码实例使用的Guava

代码

 // 建议使用Caffeine代替guavaprivate static Cache<String, Entity> guavaCache;@Value("${guava.drools.maximumSize:1000}")private Integer maximumSize;// 默认一周@Value("${guava.drools.expireAfterAccess:168}")private int expireAfterAccess;/*** 构建guava**/@PostConstructpublic void init() {guavaCache = CacheBuilder.newBuilder().maximumSize(maximumSize).expireAfterAccess(expireAfterAccess, TimeUnit.HOURS).build();}/*** 执行规则* * @param drl 规则字符串* @param fact 规则fact* @param agendaStr agenda* @param lastTime 规则最后修改时间*/public void excute(String drl, String fact, String agendaStr, Long lastTime) {KieSession kSession = null;try {kSession = getSession(agendaStr, drl, lastTime);// 新增议程组Agenda agenda = kSession.getAgenda();agenda.getAgendaGroup(agendaStr).setFocus();kSession.insert(log);kSession.insert(fact);kSession.fireAllRules();} catch (Exception e) {log.error("drools rule excute ex.", e);} finally {if (Objects.nonNull(kSession)) {kSession.dispose();}}}public KieSession getSession(String agenda, String drl, Long lastTime) {Entity entity = guavaCache.getIfPresent(agenda);KnowledgeBaseImpl kieBase;if (Objects.isNull(entity)) {kieBase = buildKieBase(agenda, drl, lastTime);} else {if (lastTime.equals(entity.getLastTime())) {kieBase = entity.getKnowledgeBase();} else {// 此处无需删除,直接覆盖即可kieBase = buildKieBase(agenda, drl, lastTime);}}return kieBase.newKieSession();}/*** 构建 {@link KnowledgeBaseImpl}** @param agenda   规则文件唯一key* @param drl      规则内容* @param lastTime 规则最后修改时间* @return*/private KnowledgeBaseImpl buildKieBase(String agenda, String drl, Long lastTime) {log.info("drools create kieBase. agenda:{}", agenda);KieHelper helper = new KieHelper();helper.addContent(drl, ResourceType.DRL);KnowledgeBaseImpl kieBase = (KnowledgeBaseImpl) helper.build();// 解除严格模式kieBase.getConfiguration().setProperty("drools.dialect.mvel.strict", "false");guavaCache.put(agenda, new Entity(kieBase, lastTime));return kieBase;}public void removeKieBase(String agenda) {guavaCache.invalidate(agenda);}class Entity {KnowledgeBaseImpl knowledgeBase;/*** 规则最后修改时间*/Long lastTime;Entity(KnowledgeBaseImpl base, Long lastTime) {this.knowledgeBase = base;this.lastTime = lastTime;}public KnowledgeBaseImpl getKnowledgeBase() {return knowledgeBase;}public Long getLastTime() {return lastTime;}}

备注:
1、入口方法excute,其中drl,我们的规则是以字符串的方式存储在数据库中,业务方动态查询出来并传进来
2、lastTime参数,是随drl存储在库中的,每次drl修改都会同步更新lastTime,并作为规则的版本标记
3、agenda参数,这个参数在我们业务中是能唯一确定一条规则的,所以以他作为缓存的key

重点关注
代码的关键点在于把构建的KnowledgeBaseImpl对象要做一个缓存, 实例中的代码是结合我们系统的业务,而且是兼容整合旧代码改过来的,在设计上存在缺陷,强烈建议根据这个思路进行重写

drools规则引擎耗费内存问题解决相关推荐

  1. drools规则引擎因为内存泄露导致的内存溢出

    进入这个问题之前,先了解一下drools: 在很多行业应用中比如银行.保险领域,业务规则往往非常复杂,并且规则处于不断更新变化中,而现有很多系统做法基本上都是将业务规则绑定在程序代码中. 主要存在的问 ...

  2. Drools 规则引擎死循环问题解决

    在<Drools7 规则引擎视频教程>中已经讲到,使用modify或update的时候在某种程度上会导致死循环. 昨天一同学在使用Drools规则引擎时便遇到了该问题.下面看该同学贴出来的 ...

  3. 详解:Drools规则引擎探究

    引入 ▐ 问题引入 天猫奢品业务方为了吸引更多的新客,和提高会员的活跃度,做了一期活动,通过购买天猫奢品频道内的任意商品就赠送特殊积分,积分可以直接兑换限量的奢品商品.假如业务方给的规则如下: 主刃同 ...

  4. 使用 Drools 规则引擎实现业务逻辑,可调试drl文件

    http://www.srcsky.com/tech/arts/389.html 代码下载http://download.csdn.net/detail/zhy011525/2462313 使用 Dr ...

  5. SpringBoot整合Drools规则引擎动态生成业务规则

    最近的项目中,使用的是flowable工作流来处理业务流程,但是在业务规则的配置中,是在代码中直接固定写死的,领导说这样不好,需要规则可以动态变化,可以通过页面去动态配置改变,所以就花了几天时间去研究 ...

  6. Drools规则引擎之常用语法

    一.基础api 在 Drools 当中,规则的编译与运行要通过Drools 提供的各种API 来实现,这些API 总体来讲可以分为三类:规则编译.规则收集和规则的执行.完成这些工作的API 主要有Kn ...

  7. 使用 Drools 规则引擎实现业务逻辑

    要求施加在当今软件产品上的大多数复杂性是行为和功能方面的,从而导致组件实现具有复杂的业务逻辑.实现 J2EE 或 J2SE 应用程序中业务逻辑最常见的方法是编写 Java 代码来实现需求文档的规则和逻 ...

  8. drools规则引擎的在项目中的使用手记

    需求 按照登录用户的会员等级 和签到周期 根据一定的计算规则送积分.由于之前都是通过if else去做的控制.规则变更的时候可能需要重新调整代码甚至发布服务. 由于不想再每次规则变更后需要调整代码,于 ...

  9. Spring Boot整合Drools规则引擎实例

    1.DRools介绍 官网:https://www.drools.org/ 规则引擎主要完成的就是将业务规则从代码中分离出来. DRools一款由JBoss组织提供的基于Java语言开发的开源规则引擎 ...

最新文章

  1. echarts的词云图表类型有哪些_词云图的几种制作方法评测,你pick哪款
  2. 第十五届全国大学生智能汽车竞赛人工智能创意赛
  3. java迁移文件下的文件_Laravel迁移 - 一次性多次迁移(文件)
  4. Open Source Bing Maps API for ASP.NET MVC
  5. 几张动态图捋清Java常用数据结构及其设计原理
  6. web service design time table
  7. Netty与传统Server对比
  8. 如何在请求转发的时候对url解码_Java技术分享:Forward和Redirect这两种转发方式的区别...
  9. altiumdesigner的基本你操作
  10. mysql去除重复数据 重建表_MySQL 中重建mysql库中的表
  11. spss无法连接到本地计算机,通过远程连接打开SPSS产品时,收到许可证错误信息。从本地打开同一产品时没有错误。...
  12. 【python】chardet函数用法
  13. 树莓派版本及各种引脚
  14. VMware虚拟机XP系统安装图文教程
  15. FireFox把Gmail变成大容量网络硬盘
  16. 【论文笔记】虚拟领导者控制编队机动
  17. node 文件重命名
  18. Kubernetes全栈架构师(资源调度下)--学习笔记
  19. 旧版android模拟器,Mrpoid2模拟器
  20. 日语词汇辨析:以来と以降と以後

热门文章

  1. magic版本和android版本,荣耀Magic有几个版本?荣耀Magic各版本区别对比评测
  2. android imageview 锯齿,Android 圆形ImageView 怎样解决边缘锯齿的有关问题
  3. 用js将姓氏转变为星号,或者将名字转变为星号
  4. eWorld.ASP.Maker.v2017.0.3.x86.Incl.Keygen-DARKSiDERS
  5. 阿里天池FashionAI服装属性标签识别Top1%方案分享
  6. python的网络请求库urllib、urllib2、urllib3、request的联系
  7. 组成计算机的常见硬件故障,计算机硬件组成与常见故障排错
  8. 使用mp3tagiconv解决MP3乱码问题
  9. ArtCAM入门简单教程(二)——浮雕
  10. linux防火墙无法开启问题