ãã®è¨äºã¯ ã¨ã ã¹ãªã¼Advent Calendar 2020ã®16æ¥ç®ã®è¨äºã§ãã
ã¨ã ã¹ãªã¼ã¨ã³ã¸ãã¢ãªã³ã°ã°ã«ã¼ãã®é¢æ ¹ï¼@sekikatsu36ï¼ã§ãã 2020å¹´4æããã¨ã ã¹ãªã¼ã¸åå ãã主ã«SREæ¥åãæ å½ãã¦ãã¾ãã
ã¨ã ã¹ãªã¼ã§ã¯æ°ç¾ã®ãã¤ã¯ããµã¼ãã¹ãéçºã»éç¨ãã¦ãã¾ããããã¤ã¯ããµã¼ãã¹ã¯1ã¤ã®å¦çã®æµãã追跡ãããã¨ï¼ãã¬ã¼ãµããªãã£ï¼ãé£ããããã©ãã«æã®åå ç¹å®ã«ã³ã¹ãããããã¨ãã課é¡ãããã¾ãã ãã®è§£æ±ºçã¨ãã¦åæ£ãã¬ã¼ã·ã³ã°ã«çç®ããGCPã®CloudTraceã主è¦ãµã¼ãã¹ã¸å°å ¥ãããã¨ãé²ãã¦ãã¾ããã
ããã§ã¯ãã®æ´»åãéãã¦å¾ãç¥è¦ãéå¤ã«ãç´¹ä»ãã¦ããã¾ãã
ä¾ã§ã¯Javaãå©ç¨ãã¾ãã ã¾ãåæ£ãã¬ã¼ã·ã³ã°ã®å®ç¾æ¹æ³ã¨ãã¦ã¯ãOpenCensus *1 ãæ¡ç¨ãã¾ãã
ãåæ£ãã¬ã¼ã·ã³ã°ã£ã¦ä½ï¼ãã¨ããæ¹ã¯ãéå»ã«å¼ç¤¾ã®ã¨ã³ã¸ãã¢ãJJUGã«ç»å£ããéã®è³æãããã¾ãã®ã§ããã²ã覧ãã ããã
- åæ£ãã¬ã¼ã·ã³ã°ã®å®è£
- ã©ãã§Spanãä½ãã¹ãã
- ãµã³ããªã³ã°ã¬ã¼ããè¨è¨ãã
- Spanã®Closeãå¿ãã«æ³¨æãã
- ã¾ã¨ã
- We are Hiring!
åæ£ãã¬ã¼ã·ã³ã°ã®å®è£
OpenCensusã®Javaã©ã¤ãã©ãªã使ãã¨ã以ä¸ã®ããã«Span*2ãè¨é²ã§ãã¾ãã
try (Scope ignored = Tracing.getTracer() .spanBuilder("Spanã®åå") .setSampler(Samplers.alwaysSample()) .startScopedSpan()) { // ä½ãå¦ç }
ãOpenCensusãã¨ãããã使ã£ã¦ã¿ããï¼ãã¨ããå ´åã¯ã便å©ãªã©ã¤ãã©ãªãå®è£ ä¾ã®ç´¹ä»è¨äºãã¤ã³ã¿ã¼ãããä¸ã«å¤ãåå¨ãããããæ¯è¼çç°¡åã«å®è£ ã§ããã¨æãã¾ãã ä¾ãã°ãç§ã¯åãã¦OpenCensusã触ã£ãæã«ãã¡ãã®è¨äºãåèã«ããã¦ããã ãã¾ããã
ã¾ãã¨ã ã¹ãªã¼ã§ã¯ãããç°¡åã«å®è£
ã§ãããããOpenCensusã®ã©ããã¼ m3-tracing ãéçºãã¦ãã¾ããOSSãªã®ã§èå³ãããã°ãã²ã覧ãã ãããããã¦ããããã°ã¹ã¿ã¼ãã ããï¼
ãã¡ããå©ç¨ããå ´åãä¾ãã°ä»¥ä¸ã®ããã«ããçãã³ã¼ãã§Spanãè¨é²ã§ãã¾ãã ãµã¼ãã¹ãã¾ãããTraceãä½æããéã¯ãå¾è¿°ããéãtraceparentããããèªåã§å¦çããªãã¦ãããããç¹ã«ä¾¿å©ã«ä½¿ãã¾ãã
M3Tracer tracer = M3TracerFactory.INSTANCE.get(); try(TraceSpan ignored = tracer.startSpan("spanã®åå")) { // ä½ãå¦ç }
ã©ãã§Spanãä½ãã¹ãã
åæ£ãã¬ã¼ã·ã³ã°ã§ã¯ãæéãè¨æ¸¬ãããç¯å²ãSpanã¨ãã¦æ示çã«å®ç¾©ããªããã°ãªãã¾ããã ãã¡ããé ããªããããªå ´æã«ã¯å ¨ã¦äºåã«ç´°ããå¿ è¦ååã«è¨å®ãã¦ããããã¨ããã§ããããããç¹å®ã§ããªãããåæ£ãã¬ã¼ã·ã³ã°ã使ãããããã§ã åæ£ãã¬ã¼ã·ã³ã°ã®å°å ¥ã§éå°ãªã³ã¹ãããããããã°ãåãè¾¼ãã§ã¯æ¬æ«è»¢åãªã®ã§ãç§ã¯ä»¥ä¸ã®æ¹éã§Spanãè¨å®ãã¦ãã¾ãã
(1) ã¨ããããä»ãµã¼ãã¹ããåãåã£ããªã¯ã¨ã¹ãã®éå§ãçµäºã«Spanãä½ã
åãµã¼ãã¹ã§ãããæºããã¦ããã°ãæ§è½åé¡ãçºçããéã«ãã¨ããããã©ã®ãµã¼ãã¹ãåå ãªã®ããå³åº§ã«å¤æã§ãã¾ãã
大é¨åã®å種ã®Webãã¬ã¼ã ã¯ã¼ã¯ã¯ããªã¯ã¨ã¹ããåä¿¡ããæã«å®è¡ãããFilteræ©è½ãåãã¦ããã®ã§ãTraceç¨ã®Filterãå®è£ ããã®ãè¯ãã¨æãã¾ãã ã¾ãããµã¼ãã¹ãã¾ããã§Traceãçµ±åããããã«ãtraceparent *3 ã®å¯¾å¿ãå¿ããã«å®è£ ãã¾ãã
å¼ç¤¾ã®å ´åããããã®æ©è½ãå®ç¾ããServlet Filterãå ±éé¨åã¨ãã¦å®è£ ãã¾ãããm3-tracingã«çµã¿è¾¼ã¿ãè¤æ°ã®ãµã¼ãã¹ã§å©ç¨ãã¦ãã¾ãã
m3-tracing/jvm/servlet at master · m3dev/m3-tracing · GitHub
(2) ä»ãµã¼ãã¹ãå¼ã³ã ããªã¯ã¨ã¹ãã®éå§ãçµäºã«Spanãä½ã
(1)ã«è¿½å ãããã¨ã§ããªã¯ã¨ã¹ããéããã¦ããåãåãããã¾ã§ã®æéããããããã«ãªãããããã¯ã¼ã¯ãä¸éæ©å¨ãããã«ã¦ã§ã¢ã«ããé 延ãçºè¦ã§ãã¾ãã ã¾ããDBãCacheãªã©ãããèªä½ã§Spanãä½æã§ããªãå¨è¾ºãµã¼ãã¹ã¸ã®å¼ã³åºãã«ããä½è£ãããã°è¿½å ãã¾ãã å®ä¾ã¨ãã¦ããããªã¯ã¨ã¹ããä¸å¿ è¦ã«DBã¸ä½åº¦ãã¢ã¯ã»ã¹ãã¦ããããã£ãã·ã¥ãæå¹ã«ä½¿ãã¦ããªãããªã©ã®åé¡ã®çºè¦ã«ç¹ããã¾ããã
ä»ãµã¼ãã¹ã¸ã®ã¢ã¯ã»ã¹ã¯HttpClientãRepositoryãªã©ã©ã¤ãã©ãªãå ±éã³ã³ãã¼ãã³ãã«ãªã£ã¦ãããã¨ãå¤ãã®ã§ããããã©ãã or æ¡å¼µãã¾ãã å¼ç¤¾ã®å ´åãSpringã®RestTemplateãApache HttpClientãokHttp, p6spy JdbcEventListenerãªã©ãå¿ è¦ã«ãªã£ãã¯ã©ã¤ã¢ã³ãã©ã¤ãã©ãªãã¨ã«ãã©ããããå ±éé¨åãä½ã£ã¦ãã¾ãã
ä¾ãã°Apache HttpClientã使ãå ´åã¯ã以ä¸ã®ããã«ãªã¯ã¨ã¹ãã®åå¾ã«ã©ã¤ãã©ãªã®å®è£ ãæããã¨ã§ãSpanã®ä½æãtraceparentãããã®éä¿¡ãSpanã®Closeãå®è£ å¯è½ã§ãã
CloseableHttpClient httpClient = HttpClientBuilder.create() .addInterceptorFirst((HttpRequestInterceptor) M3TracingHttpInterceptor.INSTANCE) .addInterceptorLast((HttpResponseInterceptor) M3TracingHttpInterceptor.INSTANCE) .build();
(3) ãã以å¤ã¯æ§è½åé¡ãçºçãã¦ããSpanã追å ãã
YAGNIååã«å¾ããéã«1,2以å¤ã®ç®æã¯ãå¿ è¦ã«ãªã£ã¦ãã対å¿ãã¾ãã ç¹ã«åé¡ãèµ·ãã¦ããªãã®ã«Spanã追å ãã¦ãã¾ãã¨ãå°å ¥ã³ã¹ããå¢ãããSpanãå¤ããã¦ãã¤ãºã«ãªãããªã©ãè²»ç¨å¯¾å¹æãèããªããã¡ã¨èãã¦ãã¾ãã
ã¾ããCloudTraceã¯Spanã®æ°ã§èª²éããããããç²ç®çã«Spanãä½ã£ã¦ãã¾ãã¨CloudTraceã®è²»ç¨ã«å½±é¿ãåºã¾ãã åã«Spanã«æ å ±ã足ãããå ´åã¯ãåSpanãæ°ãã«ä½ãã®ã§ã¯ãªãã(1)ã§ä½æããSpanã«Attribute(Tag, Label)ãMessageEventã追å ããã®ãæå¹ã§ãã
// å¦çå¥ã«åSpanãä½ãæ¹æ³ãç¡é§ã«Spanæ°ãå¢ãã¦é«ã³ã¹ãï¼ãã¤ãºãå¢ãã try(TraceSpan span = tracer.startSpan("panret")) { if(flag) { try(TraceSpan span = span.startChildSpan("proc a")) { // å¦çA } } else { try(TraceSpan span = span.startChildSpan("proc b")) { // å¦çB } } } //æéãè¨æ¸¬ããå¿ è¦ããªããªããã¿ã°ãã¤ããæ¹ãè¦éããè¯ã try(TraceSpan span = tracer.startSpan("panret")) { span.set("flag", flag) if(flag) { // å¦çA } else { // å¦çB } }
ãµã³ããªã³ã°ã¬ã¼ããè¨è¨ãã
å ¨ã¦ã®Spanããã®ã¾ã¾è¨é²ããã¨ããªã¼ãã¼ãããã®è¥å¤§ãå©ç¨æéã®å¢å ã«ç¹ããã¾ãã ãã®ãããµã³ããªã³ã°ã¬ã¼ããè¨å®ãã¦ãå®éã«è¨é²ãããé »åº¦ãæ¸ããã®ãä¸è¬çãã¨æãã¾ãã OpenCensusã§ã¯ããµã³ããªã³ã°ã¬ã¼ããAlways, æµ®åå°æ°ç¹(ä¾ãã°0.1ãªã10%)ãNeverã®ä¸ã¤ããè¨å®ã§ãã¾ãã
ããã§æ³¨æãã¹ãã¯ãè¤æ°ã®ãµã¼ãã¹ãTraceã横æããå ´åã®ãµã³ããªã³ã°ã¬ã¼ãã§ãã ä¾ãã° ãµã¼ãã¹Aãããµã¼ãã¹Bã«ãªã¯ã¨ã¹ããéä¿¡ãããæããµã¼ãã¹Bã®ãµã³ããªã³ã°ã¬ã¼ãã¯ãµã¼ãã¹Aã®ãµã³ããªã³ã°ã¬ã¼ãã«å½±é¿ãåãã¾ãã
ãµã¼ãã¹Aã®ãµã³ããªã³ã°ã¬ã¼ããNeverã ã£ãå ´å
ãµã¼ãã¹Aã®Spanã¯ä¸åè¨é²ãããããµã¼ãã¹Bã¯èªèº«ã®ãµã³ããªã³ã°ã¬ã¼ãã«å¾ã£ã¦Spanãè¨é²ãã¾ãã ãªããOpenCensusã®ã©ã¤ãã©ãªã使ãå ´åããµã³ããªã³ã°ã¬ã¼ããNeverã§ãã£ã¦ãããµã¼ãã¹Aããéããããªã¯ã¨ã¹ãã«ã¯traceparentããããä»ä¸ããã¾ãã
ãµã¼ãã¹Aã®ãµã³ããªã³ã°ã¬ã¼ããNever以å¤ã ã£ãå ´å
ãµã¼ãã¹BãNeverã§ããã°ããµã¼ãã¹Aã®Spanã ãè¨é²ããã¦ãã¾ãã§ãµã¼ãã¹Bãå¼ã°ãã¦ããªãããã«è¦ãããããã§ã¯ããã¾ããã ãµã¼ãã¹Bã§ã¯èªèº«ã®è¨å®ã¯ç¡è¦ããã親ã§ãããµã¼ãã¹Aã®Spanãè¨é²ãããå ´åã¯åæã«è¨é²ããã¾ãã
ãã®ããããSpanã®çæãæããããã«ãµã¼ãã¹Bã¯ãµã³ããªã³ã°ã¬ã¼ãã0.01ã«ããããã¨ããã±ã¼ã¹ã§ãããµã¼ãã¹Aã誤ã£ã¦Alwaysã«ãªã£ã¦ãã¾ãã¨ãå¼ããããã¦å ¨Spanãåºåããã¾ãã ãªãããµã¼ãã¹Aãçµç±ãããç´æ¥ãµã¼ãã¹Bå ã«ãªã¯ã¨ã¹ããé£ãã ã±ã¼ã¹ã§ã¯ãå½ç¶ãµã¼ãã¹Bã®ãµã³ããªã³ã°ã¬ã¼ããç´æ¥å½±é¿ãã¾ãã
ãã®ããã«ã親ã¨ãªãéä¿¡å ã®ãµã³ããªã³ã°ã¬ã¼ããè¨å®ããéã«ã¯æ³¨æãå¿ è¦ã§ãã 誤ã£ã¦rootã¨ãªããµã¼ãã¹ã®ãµã³ããªã³ã°ã¬ã¼ããAlwaysã«è¨å® â å¾ç¶ã®ãµã¼ãã¹ã§Spanãå ¨åºå â CloudTraceã®å©ç¨éé¡ãæ¥é¨°ãã¿ãããªç¶æ³ã«ã¯ãæ°ãã¤ããã ããã ç¹ã«rootã«è¿ããµã¼ãã¹ã§ã¯ããµã³ããªã³ã°ã¬ã¼ããä½ãã«è¨å®ãã¦ããã¦ãå¿ è¦ã«å¿ãã¦ä¸ãã¦ããæ¹ãè²»ç¨é¢ã§ã¯å®å¿ã§ãã
Spanã®Closeãå¿ãã«æ³¨æãã
åæ£ãã¬ã¼ã·ã³ã°ã¯ä¾¿å©ã§ããã誤ã£ã使ãæ¹ãããã¨ã¡ã¤ã³å¦çã«å½±é¿ãä¸ãã¦ãã¾ãã¾ãã ãã®1ã¤ããSpanã®éãå¿ãé »çºã«ããã¡ã¢ãªãªã¼ã¯ã§ãã åºæ¬çã« try-with-resources ãããã¯ã使ã£ã¦ããã°åé¡ãªãã¯ãã§ãããã
Span (ã¹ãã³å) is GC'ed without being ended.
OpenCensus-Javaã®å ´åãä¸è¨ã®ã¨ã©ã¼ãã°ãåºåãããå ´åãã©ããã«Closeã®ãå¿ããããã¾ãã ãã®ã±ã¼ã¹ã§ã¯GCããã¦ããã®ã§ã»ã¼ãã§ãããCloseãæ¼ãã¦ããã®ã¯ç¢ºããªã®ã§ãæ½°ãã¦ãããæ¹ãããããã§ãã
CloseableHttpClient httpClient = HttpClientBuilder.create() .addInterceptorFirst((HttpRequestInterceptor) M3TracingHttpInterceptor.INSTANCE) .addInterceptorLast((HttpResponseInterceptor) M3TracingHttpInterceptor.INSTANCE) .build();
ä¾ãã°ãåè¿°ããä¸è¨ã®ã³ã¼ãã«ã¯ãå®ã¯ãã°ãããã¾ãã ã¨ããã®ããApache HttpClientã§ã¯ãªã¯ã¨ã¹ãã®éä¿¡ä¸ã«ä¾å¤ãçºçããã¨ãHttpResponseInterceptorã¯å®è¡ããã¾ããããã®ããCloseãããæãã¾ãã
Webãã¬ã¼ã ã¯ã¼ã¯ã®å¶ç´ãªã©ã§ try-with-resources ã使ããªãã·ã¼ã³ã§Spanãä½æããå ´åã¯ãä¾å¤ãªã©ã§Closeã§ããªãã±ã¼ã¹ããªãããä»æ§ã確èªãã¾ãããã setRetryHandlerã使ãã°ä¾å¤ã®çºçæãå¦çãæ¾ãã¾ãã
CloseableHttpClient httpClient = HttpClientBuilder.create() .addInterceptorFirst((HttpRequestInterceptor) M3TracingHttpInterceptor.INSTANCE) .addInterceptorLast((HttpResponseInterceptor) M3TracingHttpInterceptor.INSTANCE) .setRetryHandler(new M3TracingHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler())) .build();
ã¾ã¨ã
é常ã«ç°¡åã«ã§ãããCloudTraceã使ã£ã¦ãã¦å¾ãç¥è¦ã¨ãéçºãã m3-tracingã«ã¤ãã¦ç´¹ä»ããã¦ããã ãã¾ããã
ä»å¾ã¯æ°ããè¦æ ¼ã§ããOpenTelemetryãGAããåæ£ãã¬ã¼ã·ã³ã°ã¯ã¾ãã¾ãçãä¸ãã£ã¦ããé åããªã¨æã£ã¦ãã¾ãã åæ£ãã¬ã¼ã·ã³ã°ã«ãã£ã¦èª²é¡ãçºè¦ã»è§£æ±ºã§ããä¾ã社å ã«å¢ãã¦ãã¾ããã®ã§ããããããæ´»ç¨ã»å¿ç¨ãé²ãã¦ããããã§ãã
We are Hiring!
ã¨ã ã¹ãªã¼ã§ã¯ããã¼ã¿ãç¨ãã¦ä¾¡å¤ãçã¿åºãããã¨ã³ã¸ãã¢ãåºãåéä¸ã§ãã
ãã¼ã¿åºç¤ã®ç®¡çã®ã¿ãªããããã®åºç¤ã使ã£ãã·ã¹ãã ã®éçºãæ½çã®å®ç¾ãªã©åºæ¥ããã¨ãããããããã¾ãããããããã°ãã²ä»¥ä¸ããå¿åãæ¤è¨ãã¦ã¿ã¦ä¸ãã!
*1:å¾ç¶ã®æ°è¦æ ¼ã«OpenTelemetryãããã¾ããCloudTraceã«ã¦ãJavaã§ã¯ã¾ã OpenCensusãæ¨å¥¨ã¯ã©ã¤ã¢ã³ãã©ã¤ãã©ãªã®ãããOpenCenesusãå©ç¨ãã¦ãã¾ã
*2:å¦çã®1åä½ãããå¦çã®éå§ããçµäºã¾ã§ã«çºçããSpanããããªã¼æ§é ã§ã¾ã¨ãããã®ãTraceã¨ãªã
*3:OpenCensusã§ã¯ããªã¯ã¨ã¹ãã®éä¿¡æã«traceparentã¨ããHTTPãããã«ç¾å¨ã®Spanæ å ±ãã»ãããããã¨ã§ãç°ãªããµã¼ãã¹éã§Spanã®è¦ªåé¢ä¿ãç¶æãã¾ããéä¿¡å´ã¯traceparentã®ä½æãåä¿¡å´ã¯traceparentã®è§£æãå¿ è¦ã§ãã