Grails 应用程序启动速度太慢

Grails app is too slow to startup

我正在使用 grails 2.4.4 开发 Web 应用程序,而 Grails(使用 jetty 插件)大约需要 20 秒来初始化并使应用程序可用。

我可以接受这么长的时间,但旧硬件需要 3 分钟才能启动整个过程,我需要它更快,因为一旦服务器启动,性能就很好,而不是一个问题。

谷歌搜索发现在 SO 中 jar 扫描 servlet 注释可能是问题所在,并为 WEB-INF/lib 中的 类 禁用它并将其添加到应用上下文 xml:

<Call name="setAttribute">
    <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg>
    <Arg>nothing.jar$</Arg>
</Call>

这有助于将时间从 16 秒缩短到 13 秒。 还尝试使用配置的 servlet 2.5 而不是 3.0 进行构建(并移至码头 7)以尝试进一步改进这一点,因为注释扫描是 servlet 3.0 的一项功能,但速度提升很小(大约 1 秒)。

我的 objective 是将这个时间减少到 6 秒,因为在我测试过的最旧的硬件中它花了大约 3 分钟,所以它慢了大约 10 倍,1 分钟的启动时间在某种程度上是可以容忍的。

我对如何实现这一点有点迷茫。查看日志发现上下文初始化大约需要 2000 毫秒

2017-02-08 02:15:08,318 [main] INFO context.ContextLoader - Root WebApplicatio nContext: 初始化完成于 2001 ms

是否可以加快速度?

如果您使用的是 Jetty 9.x,那么知道 classpath/bytecode 扫描是必需的,因为它实现了 Servlet 3.1(需要它)。

使用 org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern 只会跳过 WEB-INF/lib 中的那些 jar,但您的容器类路径仍会被扫描(这意味着 您活动的 grails 环境中的所有内容)。

Note: you should never have a production server kicked from a build tool (maven, grails, etc) as that is a huge performance and security risk.

无法通过换出 servlet 支持 jar 来更改扫描行为(事实上,您不能将 Servlet 2.5 jar 与 Jetty 一起使用,它会彻底失败)。您实际使用 Servlet 2.5 jar 交换所做的是更改应用程序的支持级别,而不是 Jetty 中的行为。

但是并没有丢失所有内容,您可以 "precalculate" 扫描要求并使用 Jetty 9 的 quickstart features 通过提供所需的内容来启动您的应用程序,避免每次启动时重复扫描.

云提供商大量使用快速启动技术来近乎即时地启动 Web 应用程序(通常不到 500 毫秒)。

Note: if you are using hibernate, spring, cdi, or other libraries that have their own Annotations, then there is very often another bytecode scanning step performed by that library, not Jetty.