Google App Engine for Java的Performance性能问题

Google App Engine - Google Code,会根据负载情况自动关闭或者启动Java web应用的JVM,这使得很多http请求会触发启动JVM并部署web应用,因此这样的http请求非常慢,响应性能很差,用户体验非常差。因为大部分的应用还是需要连接DataStore,那么就需要初始化Data类的MetaData和连接数据库,不可避免需要很多时间。这个问题甚至Google自己也没有很好的办法。

What is a loading request?

Some requests run slower because App Engine needs to create a new Java virtual machine to service the request. We call that kind of request, a Loading Request. During a loading request, your application undergoes initialization (such as class loading, JIT compiling, etc) which causes the request to take longer.

 

For slow requests which are already close to App Engine's request deadline, the extra initialization can push it past the deadline, causing a DeadlineExceededException.

 

What causes loading requests?

App Engine spins up JVMs on demand, so there are several reasons why you may receive a loading request:

  1. You just uploaded a new version of your application.
  2. Your application may not be getting any traffic.
  3. Your traffic has become high enough to need another JVM to scale.

You can expect that during the course of developing your application, you will often experience the first two scenarios. In comparison, for a production app receiving even a very small but steady amount of traffic, loading requests are relatively infrequent.

How do I distinguish normal requests from loading requests in my application logs?

You can register an HttpSessionListener in your web.xml which logs from its sessionCreated method. For example:

// web.xml snippet
<listener>
 
<listener-class>
  com
.example.LogLoadingRequest
 
</listener-class>
</
listener>

// LogLoadingRequest.java
public class LogLoadingRequest implements ServletContextListener {
 
private static final Logger logger = Logger.getLogger(LogLoadingRequest.class.getName());
 
public void contextInitialized(ServletContextEvent sce) {
    logger
.log(Level.INFO, "Loading request occuring.");
 
}

 
public void contextDestroyed(ServletContextEvent sce) {
 
}
}

In the future, the Admin Console logs viewer will mark loading requests specifically so that they can be easily identified.

Do I need to be concerned about high CPU warnings in the admin console for my loading requests?

App Engine provides high CPU warnings to help you determine which requests might need optimization. In the case of loading requests, though, the execution time is artificially longer due to the extra application initialization required. In addition, the number of loading requests is inversely proportional to the amount of traffic your application receives. So, while your CPU usage due to additional traffic will increase, your CPU usage due to loading requests will decrease.

Given that, your time is most often better spent focusing on optimizing other high CPU warnings in relation to your application's total CPU usage.

How can I speed up loading requests?

Here are a few suggestions:

  1. Perform application initialization lazily, rather than eagerly, so it doesn't all occur within a single request.
  2. Share expensive initialization between JVMs. For example, put data which is expensive to read or compute into memcache, where it can be quickly read by other JVMs during startup.
  3. Move initialization from application startup to build-time where reasonable. For example, convert a complex datafile into a simple, quick-to-read datafile in your build process.
  4. Use slimmer dependencies. For example, prefer a library that is optimized to your task, as opposed to a large library that performs very heavy initialization.

What is Google doing to speed up loading requests?

  1. With the release of 1.2.8, we've introduced a new class-loading optimization called precompilation. We've seen improvements to loading requests of 30% and greater. For now, you'll need to opt into precompilation in order to take advantage of it. You can do this by including the following code in your appengine-web.xml file:
    <precompilation-enabled>true</precompilation-enabled>
    In the future, we plan to turn this optimization on for all applications.
  2. We're also making runtime optimizations guided by profiling applications with longer loading requests. In addition, we've provided profiling feedback to third-party language runtimes such as Groovy and JRuby and suggestions for optimization of their own libraries and runtimes.
  3. We're actively working on further startup optimizations.

Can I pay to keep a JVM reserved for my application?

We've seen this request from some developers with low-traffic applications who'd like to reduce the percentage of loading requests they receive. Although we have many improvements in the pipeline to improve loading request performance, we'd like to gauge the general interest in this feature. If you'd like to be able to reserve a JVM at a price, please star this issue. If there's a particular pricing scheme you're interested in, let us know.

Should I run a cron job to keep my JVMs alive and reduce my loading requests?

We discourage developers from doing this because it increases the average number of loading requests for all low-traffic applications. Instead, we will continue to improve the performance of loading requests for everyone, and you can use the advice on this page to optimize your application's startup performance.

你可能感兴趣的:(java,Google,GAE)