【问题标题】:Interacting with a large java program as a service?与作为服务的大型 Java 程序交互?
【发布时间】:2016-05-23 01:28:01
【问题描述】:

我该怎么做?

我想做的是一次加载斯坦福 NLP,然后通过 HTTP 或其他端点与之交互。原因是加载需要很长时间,并且加载每个要分析的字符串是不可能的。

例如,这里是斯坦福 NLP 在一个简单的 C# 程序中加载,该程序加载了 jars...

    Reading POS tagger model from edu/stanford/nlp/models/pos-tagger/english-left3words/english-left3words-distsim.tagger ... done [9.3 sec]. 
    Loading classifier from D:\Repositories\StanfordNLPCoreNLP\stanford-corenlp-3.6.0-models\edu\stanford\nlp\models\ner\english.all.3class.distsim.crf.ser.gz ... done [12.8 sec]. 
    Loading classifier from D:\Repositories\StanfordNLPCoreNLP\stanford-corenlp-3.6.0-models\edu\stanford\nlp\models\ner\english.muc.7class.distsim.crf.ser.gz ... done [5.9 sec]. 
    Loading classifier from D:\Repositories\StanfordNLPCoreNLP\stanford-corenlp-3.6.0-models\edu\stanford\nlp\models\ner\english.conll.4class.distsim.crf.ser.gz ...  done [4.1 sec]. 
done [8.8 sec]. 

Sentence #1 ...

超过 30 秒。如果这些都必须每次加载,哎呀。为了展示我想在 java 中做什么,我用 C# 编写了一个工作示例,这个完整的示例有一天可能会对某人有所帮助:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using java.io;
using java.util;
using edu.stanford.nlp;
using edu.stanford.nlp.pipeline;
using Console = System.Console;

namespace NLPConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            // Path to the folder with models extracted from `stanford-corenlp-3.6.0-models.jar`
            var jarRoot = @"..\..\..\..\StanfordNLPCoreNLP\stanford-corenlp-3.6.0-models";
            // Text for intial run processing
            var text = "Kosgi Santosh sent an email to Stanford University. He didn't get a reply.";
            // Annotation pipeline configuration
            var props = new Properties();
            props.setProperty("annotators", "tokenize, ssplit, pos, lemma, ner, parse, sentiment"); 
            props.setProperty("ner.useSUTime", "0");
            // We should change current directory, so StanfordCoreNLP could find all the model files automatically
            var curDir = Environment.CurrentDirectory;
            Directory.SetCurrentDirectory(jarRoot);
            var pipeline = new StanfordCoreNLP(props);
            Directory.SetCurrentDirectory(curDir);
            // loop
            while (text != "quit")
            {
                // Annotation
                var annotation = new Annotation(text);
                pipeline.annotate(annotation);
                // Result - Pretty Print
                using (var stream = new ByteArrayOutputStream())
                {
                    pipeline.prettyPrint(annotation, new PrintWriter(stream));
                    Console.WriteLine(stream.toString());
                    stream.close();
                }
                edu.stanford.nlp.trees.TreePrint tprint = new edu.stanford.nlp.trees.TreePrint("words");
                Console.WriteLine();
                Console.WriteLine("Enter a sentence to evaluate, and hit ENTER (enter \"quit\" to quit)");
                text = Console.ReadLine();
            } // end while
        }
    }
}

因此加载需要 30 秒,但是每次在控制台上给它一个字符串时,解析和标记该字符串需要一秒钟的最小时间。

您可以看到我在 while 循环之前加载了 jar 文件。

这最终可能是一个套接字服务、HTML 或其他可以处理请求(以字符串的形式)并返回解析的东西。

我的最终目标是在 Nifi 中使用一种机制,通过一个可以发送要解析的字符串的处理器,并在不到一秒的时间内返回它们,而传统的 Web 服务器线程示例则​​需要 30 多秒(例如)用来。每个请求都会加载整个内容 30 秒,然后开始工作。我希望我说清楚了!

如何做到这一点?

【问题讨论】:

  • 你实际上并没有问过问题。
  • 那么你的问题是什么?
  • 我猜您正在寻找如何使用 Apache NiFi 来利用 Standford 的 NLP(然后可以作为 Wbe 服务流程中的一个步骤添加)的方向?您是否有理由涉及 C# 而不仅仅是使用 java NLP 库编写 NiFi 处理器?您可以在 OnSchedule 方法中初始化所有内容,然后处理进入 OnTrigger 的字符串
  • 好的。让我换个说法:“我想做的是一次加载斯坦福 NLP,然后通过 HTTP 或其他端点与之交互。”说“我怎样才能加载斯坦福 NLP 一次,然后通过 HTTP 或其他端点与之交互。”。但是对于任何需要时间加载的 Java 进程来说,这个问题可能都是一样的,对吧?

标签: java c# multithreading sockets apache-nifi


【解决方案1】:

您列出的任何机制都是通过 Apache NiFi 利用该服务的完全合理的前进路线。根据您的需求,与 NiFi 标准版本捆绑在一起的一些处理器和扩展可能足以与您提议的 Web 服务或类似产品进行交互。

如果您正在努力在 NiFi 本身内执行所有这些操作,自定义 Controller Service 可能是向 NiFi 提供该资源的绝佳途径,该资源属于应用程序本身的生命周期内。

NiFi 可以通过控制器服务和自定义处理器等项目进行扩展,我们有一些 documentation 可以帮助您开始这条道路。

其他细节当然有助于提供更多信息。请随时在此处跟进其他 cmets 和/或通过我们的mailing lists 与社区联系。

如果不清楚 NiFi 是 JVM 驱动的并且工作将使用 Java 或 JVM 友好的语言完成,我确实想提出一项。

【讨论】:

  • 这真是太好了。我希望将文本解析器/标记器作为 Nifi 可以向其发送文本的服务,然后输出标记。在不了解 Nifi 服务的情况下,我正在考虑创建某种可以多线程的服务,但不会为每个线程加载代码(30 秒以上)。创建 Nifi 服务可能比创建 Web/端口服务更容易......我还有很多工作要做,但这给了我一些切实的方向而不是猜测。谢谢!
【解决方案2】:

您应该查看斯坦福 NLP 在 3.6.0 版中引入的 the new CoreNLP Server。似乎它只是你想要的? ETS 等其他一些人也做过类似的事情。

要点:如果大量使用它,您可能(目前)想要从 github HEAD 获取最新的 CoreNLP 代码,因为它包含一些对服务器的修复,这些修复将在下一个版本中发布。

【讨论】:

  • 克里斯托弗,我无法投票赞成你的答案...我浏览了服务器,但应该进一步阅读。我认为我的主要问题是如何运行一个无需重新加载即可接受输入并提供输出的 java 程序。但它会是单线程的(坏的)。我将研究 NLP 服务器!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-15
  • 2017-10-24
  • 1970-01-01
  • 2017-11-01
相关资源
最近更新 更多