配置 Eclipse 将 App Engine 类预先捆绑到单个 JAR 中以加快预热速度

发布于 2025-01-08 01:14:15 字数 477 浏览 1 评论 0原文

在与另一家同样使用 App Engine 的公司的同事进行讨论后,他告诉我,他通过以下步骤成功地将应用程序预热时间从约 15 秒缩短到约 5 秒:

  1. 配置 Eclipse 将编译过程中生成的类捆绑到单个 JAR 文件中。
  2. 将 Eclipse 配置为在 App Engine 部署期间上传这个单个 JAR 文件,而不是上传数百(或数千)个单独的 Java 类。

他认为,在实例预热期间,由于实例只需要加载单个捆绑的 JAR 文件,而不是数千个单独的类,因此预热速度会明显加快。对此有什么想法或意见吗?

我肯定想自己尝试一下,但我没有足够的 Eclipse-mojo 来知道如何配置这些步骤。有谁知道如何配置 Eclipse 或 Google Plugin for Eclipse 来执行上述步骤? (当然,部署的应用程序在 App Engine 中成功运行)

谢谢,

After some discussion with a colleague from another company that also uses App Engine, he told me that he managed to cut down his app warm up time from ~15 seconds to ~5 seconds using the following steps:

  1. Configure Eclipse to bundle classes produced during compilation into a single JAR file.
  2. Configure Eclipse to upload this single JAR file instead of hundreds (or thousands) of separate Java classes during App Engine deployment.

He argues that during instance warm up, since the instance need to load only a single bundled JAR file instead of thousands of separate classes, the warm up would be significantly faster. Any thoughts or opinions about this?

I would definitely like to try it by myself, but I don't have enough Eclipse-mojo to know how to configure such steps. Does anyone know how to configure Eclipse or the Google Plugin for Eclipse to do the steps outlined above? (And have the deployed apps successfully runs in App Engine, of course)

Thank You,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

茶花眉 2025-01-15 01:14:15

我们在 Eclipse 中所做的是:

  • 在 Project Properties > 中Java 构建路径(“源”选项卡)将输出文件夹从 war/WEB-INF/classes 更改为其他内容,例如 bin (我相信 Eclipse 曾经抱怨过这一点
  • )构建器添加一个新的构建器(我使用类型“program builder”并将其指向我的 JDK 中的 jar 可执行文件,但正如其他人提到的,Ant 构建器也可以工作)。显然,您应该配置此构建器以从您决定将类文件写入的任何位置获取输入,并输出到类似 war/WEB-INF/lib/myclasses.jar 之类的内容。

您可以将 jar 构建器配置为在类文件更改时自动执行(随着源文件的更改,通常会自动重新编译)。

但也有一些缺点。由于某种原因,google eclipse 插件会因为更改 java 编译器的输出目录而感到困惑。这意味着您在部署时必须手动指向 war 目录,并且我相信您必须手动将一些 GAE jar 复制到 war/WEB-INF/lib 文件夹中。

What we did in Eclipse was:

  • In Project Properties > Java Build Path (Source tab) change output folder from war/WEB-INF/classes to something else, e.g. bin (I believe Eclipse complained about this once)
  • In Project Properties > Builders add a new builder (I used type "program builder" and pointed it to the jar executable in my JDK, but as others mentioned an Ant builder would work too). Obviously you should configure this builder to take its input from wherever you decided to write your class files to, and output to something like war/WEB-INF/lib/myclasses.jar

You can configure the jar builder to execute automatically as class files change (which in turn are usually automatically recompiled as your source files change).

There are some downsides, though. For some reason the google eclipse plugin gets confused by your changing the output directory of the java compiler. This means you will have to manually point to the war directory when deploying, and I believe you'll have to manually copy some GAE jars into the war/WEB-INF/lib folder.

娇纵 2025-01-15 01:14:15

我不知道如何(或是否)将其集成到 Eclipse 中,但使用 ant 来说这是相当微不足道的:

<import file="${appengine.sdk.dir}/config/user/ant-macros.xml" />

<target name="deploy">
    <delete dir="${staging.dir}" />
    <mkdir dir="${staging.dir}" />

    <copy todir="${staging.dir}">
        <fileset dir="war">
            <exclude name="WEB-INF/classes/**" />
            <exclude name="WEB-INF/appengine-generated/**" />
        </fileset>
    </copy>
    <jar destfile="${staging.dir}/WEB-INF/lib/classes.jar" basedir="${classes.dir}" />

    <appcfg action="update" war="${staging.dir}" />
</target>

我要补充的是,我没有体验到应用程序启动时间减少了 3 倍。我在此帖子中发布了一些实验数字:

https://groups.google。 com/d/msg/google-appengine/dStBW4wIemY/K69f9ufDiN0J

我发现,与20-45 秒,它使我的应用程序在 20 秒内持续加载。后来它并没有保持如此一致,但我现在仍然将我的类作为部署的标准部分。

I don't know how (or if) you can integrate it into eclipse, but it's fairly trivial to do with ant:

<import file="${appengine.sdk.dir}/config/user/ant-macros.xml" />

<target name="deploy">
    <delete dir="${staging.dir}" />
    <mkdir dir="${staging.dir}" />

    <copy todir="${staging.dir}">
        <fileset dir="war">
            <exclude name="WEB-INF/classes/**" />
            <exclude name="WEB-INF/appengine-generated/**" />
        </fileset>
    </copy>
    <jar destfile="${staging.dir}/WEB-INF/lib/classes.jar" basedir="${classes.dir}" />

    <appcfg action="update" war="${staging.dir}" />
</target>

I will add that I did not experience a 3X reduction in app startup time. I posted some experimental numbers in this thread:

https://groups.google.com/d/msg/google-appengine/dStBW4wIemY/K69f9ufDiN0J

What I found is that instead of varying wildly from 20-45s, it made my app consistently load in 20s. It has not subsequently remained this consistent, but I still jar my classes as a standard part of deployment now.

哑剧 2025-01-15 01:14:15

实现此目的的一种方法是通过 Ant 进行部署,如下所述:https ://developers.google.com/appengine/docs/java/tools/ant

接下来,您可以修改 ant build.xml 文件以调用 ant 命令来构建 jar 文件。在实际部署之前,您可以删除或移走已编译的工件。构建 jar 文件应放置在 WAR/WEB-INF/lib 文件夹中。

这个解决方案的缺点是你必须通过build.xml、iso通过appengine eclipse插件进行部署。

One way this can be achieved if by doing the deployment through Ant, as described in: https://developers.google.com/appengine/docs/java/tools/ant

Next you can modify the ant build.xml file to call the ant command for building the jar file. Just before the actual deployment you can either delete or move the compiled artifacts away. The build jar-file should be placed in the WAR/WEB-INF/lib folder.

Drawback of this solution is that you have to deploy through the build.xml, i.s.o. through the appengine eclipse plugin.

小嗷兮 2025-01-15 01:14:15

正如之前的回答中所述,App Engine SDK 支持将 WEB-INF/classes 打包到一个 jar 文件,最终位于 WEB-INF/lib/_ah_webinf_classes-0000.jar 中。 激活此功能

  1. 您可以

    使用 appcfg 工具和选项 --enable_jar_classes

  2. 通过配置 WAR 或 EAR 项目的属性来使用 Google Plugin for Eclipse:项目属性 >谷歌应用引擎>部署> “将 WEB-INF/classes 打包为 jar”

对于我来说,在 App Engine 1.9.4 上,这仅对实例启动产生了微小的改进(大约 5-10%,如果有的话)。


请注意,这会将 WEB-INF/classes 中的所有文件打包(不仅仅是 .class 文件)。更改后,我在实例化过程中收到一条错误消息,无法再读取logging.properties文件;可能是因为当时尚未读取新的 jar 文件:

无法读取 java.util.logging 配置文件,WEB-INF/classes/logging.properties

作为解决方法,我更改了appengine-web.xml 中的路径到 WEB-INF/logging.properties 并配置 maven-war-plugin 将文件复制到该位置:

                <webResources>
                    <resource>
                        <directory>lib</directory>
                        <targetPath>WEB-INF/lib</targetPath>
                    </resource>
                    <resource>
                        <!-- Workaround: During GAE deployment, all files in WEB-INF/classes will be packaged into WEB-INF/lib/_ah_webinf_classes-0000.jar, 
                            which prevents the logging.properties referenced in appengine-web.xml from being read. -->
                        <directory>src/main/resources</directory>
                        <includes>
                            <include>logging.properties</include>
                        </includes>
                        <targetPath>WEB-INF</targetPath>
                    </resource>
                </webResources>

As stated in an earlier answer, the App Engine SDK supports packaging WEB-INF/classes into a jar file, which will end up in WEB-INF/lib/_ah_webinf_classes-0000.jar. You can activate this

  1. using the appcfg tool with the option --enable_jar_classes.

  2. using the Google Plugin for Eclipse by configuring the properties of either your WAR or EAR project: Project properties > Google App Engine > Deployment > "Package WEB-INF/classes as a jar"

For me, on App Engine 1.9.4, this resulted in only a minor improvement in instance spin-up (about 5-10 %, if any).


Note that this will package all files in WEB-INF/classes (not only .class ones). Following the change, I got an error message during instantiation about not being able to read the logging.properties file anymore; probably because the new jar file hasn't been read at that time:

Unable to read the java.util.logging configuration file, WEB-INF/classes/logging.properties

As a workaround, I changed the path in appengine-web.xml to WEB-INF/logging.properties and configured the maven-war-plugin to copy the file to that location:

                <webResources>
                    <resource>
                        <directory>lib</directory>
                        <targetPath>WEB-INF/lib</targetPath>
                    </resource>
                    <resource>
                        <!-- Workaround: During GAE deployment, all files in WEB-INF/classes will be packaged into WEB-INF/lib/_ah_webinf_classes-0000.jar, 
                            which prevents the logging.properties referenced in appengine-web.xml from being read. -->
                        <directory>src/main/resources</directory>
                        <includes>
                            <include>logging.properties</include>
                        </includes>
                        <targetPath>WEB-INF</targetPath>
                    </resource>
                </webResources>
柒七 2025-01-15 01:14:15

请注意,从版本 1.7.4 开始:

您现在可以将所有 WEB-INF/classes/* 类打包到 jar 文件中。这可以通过新的

中的

--enable_jar_classes 选项appcfg 工具。默认情况下,未设置此选项。

http://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes

Note that as of version 1.7.4:

You can now package all the WEB-INF/classes/* classes into jar files. This can be done via the new

--enable_jar_classes option in the appcfg tools. By default, this option is not set.

http://code.google.com/p/googleappengine/wiki/SdkForJavaReleaseNotes

梦在夏天 2025-01-15 01:14:15

我认为最简单的方法是创建一个单独的项目,在其中编写所有代码并存储任何其他依赖项。当您准备好部署时,Eclipse 导出到可运行的 JAR 文件可以将所有依赖项和您的类重新打包到一个 JAR 文件中,然后您可以将其用作可部署的 Google App Engine 项目中的一个依赖项,该项目基本上包含任何WEB-INF 文件夹中的配置文件以及其他静态资源 + 一个大 JAR 文件。

除了 eclipse 导出之外,您还可以将其设置为 Maven 或 Ant 构建,它们也可以进行重新打包。

I think the easiest way to do this would be to have a separate project that you write all the code in as well as store any other dependencies. When you're ready to deploy, Eclipse's export to runnable JAR file can repack all the dependencies and your classes into a single JAR file, which you would then use as your one dependency in your deployable Google App Engine project which would basically consist of any config files in the WEB-INF folder as well as other static resources + the one big JAR file.

Alternatively to the eclipse export, you can set that up as a Maven or Ant build which can also do the repacking.

岁月苍老的讽刺 2025-01-15 01:14:15

他认为在实例预热期间,由于实例只需要加载
单个捆绑的 WAR 文件而不是数千个单独的类,热身
会明显更快。对此有什么想法或意见吗?

我对此表示怀疑。 WAR 只是一个 ZIP 文件,在部署到服务器上时会被解压。因此,还有一个额外的步骤,这意味着该过程可以同样快(如果在上传时解压)或较慢(如果在实例启动时解压)。

He argues that during instance warm up, since the instance need to load only a
single bundled WAR file instead of thousands of separate classes, the warm up
would be significantly faster. Any thoughts or opinions about this?

I doubt it. WAR is just a ZIP file, which gets unpacked when it's deployed on the server. So there is an additional step, meaning the process can be equally fast (if unpacked when uploaded) or slower (if unpacked when instance is spun up).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文