JavaOne 2008 - TS-6048 - Complex Event Processing at Orbitz

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    2 Favorites

    JavaOne 2008 - TS-6048 - Complex Event Processing at Orbitz - Presentation Transcript

    1. COMPLEX EVENT PROCESSING AT ORBITZ WORLDWIDE Matt O’Keefe, Senior Architect Doug Barth, Technical Lead TS-6048
        • How to make pager duty suck less
    2. $10.8 Billion in Gross Bookings in 2007
    3. Dozens of Apps, Hundreds of VMs and Thousands of Services
    4. The Need for Abstraction Webapp Travel Business Services Switching Services abstraction Transaction Services Suppliers
    5. Complex Event Processing is…
      • …about sensing and responding to threats and opportunities in real time.
    6. The Big Picture Event Processors Monitored Apps Operations Center Graphite JMX, ssh ERMA SNMP Portal
    7. ERMA
      • E xtremely R eusable M onitoring A PI
    8. The Monitor Interface
    9. Using EventMonitors protected void doValidate(RequestContext context, Object formObject, Errors errors) throws Exception { super.doValidate(context, formObject, errors); if (errors.hasErrors()) { EventMonitor validationMonitor = new EventMonitor("ValidationErrors"); validationMonitor.set("errors", errors.getAllErrors()); validationMonitor.fire(); } }
    10. The CompositeMonitor Interface
    11. Using TransactionMonitors public Hotel findHotelById(Long id) { TransactionMonitor monitor = new TransactionMonitor(getClass(), "findHotelById"); monitor.set(“id”, id); try { Hotel hotel = em.find(Hotel.class, id); monitor.succeeded(); return hotel; } catch (RuntimeException e) { monitor.failedDueTo(e); throw e; } finally { monitor.done(); } }
    12. TransactionMonitorTemplate public void cancelBooking(final Long id) { TransactionMonitorTemplate.INSTANCE.doInMonitor( getClass(), "cancelBooking", new TransactionMonitorCallback() { public Object doInMonitor(TransactionMonitor monitor) { monitor.set("id", id); Booking booking = em.find(Booking.class, id); if (booking != null) { em.remove(booking); } return null; } }); }
    13. Interceptors public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
    14. Listeners public interface FlowExecutionListener { public void requestSubmitted(RequestContext context); public void requestProcessed(RequestContext context); public void sessionStarting(RequestContext context, FlowDefinition definition, MutableAttributeMap input); public void sessionCreated(RequestContext context, FlowSession session); public void sessionStarted(RequestContext context, FlowSession session); public void eventSignaled(RequestContext context, Event event); public void stateEntering(RequestContext context, StateDefinition state) throws EnterStateVetoException; public void stateEntered(RequestContext context, StateDefinition previousState, StateDefinition state); public void paused(RequestContext context, ViewSelection selectedView); public void resumed(RequestContext context); public void sessionEnding(RequestContext context, FlowSession session, MutableAttributeMap output); public void sessionEnded(RequestContext context, FlowSession session, AttributeMap output); public void exceptionThrown(RequestContext context, FlowExecutionException exception); }
    15. Annotations @Monitored public interface UnderpantsGnomes { void collectUnderpants(); void ?(); void profit(); }
    16. Spring/AspectJ <aop:config> <aop:aspect id=&quot;transactionMonitorActionAspect&quot; ref=&quot;transactionMonitorActionAdvice&quot;> <aop:pointcut id=&quot;transactionMonitorActionPointcut“ expression=&quot; target(org.springframework.webflow.execution.Action) and args(context) &quot;/> <aop:around pointcut-ref=&quot;transactionMonitorActionPointcut“ method=&quot; invoke &quot;/> </aop:aspect> </aop:config> <bean id=&quot;transactionMonitorActionAdvice&quot; class= &quot; c.o.webframework.aop.aspectj.TransactionMonitorActionAdvice &quot;/>
    17. Joining Monitors - Across Threads TransactionMonitor monitor = new TransactionMonitor(&quot;Profit&quot;); ErmaCallable callable = new ErmaCallable( new CollectUnderpantsCallable() ); try { Future future = executorService.submit(callable); future.get(FUNDING_DURATION, TimeUnit.MILLISECONDS); monitor.addChildMonitor(callable.getMonitor()); monitor.succeeded(); } catch (TimeoutException e) { monitor.failedDueTo(e); throw e; } finally { monitor.done(); }
    18. Joining Monitors - Distributed Services public DispatcherResponse doFilter(DispatcherRequest request, Object resource, FilterChain chain) throws Throwable { TransactionMonitor monitor = new TransactionMonitor(getName(request)); MonitoringEngine mEngine = MonitoringEngine.getInstance(); Map inheritableAttributes = mEngine.getInheritableAttributes() ; Map serializableAttributes = mEngine.makeSerializable(inheritableAttributes); HashMap ermaAttributes = new HashMap(serializableAttributes); request.addParameter( ERMA_FILTER_PARAM_KEY , OLCSerializer.serialize(ermaAttributes) ); DispatcherResponse response = chain.doFilter(request, resource); … return response; }
    19. Distributed Services (cont.) public DispatcherResponse doFilter(DispatcherRequest request, Object resource, FilterChain chain) throws Throwable { … DispatcherResponse response = chain.doFilter(request, resource); Object responseBlob = response.getParameter( ERMA_FILTER_PARAM_KEY ); Monitor responseMonitor = (Monitor) OLCSerializer.deserialize ((byte[]) responseBlob); monitor.addChildMonitor(responseMonitor); Throwable throwable = response.getThrowable(); if (throwable == null) { monitor.succeeded(); } else { monitor.failedDueTo(throwable); } return response; }
    20. The MonitorProcessor Interface public interface MonitorProcessor { public void startup(); public void shutdown(); public void monitorCreated(Monitor monitor); public void monitorStarted(Monitor monitor); public void process(Monitor monitor); }
    21. A MonitorProcessorAdaptor Example public class ResultCodeAnnotatingMonitorProcessor extends MonitorProcessorAdapter { public void process(Monitor monitor) { if (monitor.hasAttribute(&quot;failureThrowable&quot;)) { Throwable t = (Throwable) monitor.get(&quot;failureThrowable&quot;); while (t.getCause() != null) { t = t.getCause(); } monitor.set(&quot;resultCode&quot;, t.getClass().getName()); } else { monitor.set(&quot;resultCode&quot;, &quot;success&quot;); } } }
    22. LoggingMonitorProcessor Output process: c.o.monitoring.api.monitor.TransactionMonitor -> blockedCount = 9 -> blockedTime = 17 -> cpuTimeMillis = 1470.0 -> createdAt = Sun Mar 09 16:13:17 CDT 2008 -> endTime = Sun Mar 09 16:13:30 CDT 2008 -> failed = false -> hostname = oberon -> latency = 13180 -> name = httpIn_/shop/airsearch/search/air/pageView_airResults -> remoteIpAddress = 10.222.186.147 -> sessionId = D417C9CC585F82E1 -> threadId = 2a20ec -> validationFailure = false -> vmid = wl -> waitedCount = 10 -> waitedTime = 10414
    23. EventPatternLoggingMonitorProcessor Output wl|httpIn_/shop/airsearch/search/air/pageView_airResults|13180 wl|RoundTripAirSearchAction.resolveRoundTripAirLocations|136 wl|jiniOut_LocationFinderService_findAirports|84 tbs-shop-13.31|jiniIn_LocationFinderService_findAirports|31 tbs-shop-13.31|jiniOut_AirportLookupService_findLocationByIATACode|9 market-8.4|jiniIn_AirportLookupService_findLocationByIATACode|3 tbs-shop-13.31|jiniOut_AirportLookupService_findLocationByIATACode|15 market-8.4|jiniIn_AirportLookupService_findLocationByIATACode|10 wl|jiniOut_LocationFinderService_findAirports|48 tbs-shop-13.31|jiniIn_LocationFinderService_findAirports|16 tbs-shop-13.31|jiniOut_AirportLookupService_findLocationByIATACode|14 market-8.4|jiniIn_AirportLookupService_findLocationByIATACode|10 wl|AirSearchExecuteAction.search|10422 wl|jiniOut_ShopService_createResultSet|9798 tbs-shop-13.31|jiniIn_ShopService_createResultSet|9601 tbs-shop-13.31|com.orbitz.tbs.host.shop.ShopServiceImpl.createResultSet.AIR|9361 tbs-shop-13.31|com.orbitz.tbs.spi.SpiShopService.createResultSet.AIR|9333 tbs-shop-13.31|jiniOut_LowFareSearchService_execute|9175 air-search-7.2.1|jiniIn_LowFareSearchService_execute|9094 air-search-7.2.1|LowFareSearchRequest|9048 air-search-7.2.1|com.orbitz.afo.lib.search.service.LowFareSearchServiceImpl|9038 air-search-7.2.1|com.orbitz.afo.lib.search.service.LowFareSearchServiceImpl.execute|9037 wl|jiniOut_ShopService_viewResultSet|607 tbs-shop-13.31|jiniIn_ShopService_viewResultSet|486 wl|pageView_airResults wl|jsp.render.air200.page|2475
    24. EventPatternLoggingMonitorProcessor Output wl|AirSearchExecuteAction.search| NoSearchResultsAvailableException wl|jiniOut_ShopService_createResultSet| NoSearchResultsAvailableException tbs-shop|jiniIn_ShopService_createResultSet| NoSearchResultsAvailableException tbs-shop|c.o.t.h.s.ShopServiceImpl.createResultSet.AIR| NoSearchResultsAvailableException tbs-shop|c.o.t.s.SpiShopService.createResultSet.AIR| NoSearchResultsAvailableException tbs-shop|jiniOut_LowFareSearchService_execute| SearchSolutionNotFoundException air-search|jiniIn_LowFareSearchService_execute| SearchSolutionNotFoundException air-search|LowFareSearchRequest| SearchSolutionNotFoundException Follow the trail of Exceptions… don’t bother the on-call engineers for the higher layers… save time by narrowing your log search query!
    25. Event Processing
    26. EventFlow
    27. Expression Language !failed latency > 1000 && failed totalFailed/total sum(int(failed)) stddev(latency) indexof(name, ‘jini’) == 0 strftime(“%Y%m%d, windowTimestamp)
    28. Event Processing Demo StreamBase Studio
    29. Custom Functions public class HelloWorld { public static String sayHello(String name) { return &quot;Hello, “ + name; } }
    30. Custom Operators public void processTuple(int inputPortId, Tuple tuple) throws StreamBaseException { String name = tuple.getString(&quot;name&quot;); Tuple output = outputSchema.createTuple(); output.setField(&quot;message&quot;, &quot;Hello, &quot;+name); sendOutput(OUTPUT_PORT, output); }
    31. Visualization
    32. SNMP
    33. Graphite
    34. Graphite RESTful URLs target=tbs-shop.all.jiniIn.ShopService.createResultSet#all.count
    35. Graphite RESTful URLs - Wildcards target=tbs-shop.all.jiniIn.ShopService. * .count
    36. Graphite RESTful URLs - Functions target= derivative( tbs-shop.all.jiniIn.ShopService.*.count )
    37. Graphite RESTful URLs – Pie Charts target=cpuTime:790&target=waitedTime:4043&target=blockedTime:0&target=other:31
    38. Graphite RESTful URLs – Raw CSV Data target=tbs-shop.all.jiniIn.ShopService.*.count& rawData=true 0 0 0 0 0 0 0 0 0 0 0 0 0 None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None 84 92 90 84 76 81 78 84 89 83 85 81 89 None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None None 81 91 94 82 79 81 79 83 87 84 82 86 85 None None None None None None None None None None None None None 0 0 0 0 0 1 0 0 0 0 0 0 0 None None None None None None None None None None None None None 0 0 0 0 0 0 0 0 0 0 0 0 0 81 91 94 82 79 82 79 83 87 84 82 86 85
    39. Graphite CLI - Dashboards
    40. Monitoring Portal
    41. RSS
    42. Command Line Stream Discovery [mokeefe@egcep03 ~]$ sbc list input-streams input-stream DeleteFromThresholds input-stream GarbageCollectorStats input-stream ListActiveAlarmsInput input-stream MemoryPoolStats input-stream MemoryStats input-stream MonitorInput input-stream MonitoringEngineManager_lifecycle input-stream ReloadLog4j input-stream ThreadStats input-stream ThresholdInput …
    43. Command Line Schema Discovery [mokeefe@egcep03 ~]$ sbc describe MonitorInput <stream name=“…&quot; schema=“…&quot; uuid=&quot;...&quot;> <schema name=&quot;schema:MonitorInput&quot; uuid=“…&quot;> <field name=&quot;name&quot; size=&quot;256&quot; type=&quot;string&quot;/> <field name=&quot;vmid&quot; size=&quot;128&quot; type=&quot;string&quot;/> <field name=&quot;hostname&quot; size=&quot;128&quot; type=&quot;string&quot;/> <field name=&quot;threadId&quot; size=&quot;32&quot; type=&quot;string&quot;/> <field name=&quot;createdAt&quot; type=&quot;timestamp&quot;/> <field name=&quot;endTime&quot; type=&quot;timestamp&quot;/> <field name=&quot;latency&quot; type=&quot;int&quot;/> <field name=&quot;cpuTimeMillis&quot; type=&quot;int&quot;/> <field name=&quot;failureThrowable&quot; size=&quot;16384&quot; type=&quot;string&quot;/> <field name=&quot;failed&quot; type=&quot;bool&quot;/> <field name=&quot;resultCode&quot; size=&quot;128&quot; type=&quot;string&quot;/> <field name=&quot;sessionId&quot; size=&quot;32&quot; type=&quot;string&quot;/> <field name=&quot;locale&quot; size=&quot;24&quot; type=&quot;string&quot;/> <field name=&quot;remoteIpAddress&quot; size=&quot;15&quot; type=&quot;string&quot;/> <field name=&quot;posCode&quot; size=&quot;4&quot; type=&quot;string&quot;/> </schema> </stream>
    44. Command Line Queries [mokeefe@egcep03 ~]$ sbc dequeue MonitorInput --where &quot; sessionId == '570EA1FABEE015B9' and vmid='tbs-shop-13.31' &quot; jiniOut_AirportLookupService_findLocationByIATACode,tbs-shop-13.31,egbsoneg01.prod.o.com,67484c,2008-03-10 15:40:42.489-0500,2008-03-10 15:40:42.489-0500,2008-03-10 15:40:42.502-0500,13,null,null,null,false,null,null,GBP,570EA1FABEE015B9,English (United Kingdom),10.235.1.119,null,EBUK jiniIn_LocationFinderService_findAirports,tbs-shop-13.31,egbsoneg01.prod.o.com,67484c,2008-03-10 15:40:42.480-0500,2008-03-10 15:40:42.480-0500,2008-03-10 15:40:42.503-0500,23,null,null,null,false,null,success,GBP,570EA1FABEE015B9,English (United Kingdom),10.235.1.119,null,EBUK …
    45. Event Pattern Monitoring
    46. Event Pattern Monitoring (cont)
    47. Event Pattern Monitoring Work In Progress Orbitz Worldwide Real-time Clickstream Analysis w/Correlation
    48. Recap Event Processors Monitored Apps Operations Center Graphite JMX, ssh ERMA SNMP Portal
    49. Future Directions
      • Orbitz Worldwide will open source ERMA
      • Orbitz Worldwide will open source Graphite
      • Orbitz Worldwide is considering open sourcing of
      • orbitz-lib-streambase
      • Esper integration
    50. For More Information
      • The Power of Events: An Introduction to Complex Event Processing in Distributed Enterprise Systems, David Luckham, Addison Wesley Professional, May 2002, ISBN: 0201727897
      • http:// www.complexevents.com
      • ERMA and Graphite: Watch http://forum.complexevents.com/ for an announcement
      • http:// corp.orbitz.com /careers/
      • StreamBase: http:// www.streambase.com /
      • Esper: http://esper.codehaus.org/
    51. Matt O’Keefe, Senior Architect Doug Barth, Technical Lead TS-6048
    52. Appendix: Filters public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws … { TransactionMonitor monitor = new TransactionMonitor(getClass(), &quot;doFilter&quot;); try { filterChain.doFilter(servletRequest, servletResponse); monitor.succeeded(); } catch (IOException e) { monitor.failedDueTo(e); throw e; } catch (ServletException e) { monitor.failedDueTo(e); throw e; } catch (RuntimeException e) { monitor.failedDueTo(e); throw e; } finally { monitor.done(); } }
    53. Appendix: Interceptors public class ERMAInterceptor extends HandlerInterceptorAdapter { public boolean preHandle(…) throws Exception { TransactionMonitor monitor = new TransactionMonitor(&quot;httpIn&quot;); monitor.setInheritable(POSCODE, getPosCode()); monitor.setInheritable(LOCALE, getLocale()); monitor.setInheritable(CURRENCY, getCurrency()); monitor.setInheritable(CHANNEL, getChannel()); monitor.setInheritable(SESSION_ID, getSessionId()); monitor.setInheritable(IP_ADDR, getClientAddress()); }
    54. Appendix: Interceptors (cont.) public void postHandle(…) throws Exception { View view = modelAndView.getView(); if (view == null) { String viewName = modelAndView.getViewName(); EventMonitor monitor = new EventMonitor(&quot;pageView_&quot; + viewName); monitor.fire(); } else if (RedirectView.class.isAssignableFrom( view.getClass())) { String redirectUrl = extractDispatcherPath(request); EventMonitor monitor = new EventMonitor(&quot;redirect_&quot; + redirectUrl); monitor.fire(); } }
    55. Appendix: Interceptors (cont.) public void afterCompletion(…, Exception exception) throws Exception { TransactionMonitor httpInMonitor = (TransactionMonitor) MonitoringEngine.getInstance(). getCompositeMonitorNamed(&quot;httpIn&quot;); if (exception == null) { httpInMonitor.succeeded(); } else { httpInMonitor.failedDueTo(exception); } httpInMonitor.set(Monitor.NAME, constructNewMonitorName(httpInMonitor)); httpInMonitor.done(); }
    56. Appendix: Listeners public void stateEntering(RequestContext context, StateDefinition nextState) throws EnterStateVetoException { EventMonitor monitor = new EventMonitor(&quot;flowExecution.stateEntering&quot;); StateDefinition currentState = context.getCurrentState(); monitor.set(&quot;currentStateId&quot;, currentState.getId()); monitor.set(&quot;nextStateId&quot;, nextState.getId()); monitor.fire(); }

    + Matt O'KeefeMatt O'Keefe, 11 months ago

    custom

    929 views, 2 favs, 0 embeds more stats

    A multimedia recording of this presentation can be more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 929
      • 929 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 33
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories