2009-06-13 4 views
5

En mi aplicación, tenemos un método de servicio web llamado getFoo() que devuelve un objeto Foo. El método getFoo() se llama varios cientos de veces por segundo. El objeto Foo se clasifica desde nuestro objeto Java a la respuesta XML SOAP utilizando Apache CXF.¿Cómo puedo almacenar en caché el XML SOAP estructurado generado por Apache CXF para un objeto Java en particular para mejorar el rendimiento?

Desde el perfil de nuestra aplicación, determinamos que la clasificación de este objeto (objeto java -> jabón codificado xml) es el mayor consumidor de ciclos de CPU. y dado que nuestro objeto Foo no cambia muy a menudo, volver a ordenar este objeto cada vez es innecesario.

Me di cuenta de que esto es una optimización común y me pregunté cómo otros lo abordaron. Miré brevemente los documentos CXF y hay un interceptor Marshall que probablemente podría utilizar. Podría crear un mapa que pueda asignar objetos Foo a la versión codificada en XML. Pero, entonces surgen algunos otros problemas, como cómo eliminar objetos de este mapa una vez que ya no son necesarios, etc. Sería bueno si hubiera soporte integrado para detectar de alguna manera los cambios en el objeto y reorganizarlos .. . Nada imposible, pero no quería reinventar la rueda.

EDITAR (6/16/09): Hemos progresado haciendo un BareOutInterceptor personalizado y modificando la cadena Interceptor para llamar a la personalizada. La costumbre agrega algo de lógica adicional para llamar solo al método "writeParts (....)" que realiza la clasificación solo de una vez para un objeto java dado. Publicará la solución una vez finalizado. Además, cambié el nombre de la pregunta.

+0

¿Hay algún experto de Apache CXF en SO que pueda decirnos cómo agregar un marcador de referencias personalizadas en la cadena del interceptor de salida? –

Respuesta

3

Ok, no es exactamente la respuesta que está buscando, pero de todos modos: el motivo por el que REST se usa en servicios web con alto tráfico (por ejemplo, Google) es que REST está diseñado para almacenarse en caché, mientras que SOAP simplemente NO está diseñado para ser cachable

SOAP se basa básicamente en (por definición HTTP) las solicitudes POST no almacenables en caché, y REST usa GET, que es fácil de almacenar en caché.

Debería inspeccionar la solicitud SOAP (POST) antes de que vaya al servicio web real, es decir, utilizando un proxy. Los proxies "estándar" generalmente desconocen la sintaxis de SOAP.

IBM's WebSphere Application Server though can do that

Saludos, Olaf

+0

@Olaf Cuando se llama al método del servicio web ... Todavía quiero aplicar alguna lógica comercial para determinar el contenido del objeto Foo. Por lo tanto, no es tan simple como para una devolución de un post dado y. Pero, por lo general, los contenidos son exactamente los mismos para el 99% de los usuarios que llaman al servicio. Entonces, me gustaría almacenar en caché el resultado ordenado de alguna manera para el objeto. Gracias por su publicación aunque el artículo fue interesante. – blak3r

+0

No sé si hay una implementación/ejemplo listo para usar para eso, pero podría usar una implementación de Patrón de Memoización (ligeramente modificada) para eso. http://en.wikipedia.org/wiki/Memoization –

0

No existe un requisito estricto en SOAP que es necesario utilizar un marco como CXF para manejar el servidor o cliente SOAP puntos finales. Acabamos de encontrar interbloqueos de subprocesos de cliente cuando usamos un cliente SOAP basado en Axis 1.4 para hablar con un servidor basado en Axis 1.1, y los solucionamos abandonando Axis y realizando las solicitudes en código escrito a mano. Tuvimos que mentirle al servidor de Axis diciéndole que todavía teníamos un cliente de Axis, ¡pero no sentimos ningún remordimiento! ;-)

De manera similar, debería poder evitar CXF y generar respuestas SOAP en su propio código java escrito a mano. Luego puede usar un Mapa para almacenar en caché sus cadenas XML ordenadas (sin analizar, serializadas) y eliminar este punto de acceso.

Totalmente de acuerdo con Olaf en REST: si aprovecha al máximo HTTP, entonces todo este almacenamiento en caché se realiza de forma gratuita en todos los cachés intermedios entre su servidor y sus clientes. Eso es ciertamente algo a considerar para nuevos servicios.

Actualización: CXF tiene la noción de personalizable interceptor chains. Un tipo de interceptor de salida es para la fase MARSHAL, por lo que parece que podría agregar esta memoria caché allí sin tener que deshacerse de CXF.¿Tal vez un experto en CXF puede verificar eso para nosotros?

+0

@Jim Ferrans - Tenemos varios métodos y objetos complejos que harían que mantener el código escrito a mano sea inviable. Esperaba encontrar un ejemplo de cómo usar cadenas de interceptor para almacenar en caché el componente de cuerpo de método del mensaje de jabón. No he encontrado ningún buen ejemplo en los documentos de Apache. – blak3r

0

El objeto Foo se clasifica desde nuestro objeto Java a la respuesta XML SOAP utilizando Apache CXF.
.. el mayor consumidor individual de ciclos de CPU. y dado que nuestro objeto Foo no cambia muy a menudo, volver a utilizar este objeto cada vez es innecesario.

¿La aplicación del cliente necesita saber los cambios en Foo al instante o tan pronto como sea posible?

¿Por qué no almacenarlo en el lado del consumidor/cliente? Un diseño en el que llame al mismo método de servicio web cientos de veces por segundo probablemente no sea el mejor.

+0

Tenemos miles de clientes únicos que llaman al método getFoo aproximadamente una vez cada 20 s. Por lo tanto, no podemos almacenar en caché en el lado del cliente. – blak3r

Cuestiones relacionadas