2012-04-07 12 views
7

Normalmente ejecuto aplicaciones de tiempo completo en mi aplicación sandbox. Sin embargo, tengo una operación complicada (básicamente la reconstrucción de la base de datos) que hace que los appstats exploten mi instancia, lanzando OutOfMemoryErrors. Incluso con tamaños de instancia más grandes, todavía falla. Appstats solo quiere demasiada RAM.¿Cómo puedo suspender los appstats para una sola solicitud en App Engine/Java?

No necesito appstats en esta solicitud. Idealmente, llamaré a un método sobre cualquier objeto ThreadLocal que sea responsable de la recopilación de appstats y le diré que mueva sus pulgares durante unos minutos.

He considerado extender el AppstatsFilter para ignorar ciertas URL, pero la solicitud ofensiva se ejecuta como una tarea diferida e identificarla por ruta es algo complicado.

¿Cómo puedo decirle a los usuarios de la aplicación que pause?

Por si acaso no está claro: Cargar una versión de mi aplicación con appstats deshabilitado, ejecutar mi tarea, y luego cargar una versión con appstats habilitados es lo que estoy haciendo ahora. No quiero hacer esto

+0

Supongo que solo está optando por las direcciones URL que desea monitorizar, ¿no es una opción? FWIW. He deseado poder hacer lo que estás pidiendo más de una vez, pero mordí la viñeta y acabo de hacer una lista de las URL que necesitábamos para monitorear y ponerlas en la configuración. –

+0

Desafortunadamente, la URL que deseo excluir es/_ah/queue/__ deferred__. Probablemente podría montar el DeferredTaskServlet en una URL adicional y enrutar esta solicitud específica, pero esto parece ir muy lejos de la reserva. – stickfigure

+0

¿Alguna vez resolvió esto? – Keith

Respuesta

1

Buena pregunta. Para Python, la respuesta es simple:

from google.appengine.ext.appstats import recording 

class ...(webapp.RequestHandler): 
    def get(self): 
    recording.dont_record() 
    ... 

¿Tal vez hay una API similar en Java?

Alternativamente, una vez más, la versión de Python tiene una forma flexible de filtrar las solicitudes de grabación; Creo que en la versión de Java puedes lograr algo similar al usar las entradas y en tu web.xml. (Ver la Java AppStats docs.)

+0

No puedo encontrar un equivalente de Java en el código fuente del SDK, y desafortunadamente la URL relevante es la URL de la tarea estándar __deferred__. ¡Sin embargo, un método como este es exactamente lo que estoy buscando! – stickfigure

1

Jeff, me pregunto si esto puede ayudar a reducir la aparición de OutOfMemoryErrors: How to reduce the memory usage of Appstats on Google App Engine Java

<filter> 
    <filter-name>appstats</filter-name> 
    <filter-class>com.google.appengine.tools.appstats.AppstatsFilter</filter-class> 
    <init-param> 
     <param-name>maxLinesOfStackTrace</param-name> 
     <param-value>16</param-value> 
    </init-param> 
</filter> 
+1

No es una solución ideal, pero ciertamente útil, ¡gracias! – stickfigure

2

Lo que hice es escribir mi propia CustomAppstatsFilter y excluye cierta URL de.

public class CustomAppstatsFilter extends AppstatsFilter { 

    @Override 
    public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 

    if (request instanceof HttpServletRequest) { 
     String url = ((HttpServletRequest) request).getRequestURL().toString(); 

     // We do not want these to show up in appstats 
     if ((url.contains("appstats")) 
       || url.contains("_ah/") 
       || url.contains("cron/") 
       || url.contains("batch/")) { 
      chain.doFilter(request, response); 
      return; 
     } else { 
      super.doFilter(request, response, chain); 
     } 
    } 
    } 
} 

EDITAR - Esto se puede combinar con ZiglioNZ gran respuesta.

<!-- Appstats filter for profiling application --> 
<filter> 
    <filter-name>appstats</filter-name> 
    <filter-class>my.company.filter.CustomAppstatsFilter</filter-class> 
    <init-param> 
     <param-name>maxLinesOfStackTrace</param-name> 
     <param-value>5</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <!-- excludes are in CustomAppstatsFilter --> 
    <filter-name>appstats</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 
+0

Esto casi soluciona el problema, pero la URL es la URL de ejecución de la tarea diferida, que se aplica a todas las tareas diferidas. Lo que necesito es algo equivalente a dont_record() de Python que puedo ejecutar en mi código. – stickfigure

+0

Como [este artículo] (https://developers.google.com/appengine/articles/deferred) explica, si necesita un control completo sobre cómo se ponen en cola y se ejecutan las tareas, debe usar la API Task Queue. ;-) – lucdc

+0

No necesito ni deseo un control completo sobre cómo se ponen en cola y se ejecutan las tareas; eso es aplastar a las moscas con mazos. Solo quiero que los appstats fallen más graciosamente. Python tiene una API para ello, pero aparentemente Java no :( – stickfigure

Cuestiones relacionadas