Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Process 在java web应用程序/服务中使用jni时,如何避免性能瓶颈_Process_Thread Safety_Java Native Interface_Shared Libraries - Fatal编程技术网

Process 在java web应用程序/服务中使用jni时,如何避免性能瓶颈

Process 在java web应用程序/服务中使用jni时,如何避免性能瓶颈,process,thread-safety,java-native-interface,shared-libraries,Process,Thread Safety,Java Native Interface,Shared Libraries,您好, 我无法提供问题中的所有细节,以下是关键细节 我有一个本机dll(和相应的.so)包装一个静态库,它是由Eiffel编程语言创建的。 我在静态库中写了一个C++包装,我已经成功地把它暴露给了java。然而,如果我在web应用程序中使用这个dll,事情会变得有点复杂。问题是多个java线程将访问相同的C++代码,其中本地上下文(?)被不同类和实例调用之间保持。 为了使用Effelc代码的功能,必须从C++开始初始化EiffelRunTimes,然后使用EiffelScript来利用C++中的

您好, 我无法提供问题中的所有细节,以下是关键细节

我有一个本机dll(和相应的.so)包装一个静态库,它是由Eiffel编程语言创建的。 我在静态库中写了一个C++包装,我已经成功地把它暴露给了java。然而,如果我在web应用程序中使用这个dll,事情会变得有点复杂。问题是多个java线程将访问相同的C++代码,其中本地上下文(?)被不同类和实例调用之间保持。 为了使用Effelc代码的功能,必须从C++开始初始化EiffelRunTimes,然后使用EiffelScript来利用C++中的Eiffl类。 不幸的是,这意味着所有传入java服务器端的请求都在C++中的一个单一位置(在本地DLL中)结束,其中只有一个EffelLunTime. 这种情况迫使我使整个Eiffel运行时线程安全,并且只有一个Java线程的一个操作可以通过JNI使用Eiffel代码。 我有一种感觉,这可能很快成为一个可伸缩性问题

我觉得我可能需要一个进程池,每个进程都加载同一个dll(或*nix下的.so)的副本,该dll将提供给来自Java的传入线程。因此一旦加载了共享库,C++代码将创建,比如说10个进程,java端的传入线程将通过C++代码分配给这些进程。 事件的流程如下所示:

Java线程访问共享库中的本机代码(c++)。 本机代码检查进程池中有哪些进程可用 通过ipc使用其中一个进程,将其标记为忙碌(可能使用线程?)

这是我能想到的唯一一种跨平台的方法,可以安全地加载同一段代码(Eiffel运行时和Eiffel类),而不会出现任何线程安全问题

这都是因为Eiffel运行时是一个昂贵的全局组件,我必须通过JNI公开它

或者我应该简单地使用线程安全操作,在这个操作中,JNI在任何时候都只提供一个线程? 我能用Java做些什么来创建轻量级的、隔离的、类似jvm的容器,每个容器只使用一个Eiffel运行时

非常感谢您的反馈

致意
Seref

第一个问题:如果在单独的进程中加载了DLL的多个副本,它们会正常运行吗?假设“是”,那么您的想法是让多个副本运行声音,这是有潜力的。(实际上,首先要问另一个问题:我假设在Java中重新实现埃菲尔铁塔已经被检查过,并且证明太困难了?)

我倾向于首先检查您的简单、单一、线程安全的方法是否能够提供足够好的性能。如果它不需要扩展性,那么另一种可能性是考虑使用一些便宜的机器(或虚拟机)——这具有简单的优点。不需要太多的开发工作就可以花费几台机器

否则,您关于“服务”流程池的想法听起来是一个合理的想法。有很多不同的进程间通信(IPC)的可能性。根据定义,您在每次呼叫中都要花费很长时间在服务中(否则您会有问题吗?),因此在这种情况下,不需要对实际的IPC机制进行高度优化-有利于简化和易于管理。我将首先介绍一种使用JMS的基于队列的方法——是的,还有很多其他选项,包括RMI或低级套接字——但JMS有两个优点:非常简单,可扩展性差,请求者只在队列上弹出消息,不需要知道可能有多少个服务进程。有趣的是,在一些供应商平台上有C++实现的JMS(XMIS是我使用的),因此在服务过程中甚至不使用java。 详细说明:起始位置是

  WS-Client ---WS Call ---> WS in Web App ---JNI--->C++/Eiffel
我建议使用

  WS-Client ---WS Call ---> WS in Web App --JMS enq--> Q --JMS deq--> Java---JNI--->C++/Eiffel

可以在临时响应队列上返回响应,请求消息包含对Q名称的回复和相关信息


碰巧,后一种模式与我当前的应用程序非常相似,性能很好。我认为在C++/Eiffel引擎中没有Java可能是一个胜利。如果JMS的伪同步使用看起来不吸引人,那么我的替代方案是使用带有远程接口的EJB。我们的想法是将所有的可伸缩性工作都推到基础架构中。

第一个问题:如果在不同的进程中加载了DLL的多个副本,它们会正常工作吗?假设“是”,那么您的想法是让多个副本运行声音,这是有潜力的。(实际上,首先要问另一个问题:我假设在Java中重新实现埃菲尔铁塔已经被检查过,并且证明太困难了?)

我倾向于首先检查您的简单、单一、线程安全的方法是否能够提供足够好的性能。如果它不需要扩展性,那么另一种可能性是考虑使用一些便宜的机器(或虚拟机)——这具有简单的优点。不需要太多的开发工作就可以花费几台机器

否则,您关于“服务”流程池的想法听起来是一个合理的想法。有很多不同的进程间通信(IPC)的可能性。根据定义,您在每次呼叫中都要花费很长时间在服务中(否则您会有问题吗?),因此在这种情况下,不需要对实际的IPC机制进行高度优化-有利于简化和易于管理。我将首先介绍一种使用JMS的基于队列的方法——是的,还有很多其他选项,包括RMI或低级套接字——但JMS有两个优点:非常简单,可扩展性差,请求
  WS-Client ---WS Call ---> WS in Web App --JMS enq--> Q --XMS deq--->C++/Eiffel