问候, 我无法提供该问题的所有细节,因此这里的关键细节。如何避免性能瓶颈使用JNI时Java Web应用程序/服务
我有一个本地的dll(和相应的.so)包装静态库,这是由艾菲尔编程语言创建的。 我已经写了一个关于静态库的C++包装器,并且我已经成功地将它公开给了Java。但是,如果我在Web应用程序中使用这个DLL,事情会变得有点复杂。问题是多个Java线程将访问相同的C++代码,其中本地上下文(?)由不同类的实例在调用之间保持不变。 为了使用来自Eiffel代码的功能,必须从C++初始化Eiffel运行时,然后使用Eiffel库来利用C++中的Eiffel类。 不幸的是,这意味着所有到Java服务器端的传入请求最终都会在C++中的一个位置(在本地dll中),只有一个Eiffel运行时。 这种情况迫使我使整个Eiffel运行时线程安全,并且只有一个Java线程的操作可以通过传递JNI来使用Eiffel代码。 我有一种感觉,这可能很快成为一个可扩展性问题。
我觉得我可能需要的工艺池,每个加载同一个DLL(或.so下* nix中),这将送达从Java线程进入一个副本。所以一旦加载共享库,C++代码将创建10个进程,并且来自Java端的进入线程将通过C++代码分配给这些进程。 事件的流会是这样:
Java线程访问共享库的本机代码(C++)。 原生代码检查哪些进程可从进程池 利用通过IPC的方法之一,标志着它忙(可能使用一个线程?)
这是唯一的跨平台的方式我能想到的安全地加载相同的一段代码(Eiffel运行时和埃菲尔类),没有任何线程安全问题。
这一切都是由于艾菲尔运行时是昂贵的,和全球组件,我必须通过JNI暴露。
或者我应该简单地用线程安全的操作,其中只有一个线程从JNI提供在任何时间去? 我可以用Java做什么技巧来创建每个仅使用单个Eiffel运行时的轻量级隔离jvm容器?
您的反馈将不胜感激。
问候 谢雷夫
埃菲尔代码基数很大,目前没有重写它的机会。我正在研究创建多个沙盒jvms或应用服务器实例,这些实例在后台都使用单线程安全dll。我看不到如何使用JMS与传入的Web服务请求,需要连接到jni后端,你能解释一点吗?无论如何感谢您的回应。 – mahonya 2010-10-17 16:47:18
我扩大了一点。我们正在使用这种模式取得一些成功。 – djna 2010-10-18 05:48:07
看起来很有希望,感谢您的更新。我不确定我能否得到返回响应的机制。我可能会让Web服务调用等待,直到它收到来自jms队列的请求的响应。这可能是确保线程安全性的一种更好的方式,而不必考虑C++或JNI线程安全机制的具体细节。 – mahonya 2010-10-19 10:51:32