【问题标题】:Cleanest Jetty Configuration for Development?用于开发的最干净的 Jetty 配置?
【发布时间】:2023-04-08 01:46:01
【问题描述】:

编辑:我想我应该澄清我的意图......

我正在尝试简化编写代码>>构建WAR>>部署>>刷新>>重复的开发迭代周期。我希望相对独立于 IDE(即,我不希望 Eclipse 或 IntelliJ 插件完成这项工作)。我希望能够编辑代码/静态文件并根据需要构建到我的 WAR 源目录中,并且只需将运行/调试设置作为对集中式 Jetty 安装的命令行调用。

稍后我希望能够使用通常相同的设置但使用打包的 WAR 来执行实际部署。我不想让我的应用代码特定于我的 IDE 或 Jetty。

所以也许问这个问题的更好方法是您发现使用 Jetty 作为您的开发/调试应用服务器的最干净的方法是什么?


假设我想要一个最小的 Jetty 7 安装。我想要尽可能少的 XML 配置,我只需要原始 Servlet API、没有 JSP、没有过滤等。我只想能够拥有一些自定义 servlet 并提供静态文件(如果它们存在)。这将是唯一的 WAR,它将作为给定端口的根。

理想情况下,为了便于部署,我希望 Jetty 目录只是标准下载,并且我的 WAR / XML 配置与这些标准 Jetty 文件分开。在调用 Jetty 时,我想传入这个最小的 XML 并继续。

我发现文档到处都是,其中大部分是针对 Jetty 6 或特定于各种其他包(Spring 等)的。我想如果我有这个最小的配置,那么在上面添加额外的抽象会更干净。它还可以让我更干净地处理嵌入式 Jetty 场景。

这个 SO 问题是一个示例场景,这个 XML 会很有用 Jetty Run War Using only command line

指定这个 WAR 位置和为其提供服务的主机/端口所需的最小 XML 是多少?

提前感谢您提供任何 sn-ps 或链接。

【问题讨论】:

    标签: servlets jetty war embedded-jetty xml-configuration


    【解决方案1】:

    这并不能完全回答您的问题,但如果有帮助,这里有一些非常简单的代码,使用嵌入式 Jetty 7 来启动具有一个根 servlet 的服务器:

        HandlerCollection handlers = new HandlerCollection();
        ServletContextHandler root = new ServletContextHandler(handlers, "/", ServletContextHandler.NO_SESSIONS|ServletContextHandler.NO_SECURITY);
        root.addServlet(new ServletHolder(new MyServlet()), "/*");
    
        Server server = new Server(8080);
        server.setHandler(handlers);
        server.start();
    

    当然见http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty

    【讨论】:

    • 谢谢,我确实见过很多类似的 sn-ps,但我想知道如何使用 XML 配置进行类似的最小设置?
    【解决方案2】:

    Jetty 已迁移到 Eclipse。这方面有非常微妙的信息。这也导致了包名称的变化,这是另一个层次的细微差别。他们确实发布了一个工具来将 Jetty6 设置转换为 Jetty 7 设置,但同样 - 不是很受欢迎。我对 Eclipse Jetty 论坛感到失望。您应该在此处查找有关 Jetty 7 及更高版本的文档http://wiki.eclipse.org/Jetty/Starting

    我认为这是取自 http://wiki.eclipse.org/Jetty/Reference/jetty.xml 的最小 jetty.xml

    <?xml version="1.0"?>
    <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">\ 
    <Configure id="Server" class="org.eclipse.jetty.server.Server">
    </Configure>
    

    但是,我宁愿从$JETTY_HOME/etc/jetty.xml 的副本开始,然后从那里修改。

    如果你对$JETTY_HOME/webapps目录没问题,你可以通过修改这部分来设置端口

    <Configure id="Server" class="org.eclipse.jetty.server.Server">
        ...
        <Call name="addConnector">
          <Arg>
              <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <Set name="host"><Property name="jetty.host" /></Set>
                <Set name="port"><Property name="jetty.port" default="7777"/></Set>
                <Set name="maxIdleTime">300000</Set>
                <Set name="Acceptors">2</Set>
                <Set name="statsOn">false</Set>
                <Set name="confidentialPort">8443</Set>
            <Set name="lowResourcesConnections">20000</Set>
            <Set name="lowResourcesMaxIdleTime">5000</Set>
              </New>
          </Arg>
        </Call>
        ....
    </Configure>
    

    否则,我将修改context.xml这里解释的方式(对于Jetty 7)How to serve webbapp A from portA and webapp B from portB

    另请参阅这些页面:

    .... 编辑#1:对于每个连接器的 webapp 的 URL 错误感到抱歉。我已经更新了 如何从 portA 为 webbapp A 和从 portB 提供 webapp B 的链接,以指向适用于 Jetty 7 的文档。


    更新关于“您如何在各种环境中处理 Jetty?”

    开发

    我们使用 Maven,因此嵌入的 Jetty 适合我们。我们只是运行mvn clean install run:jetty,端口在Maven的配置文件中配置,即pom.xml。这依赖于 IDE,而且可以使用 ANT 轻松嵌入 Jetty,但我从未尝试过。

    测试

    我们有独立的 Jetty 运行。我已经配置了端口和调整参数,删除了默认应用程序(例如 root.war 等)并创建了一个带有应用程序特定端口和部署目录的 context.xml。 (不幸的是,我在 Eclipse Jetty 的邮件列表中问过这个问题,但没人愿意回答)。这是一次性设置。

    对于测试构建/部署,我们有一个构建脚本,它根据测试环境规范构建 WAR,然后将其上传到测试环境。之后,我们调用一个 shell 脚本,该脚本 (1) 停止 Jetty,(2) 将 war 文件复制到 myApp 的 webapp 目录并 (3) 重新启动 Jetty。

    不过,更简单的方法是使用 Maven 的 Cargo 插件。不幸的是,我使用的是与 Cargo 不兼容的 Jetty 7.1.6。后来他们修复了它,但我已经通过自定义脚本完成了我的工作。

    产品

    Prod 与 test 具有几乎相同的程序,除了。调整是为了更高的安全性和负载平衡。但是从部署 POV 来看,从 Test case 到 Prod 并没有什么不同。

    请注意,我并不关心 XML 文件是什么以及必须有多少。我刚刚使用了我关心的那些——jetty.xmlcontext.xml。另外,我发现使用jetty.confjetty.sh 来传递JVM 参数、自定义XML 以及启动和停止会更加简洁。

    希望这会有所帮助。


    热部署:

    现在,如果您使用 Maven 并使用嵌入式 Jetty。它只知道代码何时更改——比如“枪声嗅探器”。在 dev envt 中,您运行 Jetty、进行更改、刷新页面并查看您的更改 -- 热部署。在这里找到更多http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin 寻找scanIntervalSeconds

    【讨论】:

    • 谢谢。你知道我是否必须拥有所有不同的 XML 配置文件?或者我可以合并到我从命令行指定的单个 jetty.xml 中吗?
    • $JETTY_HOME/etc 下?您可以删除所有您不会使用的内容。它是各种设置的默认配置文件。非常细粒度。我不建议删除它们。理想情况下,您应该只编辑或复制相关的 XML 文件,然后将其传递给java -jar start.jar XMLFILENAME。您应该能够合并到一个文件中,这基本上意味着将所有文件名作为参数传递。不建议。另外,查看$JETTY_HOME/etc/jetty.conf 我建议使用$JETTY_HOME/bin/jetty.sh 来启动和停止。您不需要明确传递任何 XML 文件。
    • @Nishant 谢谢,听到各种环境的高级图片很有帮助。听起来 Maven 会简化某些方面。出于好奇,您的 DEV 环境是指向爆炸的 WAR 源还是必须使用完整的构建步骤进行部署?我也在尝试简化 UI 调整,只需要编辑 >> 保存 >> 刷新。
    • @McKAMEY 是的。 Jetty 可以进行热部署。如果有代码更改,则重新加载应用程序。默认扫描间隔为 10 秒,您可以配置它。更新了答案。
    • RE:“热部署” - 很好的答案!这不仅解决了我最初的问题,而且应该为我的其他 DEV/TEST/PROD 环境提供一个很好的起点。
    【解决方案3】:

    我想我会更新我现在所做的事情。我编写了一个小型命令行应用程序/Maven 原型,它的工作方式就像我认为这一切首先应该具有的那样。引导应用程序允许您通过将路径传递给 WAR 和您的端口来启动您选择的 servlet 容器(Jetty、Tomcat、GlassFish)。

    使用 Maven,您可以创建和打包您自己的这个简单应用的实例:

    mvn archetype:generate \
        -DarchetypeGroupId=org.duelengine \
        -DarchetypeArtifactId=war-bootstrap-archetype \
        -DarchetypeVersion=0.2.1
    

    然后你像这样启动它:

    java -jar bootstrap.jar -war myapp.war -p 8080 --jetty
    

    这里是实用程序和原型的来源:https://bitbucket.org/mckamey/war-bootstrap

    【讨论】:

    • 为了紧凑的开发周期,你不想开战。
    • 我在开发过程中实际上并没有使用战争。我将它指向目标输出目录,它工作正常。
    • McKamey,那么我上面的解决方案就是您要找的。只需将 gradle 指向您的构建目录(或者不要,它已经根据约定神奇地知道)和“jettyRun”......这就是您需要做的所有事情。
    • 我在 2 年前就已经解决了这个问题。不需要gradle。
    【解决方案4】:

    如果您使用 maven(独立于 IDE)构建,那么您应该使用 maven jetty 插件进行调试。基本上,您在命令行上将应用程序作为“mvn jetty:run”运行,这一切都可以正常工作,而无需进行任何重新部署。大多数优秀的 IDE 是如何内置 maven 支持并让您将应用程序作为 maven 运行/调试的;这意味着运行 maven 会启动启动应用程序的 jetty 插件,您可以对其进行调试。由于一切都用完了 IDE 源和 bin 文件夹,您甚至不需要安装码头服务器。

    这是一个以 https://github.com/simbo1905/ZkToDo2/blob/master/commandline.build.and.run.txt 方式运行的演示项目,这里是如何在 eclipse 下运行它 https://github.com/simbo1905/ZkToDo2/blob/master/eclipse.indigo.build.and.debug.txt 但任何理解 maven 的 IDE 都应该可以工作。查看 pom.xml,它在其中设置了 maven jetty 插件。

    【讨论】:

      【解决方案5】:

      我会使用 Gradle 并每隔几秒扫描一次构建输出文件夹以查找构建中的更改。

      在 build.gradle 文件中:

      apply plugin: 'jetty'
      
      ...
      
      jettyRun.doFirst {
          // set system properties, etc here for bootstrapping
      }
      
      jettyRun {
          httpPort = 8989
          reload = 'automatic'
          scanIntervalSeconds = 3
          daemon = false
      }
      

      就是这样。您可以选择让 IDE 为您自动构建,并指向该目录。但你也可以选择不这样做。此解决方案与 IDE 完全无关。

      【讨论】:

      • 需要注意的是这里不需要war/deploy。 Jetty 直接从构建输出目录加载类。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      相关资源
      最近更新 更多