Bonnes pratiques des applications java prêtes pour la production

Cyrille Le Clerc
Cyrille Le ClercProduct Manager at Elastic
Bonnes Pratiques
                                    Des
                             Applications Java
                         Prêtes pour la Production




                                                  des          Prêtes pour la
                        Bonnes Pratiques
                                           Applications Java    Production




                                       Cyrille Le Clerc

Sunday, June 13, 2010
Cyrille Le Clerc


   Architecte Java EE depuis 11 ans

   Committer Apache CXF

   Directeur associé chez Xebia

    cleclerc@xebia.fr




                        www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
Le Déploiement




       Minimiser le nombre de composants à déployer




                         www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Minimiser le nombre de composants à
déployer
                        my-app




                                 html       *.html
                                              *.html


                                 css



                                 img



                                  js



                                 jsp
                                            *.jsp
                                              *.jsp


                             WEB-INF

                                              classes


                                                 lib




                                 www.xebia.fr / blog.xebia.fr
                                           web.xml              5
Sunday, June 13, 2010
Minimiser le nombre de composants à
déployer
                                                               my-app



                                                                        html
                                                                                 *.html    just in case
                                                                        css


                                                                        img


                                                                         js



                                                                        jsp    *.jsp
                                                                                 *.jsp
    # don't proxy static content !
    ProxyPassMatch ^(/my/.*.html)$ !                              WEB-INF

    ProxyPassMatch ^(/my/.*.css)$ !                                            classes
                                                         2                                      1
    ProxyPassMatch ^(/my/.*.gif)$ !                                              lib

    ProxyPassMatch ^(/my/.*.jpeg)$ !
    ProxyPassMatch ^(/my/.*.png)$ !                                           web.xml

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

    # proxy dynamic content                   my-app static files                          my-app.war
    ProxyPass /my/ http://my:8080/my/
                                                 Apache Httpd                              Tomcat
      3   httpd.conf

                                        www.xebia.fr / blog.xebia.fr                                      5
Sunday, June 13, 2010
Minimiser le nombre de composants à
déployer
                                                                 my-app



                                                                          html
                                                                                   *.html

                                                                          css


                                                                          img


                                                                           js



                                                                          jsp    *.jsp
                                                                                   *.jsp

                                                                       WEB-INF

                                                                                  classes

                                                                                    lib
   # proxy /my/                                                                                  1
   ProxyPass /my/ http://my:8080/my/                                             web.xml




  2   httpd.conf                               my-app static files                           my-app.war

                          Cache Proxy              Apache Httpd                              Tomcat

                                        www.xebia.fr / blog.xebia.fr                                     5
Sunday, June 13, 2010
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              2
Sunday, June 13, 2010
Le Déploiement




                        Les paramètres de configuration




                                   www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
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)
                                                             Production



                                                                                                       db-α




                                                               p1
                                                                                 app-1
                                                                                                1521


                                                            /ap
                                                                       10080
                                                80                             srv-i, srv-j, srv-k
                                                                                  ...

                                                443           /ap
              Internet                         om                                                      db-β
                                                                 p2
                                     p   any.c                                    app-2       1521
                             m y-com
                                                                       20080
                         Firewall                                           srv-l, srv-m, srv-n


                                             www.xebia.fr / blog.xebia.fr                                     2
Sunday, June 13, 2010
Les paramètres de configuration
                                                             Production



                                                                                                      db-α




                                                               p1
                                                                                 app-1
                                                                                             1521




                                                            /ap
                                                                      10080
                                                 80                         srv-i, srv-j, srv-k




                                                                                                             Sa
                                                                               ...




                                                                                                              m
                                                                                                                  e
                                                                                                                   ho
                                            443               /ap




                                                                                                                      s
                                         .com                                                         db-β




                                                                                                                       tn
                                                                 p2
                                     pany




                                                                                                             Sa
                                                                                 app-2




                                                                                                                        am
                                                                                               1521
                                y-com




                                                                                                              m
                            m




                                                                                                                            es
                                                                      20080




                                                                                                               e
                                                                           srv-l, srv-m, srv-n




                                                                                                                  ne
                        Firewall




                                                                                                                   tw
                                                                                                                       or
                                                                                                             Ca


                                                                                                                        k
                                                                                                              n


                                                                                                                            po
            Internet                                  NO communication




                                                                                                                  be


                                                                                                                              rt
                                                                                                                              s
                                                                                                                      sa
                                                                                                                       m
                                                              Validation




                                                                                                                        e
                                                                                                                            IP
                                                                                                                              !
                                                                                                      db-α
                                                               p1




                                                                                 app-1
                                                                                               1521
                                                            /ap




                                                                      10080
                                                 80                           srv-i, srv-j, srv-k
                                                                                 ...

                        proxy                    443          /ap
                                                       om        p2                                   db-β
                                                 any.c                           app-2         1521
                                           omp
                                    my-c                              20080
                                Firewall                                  srv-l, srv-m, srv-n

                                                               www.xebia.fr / blog.xebia.fr                                        5
Sunday, June 13, 2010
Le Déploiement

   La traçabilité
           my-app/tags/1.2.3/
                                                       artefact taggé

                                   my-app-1.2.3.war




                                                                                       Co
                                                                                          mme
                                    Repository                                                nt
                                                                                                   dé
                                                                                                     plo
                                                                                                        ye
                                                                                                          r
                                                                                                              ?




                        Dev zone                                                Data centers


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


   Exposer des indicateurs métier

   Logs vs. JSP vs. JMX




                           www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
Supervision et Monitoring


    Logs de monitoring

   Détail par invocation vs. moyenne par minute




                         www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

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


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




                            www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

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




                        www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

    JMX : Simple

 @ManagedResource
 public class DemoServiceImpl {

  private final AtomicInteger invocationCount = new AtomicInteger();

  @ManagedAttribute
  public int getInvocationsCount() {
    return invocationCount.get();
  }

  @ManagedOperation
  public void purge(){
    // ...
  }




                              www.xebia.fr / blog.xebia.fr             2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

    JMX : VisualVM




                        www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

    JMX : Hyperic HQ & cie




                        www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
Monitoring : logs vs. jsp vs. jmx

    JMX & JSP


                        Powered by JMX !




                                www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
La gestion des logs


    Exceptions java & stack trace vs. code erreur

    Troubleshooting vs. logs longue durée &audit




                        www.xebia.fr / blog.xebia.fr   2
Sunday, June 13, 2010
La gestion des logs

                                                                        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 now
                                                                        org.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]




        Exceptions & stack trace
                                                                                                             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]




                  vs.
                                                                                                             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]




              code erreur
                                                                                                             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 omitted
                                                                        Caused 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)

                                                 www.xebia.fr / blog.xebia.fr                                                                                                                                                                                                                                 2
Sunday, June 13, 2010
La gestion des logs


                                       >= WARN, compact stack trace, collected
         logs
                        my-app.log
                                                      only audit, collected
                        my-app-audit.log                                       10x10Mo, rolling,
                                                                                NOT collected,
                        my-app-troubleshooting.log                             mostly >= WARN
                        my-app-troubleshooting-1.log
                        ...
                        my-app-troubleshooting-9.log


   logs-to-collect        easy to collect log files


                        my-app-audit-20100411.log
                        my-app-audit-201004....log
                        ...
                        my-app-20100411.log
                        my-app-201004...log
                        ...
                                                www.xebia.fr / blog.xebia.fr                       2
Sunday, June 13, 2010
La gestion des logs


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


    Exemple de message
    ...
    2010/04/12-17:18:00:266
        CustomerService.getCustomer(12) by ze-remote-app coming from 9.0.1.53
    ...




                                       www.xebia.fr / blog.xebia.fr             2
Sunday, June 13, 2010
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                                  2
Sunday, June 13, 2010
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                                  2
Sunday, June 13, 2010
La Robustesse

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

                                                                            Sh
                                                                              or
                                                                            im t tim
                                                                               po
                                                                                  ssi eou
                                                                                     ble t i
                                                               Sometimes                ! s
                        Presentation & Business
                                                                 Slow
                                 Layer
                                                                Service




                                                                      Sometimes
                        Presentation & Business                         Slow
                                 Layer                                 Service



                                           limit concurrent invocations !




                                www.xebia.fr / blog.xebia.fr                                   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
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   2
Sunday, June 13, 2010
L’organisation

    Prévoir l’exploitation

   Dès la conception

   Processus itératif




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

    Les développeurs en support niveau 3

   Prendre conscience

   Responsabiliser




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




                        “You Build It You Run It !”
                                            Amazon




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




                         Formation
        Applications Java Prêtes pour la Production
                  Les 17 & 18 Mai 2010 !




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

More Related Content

Viewers also liked(20)

Introduction àJavaIntroduction àJava
Introduction àJava
Christophe Vaudry3K views
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
Yakov Fain2K views
AngularJS for Java DevelopersAngularJS for Java Developers
AngularJS for Java Developers
Loc Nguyen4.1K views
Reactive Thinking in JavaReactive Thinking in Java
Reactive Thinking in Java
Yakov Fain1.6K views
20090615 - Ch'ti JUG - Apache Maven20090615 - Ch'ti JUG - Apache Maven
20090615 - Ch'ti JUG - Apache Maven
Arnaud Héritier2K views
JCertif 2012 : Maven par la pratiqueJCertif 2012 : Maven par la pratique
JCertif 2012 : Maven par la pratique
Rossi Oddet2.6K views
Tp java ee.pptxTp java ee.pptx
Tp java ee.pptx
Eric Bourdet2.5K views
Soutenance PFE 2012Soutenance PFE 2012
Soutenance PFE 2012
Vanessa Pasquet6.3K views
Angular 4 for Java DevelopersAngular 4 for Java Developers
Angular 4 for Java Developers
Yakov Fain7.3K views
Angular 2 for Java DevelopersAngular 2 for Java Developers
Angular 2 for Java Developers
Yakov Fain25.9K views
Presentation Spring, Spring MVCPresentation Spring, Spring MVC
Presentation Spring, Spring MVC
Nathaniel Richand19.2K views
Reactive programming in Angular 2Reactive programming in Angular 2
Reactive programming in Angular 2
Yakov Fain2.6K views
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2
Knoldus Inc.22.4K views

Similar to Bonnes pratiques des applications java prêtes pour la production

Similar to Bonnes pratiques des applications java prêtes pour la production(20)

Synchronizing Core Data With RailsSynchronizing Core Data With Rails
Synchronizing Core Data With Rails
Ken Collins7.9K views
Introduction to Apache CamelIntroduction to Apache Camel
Introduction to Apache Camel
FuseSource.com6.5K views
ZK_Arch_notes_20081121ZK_Arch_notes_20081121
ZK_Arch_notes_20081121
WANGCHOU LU131 views
Tuning Web PerformanceTuning Web Performance
Tuning Web Performance
Eric ShangKuan3.1K views
Tuning web performanceTuning web performance
Tuning web performance
George Ang639 views
Camel and JBossCamel and JBoss
Camel and JBoss
JBug Italy2.4K views
Jspx Jdc2010Jspx Jdc2010
Jspx Jdc2010
suppport jspx942 views
Open End To End Js StackOpen End To End Js Stack
Open End To End Js Stack
Skills Matter383 views
Jsf2 composite-componentsJsf2 composite-components
Jsf2 composite-components
vinaysbk699 views
JavaEE6 my wayJavaEE6 my way
JavaEE6 my way
Nicola Pedot441 views
TorqueBox at DC:JBUG - November 2011TorqueBox at DC:JBUG - November 2011
TorqueBox at DC:JBUG - November 2011
bobmcwhirter767 views
Ajax Tags AdvancedAjax Tags Advanced
Ajax Tags Advanced
AkramWaseem1.4K views
JavaScript-CoreJavaScript-Core
JavaScript-Core
tutorialsruby603 views
JavaScript-CoreJavaScript-Core
JavaScript-Core
tutorialsruby525 views
J2 Ee OverviewJ2 Ee Overview
J2 Ee Overview
Atul Shridhar2.5K views
HTML5와 모바일HTML5와 모바일
HTML5와 모바일
ACCESS1.2K views

Recently uploaded(20)

METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...
METHOD AND SYSTEM FOR PREDICTING OPTIMAL LOAD FOR WHICH THE YIELD IS MAXIMUM ...
Prity Khastgir IPR Strategic India Patent Attorney Amplify Innovation24 views
Green Leaf Consulting: Capabilities DeckGreen Leaf Consulting: Capabilities Deck
Green Leaf Consulting: Capabilities Deck
GreenLeafConsulting177 views
CXL at OCPCXL at OCP
CXL at OCP
CXL Forum203 views
Liqid: Composable CXL PreviewLiqid: Composable CXL Preview
Liqid: Composable CXL Preview
CXL Forum120 views

Bonnes pratiques des applications java prêtes pour la production

  • 1. Bonnes Pratiques Des Applications Java Prêtes pour la Production des Prêtes pour la Bonnes Pratiques Applications Java Production Cyrille Le Clerc Sunday, June 13, 2010
  • 2. Cyrille Le Clerc  Architecte Java EE depuis 11 ans  Committer Apache CXF  Directeur associé chez Xebia cleclerc@xebia.fr www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 3. 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 2 Sunday, June 13, 2010
  • 4. 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 2 Sunday, June 13, 2010
  • 5. 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 2 Sunday, June 13, 2010
  • 6. Le Déploiement Minimiser le nombre de composants à déployer www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 7. Minimiser le nombre de composants à déployer my-app html *.html *.html css img js jsp *.jsp *.jsp WEB-INF classes lib www.xebia.fr / blog.xebia.fr web.xml 5 Sunday, June 13, 2010
  • 8. Minimiser le nombre de composants à déployer my-app html *.html just in case css img js jsp *.jsp *.jsp # don't proxy static content ! ProxyPassMatch ^(/my/.*.html)$ ! WEB-INF ProxyPassMatch ^(/my/.*.css)$ ! classes 2 1 ProxyPassMatch ^(/my/.*.gif)$ ! lib ProxyPassMatch ^(/my/.*.jpeg)$ ! ProxyPassMatch ^(/my/.*.png)$ ! web.xml ProxyPassMatch ^(/my/.*.js)$ ! # proxy dynamic content my-app static files my-app.war ProxyPass /my/ http://my:8080/my/ Apache Httpd Tomcat 3 httpd.conf www.xebia.fr / blog.xebia.fr 5 Sunday, June 13, 2010
  • 9. Minimiser le nombre de composants à déployer my-app html *.html css img js jsp *.jsp *.jsp WEB-INF classes lib # proxy /my/ 1 ProxyPass /my/ http://my:8080/my/ web.xml 2 httpd.conf my-app static files my-app.war Cache Proxy Apache Httpd Tomcat www.xebia.fr / blog.xebia.fr 5 Sunday, June 13, 2010
  • 10. 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 2 Sunday, June 13, 2010
  • 11. Le Déploiement Les paramètres de configuration www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 12. 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) Production db-α p1 app-1 1521 /ap 10080 80 srv-i, srv-j, srv-k ... 443 /ap Internet om db-β p2 p any.c app-2 1521 m y-com 20080 Firewall srv-l, srv-m, srv-n www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 13. Les paramètres de configuration Production db-α p1 app-1 1521 /ap 10080 80 srv-i, srv-j, srv-k Sa ... m e ho 443 /ap s .com db-β tn p2 pany Sa app-2 am 1521 y-com m m es 20080 e srv-l, srv-m, srv-n ne Firewall tw or Ca k n po Internet NO communication be rt s sa m Validation e IP ! db-α p1 app-1 1521 /ap 10080 80 srv-i, srv-j, srv-k ... proxy 443 /ap om p2 db-β any.c app-2 1521 omp my-c 20080 Firewall srv-l, srv-m, srv-n www.xebia.fr / blog.xebia.fr 5 Sunday, June 13, 2010
  • 14. Le Déploiement  La traçabilité my-app/tags/1.2.3/ artefact taggé my-app-1.2.3.war Co mme Repository nt dé plo ye r ? Dev zone Data centers www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 15. Supervision et Monitoring  Exposer des indicateurs métier  Logs vs. JSP vs. JMX www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 16. 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 2 Sunday, June 13, 2010
  • 17. Supervision et Monitoring Logs de monitoring  Détail par invocation vs. moyenne par minute www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 18. Monitoring : logs vs. jsp vs. jmx JSP  Attention à la sécurité !  Human Friendly and/or Script Friendly /my-app/seye5E7E/jmx/cxf.jsp www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 19. Monitoring : logs vs. jsp vs. jmx JMX  Sécurité ++  Simple  Human Friendly and/or Script Friendly www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 20. Monitoring : logs vs. jsp vs. jmx JMX : Simple @ManagedResource public class DemoServiceImpl { private final AtomicInteger invocationCount = new AtomicInteger(); @ManagedAttribute public int getInvocationsCount() { return invocationCount.get(); } @ManagedOperation public void purge(){ // ... } www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 21. Monitoring : logs vs. jsp vs. jmx JMX : VisualVM www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 22. Monitoring : logs vs. jsp vs. jmx JMX : Hyperic HQ & cie www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 23. Monitoring : logs vs. jsp vs. jmx JMX & JSP Powered by JMX ! www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 24. La gestion des logs Exceptions java & stack trace vs. code erreur Troubleshooting vs. logs longue durée &audit www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 25. La gestion des logs 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 now org.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] Exceptions & stack trace 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] vs. 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] code erreur 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 omitted Caused 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) www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 26. La gestion des logs >= WARN, compact stack trace, collected logs my-app.log only audit, collected my-app-audit.log 10x10Mo, rolling, NOT collected, my-app-troubleshooting.log mostly >= WARN my-app-troubleshooting-1.log ... my-app-troubleshooting-9.log logs-to-collect easy to collect log files my-app-audit-20100411.log my-app-audit-201004....log ... my-app-20100411.log my-app-201004...log ... www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 27. La gestion des logs  Audit par annotation @RolesAllowed("ROLE_USER") @Audited(message = "CustomerService.getCustomer(#{args[0]})") public Customer getCustomer(long id) throws MyException { // ... }  Exemple de message ... 2010/04/12-17:18:00:266 CustomerService.getCustomer(12) by ze-remote-app coming from 9.0.1.53 ... www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 28. 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 2 Sunday, June 13, 2010
  • 29. 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 2 Sunday, June 13, 2010
  • 30. La Robustesse  Prévention des saturations et des effets "domino" : l'art du code défensif Sh or im t tim po ssi eou ble t i Sometimes ! s Presentation & Business Slow Layer Service Sometimes Presentation & Business Slow Layer Service limit concurrent invocations ! www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 31. 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 2 Sunday, June 13, 2010
  • 32. 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 2 Sunday, June 13, 2010
  • 33. L’organisation Prévoir l’exploitation  Dès la conception  Processus itératif www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 34. L’organisation Les développeurs en support niveau 3  Prendre conscience  Responsabiliser www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 35. L’organisation “You Build It You Run It !” Amazon www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010
  • 36. Formation ! Formation Applications Java Prêtes pour la Production Les 17 & 18 Mai 2010 ! www.xebia.fr / blog.xebia.fr 2 Sunday, June 13, 2010