Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/9.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
JRuby:从Rack应用程序调用Java代码并将其保存在内存中_Java_Sinatra_Jruby_Rack - Fatal编程技术网

JRuby:从Rack应用程序调用Java代码并将其保存在内存中

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和Ruby,但从未使用过JRuby。我想在Rack(sinatra)web应用程序中使用一些RAM和计算密集型Java代码。特别是,这段Java代码将大约200MB的数据加载到RAM中,并提供了使用内存中的数据进行各种计算的方法

我知道在JRuby中从Ruby调用Java代码是可能的,但在我的例子中还有一个额外的要求:这个Java代码需要加载一次,保存在内存中,并作为共享资源保持可用,以便sinatra代码(由多个web请求触发)调用

问题
  • 这样的设置可能吗
  • 我需要做什么才能完成它?我甚至不确定这是JRuby本身的问题,还是需要在web服务器中配置的问题。我有使用Passenger和Unicorn/nginx的经验,但没有使用Java服务器的经验,因此,如果这涉及到Java服务器(如Tomcat)的配置,任何有关这方面的信息都会有所帮助
  • 我真的不知道从哪里开始寻找,或者是否有更好的方法来解决这个问题,因此任何和所有建议或相关链接都非常感谢。

    是关于如何将sinatra应用部署到的一些说明

    如果保留对已加载java实例的引用,则java代码可以加载一次并重用。您可以在ruby中保留来自全局变量的引用


    需要注意的一点是,您使用的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