- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
这实际上可能与 Drools 本身无关,但可能只是有一个 Java native 解决方案。我只是一个 Java 菜鸟,继承了一个项目,所以我试图了解最佳实践。
我们有一个基于规则的 Multi-Tenancy 系统,其中业务规则可以由我们的客户动态配置。我们将每个客户端的编译规则存储在 ConcurrentHashMap
中。看起来像这样
ConcurrentMap<String, KieBase> rules = new ConcurrentHashMap<>();
哪里string
是代表每个唯一客户端的 UUID。然而,这个问题是水平扩展计算是一个问题,因为这只是一个内存中的 HashMap ,每次更改都会重新编译。如果我们将其扩展,每个客户端都需要监听新的规则更改并在每次发生时重新编译,这感觉很浪费,因为它们总是会产生相同的结果。
我的最终目标是将这些计算出的规则存储在 JVM 之外,以便多个实例可以共享编译后的规则,并且这些实例中的任何一个都可以安全地同时为特定客户端重新编译规则,而所有其他实例都可以可能需要为 那个客户端 等待的规则
所以我的想法是将 Redis 用作 k/v 锁/存储,其中键是 client_id,值是 Drools KieBase 对象的序列化版本。重新计算将使用 transaction 将 redis 存储锁定在该键上(或一些类似的锁定算法)以便其他需要该 client_id 的 KieBase 的实例将等到编译完成并写回数据库。
所以我有几个问题:
最佳答案
一个简单的 ObjectOutputStream 就足以序列化一个 KieBase 对象。它下面用于写入文件,但您可以通过写入 ByteArrayOutputStream 并以任一形式获取结果来创建 String 或 byte[]。
KieBase kieBase = kieContainer.getKieBase();
FileOutputStream fos = new FileOutputStream( OUTPATH );
ObjectOutputStream oos = new ObjectOutputStream( fos );
oos.writeObject( kieBase );
oos.close();
FileInputStream fis = new FileInputStream( OUTPATH );
ObjectInputStream ois = new ObjectInputStream( fis );
KieBase kieBase1 = (KieBase)ois.readObject();
ois.close();
至于锁定,这取决于您是否需要针对并行运行的多个应用程序(在网络中)锁定外部表示,或者是否有一个(服务器)应用程序将所有内容保存在 HashMap 中。在后一种情况下,任何 Java 对象都有一个监视器:
synchronized( idString ) {
idString.wait(); // or overloaded form with timeout
}
// different thread
synchronized( idString ){
idString.notify();
}
您可以引用 Brian Goetz 的书“Java Concurrency in Practice”。
编辑任何体面的数据库都有写锁定机制。此外,在您的情况下,您甚至可以使用简单的文件存储和文件锁定进行管理,这在 MS Windows 和所有 Unices 上都可用。
关于java - 如何为外部存储序列化 JBoss Drools KieBase 集合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41645483/
我是一名优秀的程序员,十分优秀!