You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drools 7.55.0加载10万级规则内存占用高、启动慢问题咨询

Drools 7.55.0.Final 内存占用过高、启动慢、首请求耗时长问题排查

业务场景

我们当前使用Drools V 7.55.0.Final版本进行开发,业务场景为:每次API请求仅需处理1-10个Fact对象,但需匹配的规则总量约为10万条。
单条规则示例如下:

rule "Rule-000000-2627"
when
    discountObject: Discount(purchaseSource == "FLIPKART" && customerType == "NEW" && bank == "HDFC" &&
    purchaseType == "BNPL" && apparelType == "SHIRT" && price >= 100 && price < 200)
then
    discountObject.setDiscount(2);
end

业务使用的Discount实体类定义如下:

public class Discount {
    private String name;
    private String purchaseSource;
    private String customerType;
    private String bank;
    private String purchaseType;
    private String apparelType;
    private int price;
    private int discount;
}

现有集成代码

Drools配置类

public class DroolDiscountConfig {
    private KieServices kieServices = KieServices.Factory.get();

    @Value( "${drool.rule.file}" )
    private String droolConfigFile;


    private KieFileSystem getKieFileSystem() throws IOException {
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        Long startTime = Utility.startTime();
        String[] droolFiles = this.droolConfigFile.split(",");
        for(String droolFile: droolFiles) {
            kieFileSystem.write(ResourceFactory.newFileResource(droolFile));
        }
        Long elapseTime = Utility.elapsedTime(startTime);
        System.out.println("Completed loading drool file " + droolConfigFile + " in " + elapseTime);
        return kieFileSystem;
    }

    @Bean
    public KieContainer getKieContainer() throws IOException {
        System.out.println("Container created...");
        getKieRepository();
        Long startTimeKieBuilder = Utility.startTime();
        KieBuilder kb = kieServices.newKieBuilder(getKieFileSystem());
        kb.buildAll();
        System.out.println("Kie builder took " + Utility.elapsedTime(startTimeKieBuilder));

        Long startTimeKieModule = Utility.startTime();
        KieModule kieModule = kb.getKieModule();
        System.out.println("Kie Module generation took " + Utility.elapsedTime(startTimeKieModule));

        Long startTimeKieContainer = Utility.startTime();
        KieContainer kContainer = kieServices.newKieContainer(kieModule.getReleaseId());
        System.out.println("KieContainer generation took " + Utility.elapsedTime(startTimeKieContainer));
        return kContainer;

    }

    private void getKieRepository() {
        Long startTimeKieRepo = Utility.startTime();
        final KieRepository kieRepository = kieServices.getRepository();
        kieRepository.addKieModule(new KieModule() {
            public ReleaseId getReleaseId() {
                return kieRepository.getDefaultReleaseId();
            }
        });
        System.out.println("KieRepo generation took " + Utility.elapsedTime(startTimeKieRepo));
    }
}

接口层Controller代码

@RestController
public class DiscountController {

    @Autowired
    private KieContainer kieContainer;

    @PostMapping("/discount")
    public List<Discount> viewDiscount(@RequestBody List<Discount> discounts) {
        StatelessKieSession statelessKieSession = kieContainer.newStatelessKieSession();
        statelessKieSession.execute(discounts);
        return discounts;
    }
}

现存问题

当前我们将所有规则写入单个大小为40MB的drl文件中,服务启动时内存占用高达5-6GB;通过VisualVM分析内存dump发现,大部分内存被byte[]与String[]类型对象占用,未定位到具体异常根因。我们需要确认当前Drools的使用方式是否符合最佳实践,以及如何优化以降低过高的内存消耗。
除此之外还存在三个明确问题:

  • 首个API请求响应耗时过长,约30秒
  • 服务整体启动耗时过长,约5分钟
  • 若将JVM堆内存限制为3-4GB,服务启动过程中会抛出OutOfMemoryError错误,错误栈如下:
ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt:
org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'discountController': Unsatisfied dependency expressed through field 'kieContainer'; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'getKieContainer' defined in class path resource 
[load/test/DroolDiscountConfig.class]: Bean instantiation via factory method failed; nested exception is
org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.kie.api.runtime.KieContainer]: 
Factory method 'getKieContainer' threw exception; nested exception is java.lang.OutOfMemoryError: Java heap space

内容的提问来源于stack exchange,提问作者Juvenik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:24:42