Java 如何为外部存储序列化JBoss库集合?
这实际上可能与Drools本身无关,但可能只是一个Java本机解决方案。我只是一个彻头彻尾的JavaNoob,继承了一个项目,所以我试图了解最佳实践 我们有一个基于规则的多租户系统,其中业务规则可以由我们的客户动态配置。我们将每个客户机的编译规则存储在一个Java 如何为外部存储序列化JBoss库集合?,java,concurrency,redis,drools,Java,Concurrency,Redis,Drools,这实际上可能与Drools本身无关,但可能只是一个Java本机解决方案。我只是一个彻头彻尾的JavaNoob,继承了一个项目,所以我试图了解最佳实践 我们有一个基于规则的多租户系统,其中业务规则可以由我们的客户动态配置。我们将每个客户机的编译规则存储在一个ConcurrentHashMap中,如下所示 ConcurrentMap规则=新建ConcurrentHashMap(); 其中,字符串是表示每个唯一客户端的UUID。然而,这样做的问题是横向扩展计算是一个问题,因为这只是一个在每次更改时
ConcurrentHashMap
中,如下所示
ConcurrentMap规则=新建ConcurrentHashMap();
其中,字符串
是表示每个唯一客户端的UUID。然而,这样做的问题是横向扩展计算是一个问题,因为这只是一个在每次更改时重新编译的内存哈希映射。如果我们扩展它,每个客户机都需要倾听新规则的更改并在每次更改时重新编译,这感觉像是浪费,因为它们总是会产生相同的结果
我的最终目标是将这些计算出的规则存储在JVM之外,以便多个实例可以共享已编译的规则,并且这些实例中的任何一个都可以安全、并发地重新编译特定客户机的规则,而可能需要该客户机规则的所有其他实例将等待
因此,我的想法是将Redis用作k/v锁/存储,其中密钥是客户机id,值是Drools KieBase对象的序列化版本。重新计算将使用(或某些类似的锁定算法)锁定该密钥上的redis存储,以便需要该客户端id的KieBase的其他实例将等待编译完成并写回db
所以我有几个问题:
简单的ObjectOutputStream足以序列化KieBase对象。在下面,它用于写入文件,但您可以通过写入ByteArrayOutputStream并以任意形式获取结果来创建字符串或字节[]
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并发性的实践》
编辑
任何像样的数据库都有写锁定机制。此外,在您的情况下,您甚至可以使用MS Windows和所有Unice上提供的简单文件存储和文件锁定进行管理。简单的ObjectOutputStream足以序列化KieBase对象。在下面,它用于写入文件,但您可以通过写入ByteArrayOutputStream并以任意形式获取结果来创建字符串或字节[]
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并发性的实践》
编辑
任何像样的数据库都有写锁定机制。此外,在您的情况下,您甚至可以使用MS Windows和所有Unice上提供的简单文件存储和文件锁定进行管理。谢谢。我刚刚阐明了我在上面的最终目标,即在“依赖”场景中实现前者,即在多个正在运行的java进程之间共享此hashmap。虽然这给了我一个好的开始,但我会调查一下ByteArray的事情。看来我可以用绝地武士直接在Redis中储存ByteArray。至于锁定,我不确定我是否可以不使用Redis事务,或者我是否需要更高级的算法,比如Redisson doesAny Delege DB都有写锁定机制。此外,在您的情况下,您甚至可以使用MS Windows和所有Unice上提供的简单文件存储和文件锁定进行管理。我需要db的公共接口,以便可以水平扩展。我想最终我发现Redisson可能会做我想做的事。它将处理分布式并发问题,并允许我将对象序列化为可重用的对象。我刚刚阐明了我在上面的最终目标,即在“依赖”场景中实现前者,即在多个正在运行的java进程之间共享此hashmap。虽然这给了我一个好的开始,但我会调查一下ByteArray的事情。看来我可以用绝地武士直接在Redis中储存ByteArray。至于锁定,我不确定我是否可以不使用Redis事务,或者我是否需要更高级的算法,比如Redisson doesAny Delege DB都有写锁定机制。此外,在您的情况下,您甚至可以使用MS Windows和所有Unice上提供的简单文件存储和文件锁定进行管理。我需要db的公共接口,以便可以水平扩展。我想最终我发现Redisson可能会做我想做的事。它将处理分布式并发问题,并允许我将对象序列化到redis中