JRuby:从Rack应用程序调用Java代码并将其保存在内存中
我目前了解Java和Ruby,但从未使用过JRuby。我想在Rack(sinatra)web应用程序中使用一些RAM和计算密集型Java代码。特别是,这段Java代码将大约200MB的数据加载到RAM中,并提供了使用内存中的数据进行各种计算的方法 我知道在JRuby中从Ruby调用Java代码是可能的,但在我的例子中还有一个额外的要求:这个Java代码需要加载一次,保存在内存中,并作为共享资源保持可用,以便sinatra代码(由多个web请求触发)调用 问题JRuby:从Rack应用程序调用Java代码并将其保存在内存中,java,sinatra,jruby,rack,Java,Sinatra,Jruby,Rack,我目前了解Java和Ruby,但从未使用过JRuby。我想在Rack(sinatra)web应用程序中使用一些RAM和计算密集型Java代码。特别是,这段Java代码将大约200MB的数据加载到RAM中,并提供了使用内存中的数据进行各种计算的方法 我知道在JRuby中从Ruby调用Java代码是可能的,但在我的例子中还有一个额外的要求:这个Java代码需要加载一次,保存在内存中,并作为共享资源保持可用,以便sinatra代码(由多个web请求触发)调用 问题 这样的设置可能吗 我需要做什么才能完
需要注意的一点是,您使用的java库可能不是线程安全的。如果您在tomact中运行ruby代码,则可以并发执行多个请求,并且这些请求都可以访问您的共享java库。如果您的库不是线程安全的,则必须使用某种类型的设置来防止多个线程访问它。是的,设置是可能的(请参见下面关于部署的内容),要完成此设置,我建议使用 Jruby中的单例 关于问题:我同意的答案,即单例作为模块模式,我更喜欢使用单例mixin 例子 我在这里发布了一些测试代码,您可以将其用作概念证明: JRuby sinatra侧:
#文件:sample_app.rb
需要“sinatra/基地”
需要“java”#https://github.com/jruby/jruby/wiki/CallingJavaFromJRuby
java#导入org.rondadev.samples.StatefulCalculator#在这里导入java类
#单例作为模块加载一次,保存在内存中
模块应用程序
模块全局自扩展
def计算
@calc | |=StatefulCalculator.new
结束
结束
结束
#您可以调用一个方法来加载statefull java对象中的数据
应用程序::Global.calc.open\u
类示例
您可以在tomcat中使用trinidad
启动它,或者只需使用rackup config.ru
启动它,但您需要:
请注意,此处的寄存器
仅为双精度
,但在实际代码中,您可以在实际场景中使用大数据结构
部署
您可以使用Mongrel、Thin(实验)、Webrick(但谁会这么做呢?)甚至以Java为中心的应用程序容器(如Glassfish、Tomcat或JBoss)进行部署
使用构建在JBoss应用服务器上的TorqueBox。
JBossAS包括高性能集群、缓存和消息传递功能
是一个RubyGem,允许您在嵌入式ApacheTomcat容器中运行任何基于机架的小程序包装
线程同步
Sinatra将使用Mutex#synchronize方法对每个请求进行锁定,以避免线程之间出现争用情况。如果您的sinatra应用程序是多线程且非线程安全的,或者您使用的任何gems都不是线程安全的,那么您需要执行设置:lock
,true
,以便在给定时间只处理一个请求。。否则默认情况下,lock
为false
,这意味着同步
将直接向块屈服
资料来源:Franco,tyvm。这是一个很好的答案。如果我有任何问题的话,我只想在明天完成这一切,然后再接受它。为了支持这个答案的测试,我分享了以下要点:
#file: config.ru
root = File.dirname(__FILE__) # => "."
require File.join( root, 'sample_app' ) # => true
run Sample # ..in sample_app.rb ..class Sample < Sinatra::Base