Bonnes pratiques des applications java prêtes pour la production

36
Bonnes Pratiques Des Applications Java Prêtes pour la Production Bonnes Pratiques des Applications Java Prêtes pour la Production Cyrille Le Clerc Sunday, June 13, 2010

description

Les bonnes pratiques des applications Java prêtes pour la production. Les enjeux : * Améliorer la disponibilité des applications * Réduire le cycle de vie des projets * Améliorer les plateformes * Diminuer le coût d’exploitation Les axes clefs : * Le déploiement * La supervision et le monitoring * La gestion des logs * La robustesse * L’organisation

Transcript of Bonnes pratiques des applications java prêtes pour la production

Page 1: Bonnes pratiques des applications java prêtes pour la production

Bonnes Pratiques Des

Applications JavaPrêtes pour la Production

Bonnes Pratiques des Applications Java

Prêtes pour la Production

Cyrille Le Clerc

Sunday, June 13, 2010

Page 2: Bonnes pratiques des applications java prêtes pour la production

Cyrille Le Clerc

Architecte Java EE depuis 11 ans

Committer Apache CXF

Directeur associé chez Xebia

[email protected]

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 3: Bonnes pratiques des applications java prêtes pour la production

Les enjeux

Améliorer la disponibilité des applications

Réduire le cycle de vie des projets

Améliorer les plateformes

Diminuer le coût d’exploitation

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 4: Bonnes pratiques des applications java prêtes pour la production

Les axes clefs

Le déploiement

La supervision et le monitoring

La gestion des logs

La robustesse

L’organisation

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 5: Bonnes pratiques des applications java prêtes pour la production

Le Déploiement

Minimiser le nombre de composants à déployer

Colocation friendly

Les paramètres de configuration

La traçabilité

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 6: Bonnes pratiques des applications java prêtes pour la production

Le Déploiement

Minimiser le nombre de composants à déployer

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 7: Bonnes pratiques des applications java prêtes pour la production

Minimiser le nombre de composants à déployer

www.xebia.fr / blog.xebia.fr 5

html

css

img

js

jsp

WEB-INF

*.html*.html

lib

classes

web.xml

*.jsp*.jsp

my-app

Sunday, June 13, 2010

Page 8: Bonnes pratiques des applications java prêtes pour la production

Minimiser le nombre de composants à déployer

www.xebia.fr / blog.xebia.fr 5

# don't proxy static content !

ProxyPassMatch ^(/my/.*\.html)$ !

ProxyPassMatch ^(/my/.*\.css)$ !

ProxyPassMatch ^(/my/.*\.gif)$ !

ProxyPassMatch ^(/my/.*\.jpeg)$ !

ProxyPassMatch ^(/my/.*\.png)$ !

ProxyPassMatch ^(/my/.*\.js)$ !

# proxy dynamic content

ProxyPass /my/ http://my:8080/my/

httpd.conf3

html

css

img

js

jsp

WEB-INF

*.html

lib

classes

web.xml

*.jsp*.jsp

my-app

Apache Httpd Tomcat

my-app.warmy-app static files

just in case

12

Sunday, June 13, 2010

Page 9: Bonnes pratiques des applications java prêtes pour la production

Minimiser le nombre de composants à déployer

www.xebia.fr / blog.xebia.fr 5

# proxy /my/

ProxyPass /my/ http://my:8080/my/

httpd.conf2

Cache Proxy

html

css

img

js

jsp

WEB-INF

*.html

lib

classes

web.xml

*.jsp*.jsp

my-app

Apache Httpd Tomcat

my-app.warmy-app static files

1

Sunday, June 13, 2010

Page 10: Bonnes pratiques des applications java prêtes pour la production

Colocation friendly

Colocalisation de serveur (Linux, Windows, etc)▶ Minimiser les répertoires absolus et les ports réseaux▶ Ports dédiés par application (e.g. http : 10080)

▶ Chemins dédiés de répertoires (e.g. /etc/my-app-1/...)

Colocalisation de serveur Java EE▶ Ne pas utiliser de variable statique▶ Chemins dédiés de répertoires (e.g. ${java.io.tmpdir}/my-app-1/...)

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 11: Bonnes pratiques des applications java prêtes pour la production

Le Déploiement

Les paramètres de configuration

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 12: Bonnes pratiques des applications java prêtes pour la production

Les paramètres de configuration

Limiter les paramètres de configuration dont la valeur change suivant les environnements▶ Ports réseau standards (e.g. 80, 1521)▶ Noms logiques de host/serveurs (e.g. my-app-srv-1)

www.xebia.fr / blog.xebia.fr 2

Production

...

Firewall

Internet

10080app-1

20080app-2

80

443/app1

/app2my-com

pany.com

db-α1521

db-β1521

srv-i, srv-j, srv-k

srv-l, srv-m, srv-n

Sunday, June 13, 2010

Page 13: Bonnes pratiques des applications java prêtes pour la production

Les paramètres de configuration

www.xebia.fr / blog.xebia.fr 5

Production

...

Firewall

Internet

10080app-1

20080app-2

80

443

/app1

/app2my-com

pany.com

db-α1521

db-β1521

Validation

...

Firewall

10080app-1

20080app-2

80

443

/app1

/app2my-com

pany.com

db-α1521

db-β1521

proxy

srv-i, srv-j, srv-k

srv-l, srv-m, srv-n

srv-i, srv-j, srv-k

srv-l, srv-m, srv-n

NO communication

Same hostnames

Same network ports

Can be same IP !

Sunday, June 13, 2010

Page 14: Bonnes pratiques des applications java prêtes pour la production

Le Déploiement

La traçabilité

www.xebia.fr / blog.xebia.fr 2

Data centersDev zone

my-app/tags/1.2.3/

Repository

my-app-1.2.3.war

Comment déployer ?

artefact taggé

Sunday, June 13, 2010

Page 15: Bonnes pratiques des applications java prêtes pour la production

Supervision et Monitoring

Exposer des indicateurs métier

Logs vs. JSP vs. JMX

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 16: Bonnes pratiques des applications java prêtes pour la production

Supervision et Monitoring

Exposer des indicateurs métier

Suivre les succès et échecs vécus par les utilisateurs

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 17: Bonnes pratiques des applications java prêtes pour la production

Supervision et Monitoring

Logs de monitoring

Détail par invocation vs. moyenne par minute

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 18: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JSP Attention à la sécurité ! Human Friendly and/or Script Friendly

www.xebia.fr / blog.xebia.fr 2

/my-app/seye5E7E/jmx/cxf.jsp

Sunday, June 13, 2010

Page 19: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JMX Sécurité ++ Simple Human Friendly and/or Script Friendly

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 20: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JMX : Simple

www.xebia.fr / blog.xebia.fr 2

@ManagedResourcepublic class DemoServiceImpl { private final AtomicInteger invocationCount = new AtomicInteger(); @ManagedAttribute public int getInvocationsCount() { return invocationCount.get(); } @ManagedOperation public void purge(){ // ... }

Sunday, June 13, 2010

Page 21: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JMX : VisualVM

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 22: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JMX : Hyperic HQ & cie

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 23: Bonnes pratiques des applications java prêtes pour la production

Monitoring : logs vs. jsp vs. jmx

JMX & JSP

www.xebia.fr / blog.xebia.fr 2

Powered by JMX !

Sunday, June 13, 2010

Page 24: Bonnes pratiques des applications java prêtes pour la production

La gestion des logs

Exceptions java & stack trace vs. code erreur

Troubleshooting vs. logs longue durée &audit

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 25: Bonnes pratiques des applications java prêtes pour la production

La gestion des logs

www.xebia.fr / blog.xebia.fr 2

2010/04/12 14:37:19 [catalina-exec-14] WARN o.a.cxf.phase.PhaseInterceptorChain - Application {http://ws.xebia.fr/customer/v1_0}customerService#{http://ws.xebia.fr/customer/v1_0}getCustomer has thrown exception, unwinding noworg.apache.cxf.interceptor.Fault: Exception getting customer '71' at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:155) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.jaxws.AbstractJAXWSMethodInvoker.createFault(AbstractJAXWSMethodInvoker.java:86) ~[cxf-rt-frontend-jaxws-2.2.7.jar:2.2.7] at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:121) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.jaxws.JAXWSMethodInvoker.invoke(JAXWSMethodInvoker.java:60) ~[cxf-rt-frontend-jaxws-2.2.7.jar:2.2.7] at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:75) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58) ~[cxf-rt-core-2.2.7.jar:2.2.7] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441) ~[na:1.6.0_17] at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303) ~[na:1.6.0_17] at java.util.concurrent.FutureTask.run(FutureTask.java:138) ~[na:1.6.0_17] at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:106) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:243) ~[cxf-api-2.2.7.jar:2.2.7] at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:110) [cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.ServletDestination.invoke(ServletDestination.java:98) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:423) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:178) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.AbstractCXFServlet.invoke(AbstractCXFServlet.java:142) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:179) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:103) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at javax.servlet.http.HttpServlet.service(HttpServlet.java:637) [servlet-api.jar:na] at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:159) [cxf-rt-transports-http-2.2.7.jar:2.2.7] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) [catalina.jar:6.0.26] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:6.0.26] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:343) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:97) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:100) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:78) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:54) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:35) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:177) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter.doFilter(DefaultLoginPageGeneratingFilter.java:90) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:188) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:105) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:79) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:355) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:149) [spring-security-web-3.0.2.RELEASE.jar:na] at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237) [spring-web-3.0.2.RELEASE.jar:3.0.2.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167) [spring-web-3.0.2.RELEASE.jar:3.0.2.RELEASE] at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) [catalina.jar:6.0.26] at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) [catalina.jar:6.0.26] at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) [catalina.jar:6.0.26] at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) [catalina.jar:6.0.26] at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) [catalina.jar:6.0.26] at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [catalina.jar:6.0.26] at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:555) [catalina.jar:6.0.26] at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [catalina.jar:6.0.26] at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298) [catalina.jar:6.0.26] at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) [tomcat-coyote.jar:6.0.26] at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) [tomcat-coyote.jar:6.0.26] at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:396) [tomcat-coyote.jar:6.0.26] at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [na:1.6.0_17] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [na:1.6.0_17] at java.lang.Thread.run(Thread.java:637) [na:1.6.0_17]Caused by: java.lang.RuntimeException: Exception getting customer '71' at fr.xebia.ws.customer.v1_0.CustomerServiceImpl.getCustomer(CustomerServiceImpl.java:101) ~[CustomerServiceImpl.class:na] at fr.xebia.ws.customer.v1_0.CustomerServiceImpl$$FastClassByCGLIB$$30f63c56.invoke(<generated>) ~[cglib-nodep-2.2.jar:na] at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) ~[cglib-nodep-2.2.jar:na] at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:692) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at fr.xebia.audit.AuditAspect.logMessage(AuditAspect.java:139) ~[AuditAspect.class:na] at sun.reflect.GeneratedMethodAccessor62.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_17] at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_17] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:622) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:611) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:161) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:625) ~[spring-aop-3.0.1.RELEASE.jar:3.0.1.RELEASE] at fr.xebia.ws.customer.v1_0.CustomerServiceImpl$$EnhancerByCGLIB$$184a797f.getCustomer(<generated>) ~[cglib-nodep-2.2.jar:na] at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[na:1.6.0_17] at java.lang.reflect.Method.invoke(Method.java:597) ~[na:1.6.0_17] at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173) ~[cxf-rt-core-2.2.7.jar:2.2.7] at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89) ~[cxf-rt-core-2.2.7.jar:2.2.7] ... 62 common frames omittedCaused by: java.lang.RuntimeException: Too many concurrent access to ZeSlowService at fr.xebia.productionready.backend.zeslowservice.ZeSlowServiceBoundedImpl.find(ZeSlowServiceBoundedImpl.java:57) ~[ZeSlowServiceBoundedImpl.class:na] at fr.xebia.ws.customer.v1_0.CustomerServiceImpl.updateCustomerWithZeSlowServiceData(CustomerServiceImpl.java:166) ~[CustomerServiceImpl.class:na] at fr.xebia.ws.customer.v1_0.CustomerServiceImpl.getCustomer(CustomerServiceImpl.java:99) ~[CustomerServiceImpl.class:na] ... 84 common frames omitted

2010/04/12 15:06:09 [catalina-exec-18] WARN o.a.cxf.phase.PhaseInterceptorChain - Application {http://ws.xebia.fr/customer/v1_0}customerService #{http://ws.xebia.fr/customer/v1_0}getCustomer has thrown exception, unwinding now org.apache.cxf.interceptor.Fault: Exception getting customer '1' at org.apache.cxf.service.invoker.AbstractInvoker.createFault(AbstractInvoker.java:155)Caused by: java.lang.RuntimeException: Exception getting customer '1' at fr.xebia.ws.customer.v1_0.CustomerServiceImpl.getCustomer(CustomerServiceImpl.java:101)Caused by: java.lang.RuntimeException: Something went wrong at fr.xebia.ws.customer.v1_0.CustomerServiceImpl.doSomeWork(CustomerServiceImpl.java:66)

Exceptions & stack trace vs.

code erreur

Sunday, June 13, 2010

Page 26: Bonnes pratiques des applications java prêtes pour la production

La gestion des logs

www.xebia.fr / blog.xebia.fr 2

logs

logs-to-collect

my-app-audit.log

my-app.log

my-app-troubleshooting.logmy-app-troubleshooting-1.log

my-app-troubleshooting-9.log

my-app-audit-20100411.logmy-app-audit-201004....log

my-app-20100411.logmy-app-201004...log

>= WARN, compact stack trace, collected

only audit, collected

10x10Mo, rolling, NOT collected, mostly >= WARN

...

...

...

easy to collect log files

Sunday, June 13, 2010

Page 27: Bonnes pratiques des applications java prêtes pour la production

La gestion des logs

Audit par annotation

Exemple de message

www.xebia.fr / blog.xebia.fr 2

@RolesAllowed("ROLE_USER")@Audited(message = "CustomerService.getCustomer(#{args[0]})")public Customer getCustomer(long id) throws MyException { // ...}

...2010/04/12-17:18:00:266

CustomerService.getCustomer(12) by ze-remote-app coming from 9.0.1.53 ...

Sunday, June 13, 2010

Page 28: Bonnes pratiques des applications java prêtes pour la production

La Robustesse

Dépendances inter-application : fail fast est-il synonyme de fragilité ?

Prévention des saturations et des effets "domino" : l'art du code défensif,

Les modes dégradés

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 29: Bonnes pratiques des applications java prêtes pour la production

La Robustesse

Dépendances inter-application : fail fast est-il synonyme de fragilité ?

Bloquer le démarrage pour mauvaise configuration

Ne pas bloquer le démarrage pour indisponibilité d’une dépendance

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 30: Bonnes pratiques des applications java prêtes pour la production

La Robustesse

Prévention des saturations et des effets "domino" : l'art du code défensif

www.xebia.fr / blog.xebia.fr 2

Presentation & Business Layer

Sometimes Slow

Service

Short timeout is

impossible !

Presentation & Business Layer

Sometimes Slow

Service

limit concurrent invocations !

Sunday, June 13, 2010

Page 31: Bonnes pratiques des applications java prêtes pour la production

La Robustesse

Les modes dégradés

Mieux vaut-il un service limité ou un système en panne ?

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 32: Bonnes pratiques des applications java prêtes pour la production

L’organisation

Prévoir l’exploitation

Les développeurs en support niveau 3

You Build It, You Run It !

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 33: Bonnes pratiques des applications java prêtes pour la production

L’organisation

Prévoir l’exploitation

Dès la conception

Processus itératif

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 34: Bonnes pratiques des applications java prêtes pour la production

L’organisation

Les développeurs en support niveau 3

Prendre conscience

Responsabiliser

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 35: Bonnes pratiques des applications java prêtes pour la production

L’organisation

“You Build It You Run It !”Amazon

www.xebia.fr / blog.xebia.fr 2Sunday, June 13, 2010

Page 36: Bonnes pratiques des applications java prêtes pour la production

Formation !

www.xebia.fr / blog.xebia.fr 2

FormationApplications Java Prêtes pour la Production

Les 17 & 18 Mai 2010 !

Sunday, June 13, 2010