
@ZipkinProject
ã賌èªããŠãã
@ZipkinProject
ã
ãããŠããªããã®åæ£ãã¬ãŒã¹ïŒ
ãã¬ãŒã¹ãåéããããšã«ãããéçºè ã¯åæ£ã·ã¹ãã ã§ç¹å®ã®ã¯ãšãªãã©ã®ããã«å®è¡ããããã«ã€ããŠããæ·±ãç¥èãåŸãããšãã§ããŸãã ããšãã°ãã¿ã€ã ã¢ãŠããè¶ ãããªã©ããŠãŒã¶ãŒãªã¯ãšã¹ãã«åé¡ããããšããŸãã 倱æãããªã¯ãšã¹ãã®ãã¬ãŒã¹ã衚瀺ããŠãWebã€ã³ã¿ãŒãã§ãŒã¹ã«è¡šç€ºã§ããŸãã äºæãã¬å¿çæéã®å¢å ã«ããããµãŒãã¹ã®æ眪ããã°ããèŠã€ããããšãã§ããŸãã ãµãŒãã¹ã«è©³çŽ°ãªæ³šéãä»ããããŠããå Žåãåé¡ãçºçãããµãŒãã¹ã®å ŽæãèŠã€ããããšãã§ããŸãã

建ç¯
ãããã®ã³ã³ããŒãã³ãã¯ãå®å šãªãã¬ãŒã¹ã·ã¹ãã ãæ§æããŸãã

ããŒã«ã©ã€ãã©ãª
ãã¬ãŒã¹æ å ±ã¯ãZipkinã䜿çšããŠããŒãã«èªå°ããããŒã«ã©ã€ãã©ãªã䜿çšããŠãåããŒãã§åéãããŸãã ãã¹ããå¥ã®ãµãŒãã¹ã«ãªã¯ãšã¹ããè¡ããšããªã¯ãšã¹ããšãšãã«ããã€ãã®ãã¬ãŒã¹èå¥åãæž¡ããããããåŸã§ãã®ããŒã¿ããªã³ã¯ã§ããŸãã

ãã£ãã°ã«
Finagleã¯ãJavaãScalaããŸãã¯JVMã䜿çšããä»ã®èšèªã§éåæã¯ã©ã€ã¢ã³ãããã³ãªã¢ãŒãããã·ãŒãžã£ã³ãŒã«ïŒRPCïŒãµãŒããŒãäœæããããã«äœ¿çšã§ããJVMã®éåæãããã¯ãŒã¯ã¹ã¿ãã¯ã§ãã
Finagle㯠Twitterå ã§ç©æ¥µçã«äœ¿çšãããŠããããããã¬ãŒã¹ãµããŒãã®æ確ãªåºçºç¹ã«ãªã£ãŠããŸãã ãããŸã§ã®ãšãããThriftãšHTTPããµããŒãããã¯ã©ã€ã¢ã³ã/ãµãŒããŒãšãMemcacheãšRedisã®ã¿ããµããŒãããã¯ã©ã€ã¢ã³ãããããŸãã
Scalaã§FinagleãµãŒããŒãã»ããã¢ããããã«ã¯ã次ã®æé ã«åŸã£ãŠãã ããã ãã¬ãŒã¹ã®è¿œå ã¯ã finagle-zipkinäŸåé¢ä¿ãè¿œå ãã
ServerBuilder
tracer
ã
ServerBuilder
ã§ãã
ServerBuilder() .codec(ThriftServerFramedCodec()) .bindTo(serverAddr) .name("servicename") .tracer(ZipkinTracer.mk()) .build(new SomeService.FinagledService(queryService, new TBinaryProtocol.Factory()))
ã¯ã©ã€ã¢ã³ãã®ãã¬ãŒã¹èšå®ãåæ§ã§ãã äžèšã®ããã«Zipkinãã¬ãŒãµãŒãèšå®ãããšãããäžéšã®ãªã¯ãšã¹ããèªåçã«ã«ãŒãã£ã³ã°ãããŸãã ãªã¯ãšã¹ãã®éå§æãçµäºæãããã³ãªã¯ãšã¹ãã«é¢ä¿ãããµãŒãã¹ãšãã¹ããèšé²ããŸãã
è¿œå æ å ±ãèšé²ããå Žåã¯ãã³ãŒãã«ã«ã¹ã¿ã ã¡ã¢ãè¿œå ã§ããŸãã
Trace.record("starting that extremely expensive computation");
äžèšã®äŸã§ã¯ãã©ã€ã³ããŒããå®è¡ãããæç¹ã«æ·»ä»ãããŸãã ããŒå€ã§ã¡ã¢ãè¿œå ããããšãã§ããŸãã 次ã®ããã«ãªããŸãã
Trace.recordBinary("http.response.code", "500");
ã«ããŒã¹ãªãã
ããã¯ããªã¯ãšã¹ãããã¬ãŒã¹ããããã«äœ¿çšããgemã§ãã ãã¬ãŒãµãŒãåã蟌ã¿ããã¬ãŒã¹ãªã¯ãšã¹ãèå¥åãçæããã«ã¯ãRackHandlerã§ãã®gemã䜿çšã§ããŸãã ãã¬ãŒãµãŒã远跡ããzipkin-webã®äŸãåç §ããŠãã ããã
Rubyã³ãŒãããã®åŒã³åºãã远跡ããã«ã¯ã Ruby Thrift Twitterã¯ã©ã€ã¢ã³ãã䜿çšããŸãã ã¯ã©ã€ã¢ã³ãã®äœ¿çšæ¹æ³ã®äŸã以äžã«ç€ºããŸãã
client = ThriftClient.new(SomeService::Client, "127.0.0.1:1234") client_id = FinagleThrift::ClientId.new(:name => "service_example.sample_environment") FinagleThrift.enable_tracing!(client, client_id), "service_name")
çŽ æŽããã
Querulousã¯ãããŒã¿ããŒã¹ãšå¯Ÿè©±ããããã®Scalaã©ã€ãã©ãªã§ãã èŠæ±ã®ã¿ã€ãã³ã°ãšSQLã®å®è¡ã®è¿œè·¡ãå«ãŸããŸãã
ãã£ã·ãŒ
Cassieã¯ãCassandraçšã®FinagleããŒã¹ã®ã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªã§ãã Cassieã®ãã¬ãŒãµãŒã®æ§æã¯Finagleãšã»ãŒåãã§ãããCassieã®å Žåã¯KeyspaceBuilderã䜿çšãããŸãã
cluster.keyspace(keyspace).tracer(ZipkinTracer.mk());
茞é
Scribeã䜿çšããŠããã¹ãŠã®ãã¬ãŒã¹ãããŸããŸãªãµãŒãã¹ããZipkinããã³Hadoopã«è»¢éããŸãã Scribeã¯Facebookã§éçºãããã·ã¹ãã äžã®ãã¹ãŠã®ãµãŒããŒã§å®è¡ã§ããããŒã¢ã³ã§æ§æãããŠããŸãã ã¡ãã»ãŒãžãã°ãã¹ãã£ã³ããã«ããŽãªã«å¿ããŠæ£ãããµãŒãã¹ã¬ã·ãŒããŒã«éä¿¡ããŸãã
ãžããã³ã³ã¬ã¯ã¿ãŒããŒã¢ã³
ãã¬ãŒã¹ããŒã¿ãã³ã¬ã¯ã¿ããŒã¢ã³ã«å°çãããšããã«ããã®æ£ç¢ºæ§ã確èªããæ€çŽ¢çšã®ã€ã³ããã¯ã¹ãä¿åããŠæ§ç¯ããŸãã
ä¿ç®¡
Cassandraã䜿çšããŠããŒã¿ãä¿åããŸãã ã¹ã±ãŒã©ãã«ã§æè»æ§ããããTwitterã§é »ç¹ã«äœ¿çšãããŠããŸãã ãã®ã³ã³ããŒãã³ããã¢ãžã¥ãŒã«åããããšããã®ã§ãä»ã®ãã®ã«çœ®ãæããã®ã¯é£ãããªãã¯ãã§ãã
ãªã¯ãšã¹ãããŒã¢ã³
ããŒã¿ãèšé²ãããã€ã³ããã¯ã¹ãäœæããããããããååŸãã䟿å©ãªæ¹æ³ãå¿ èŠã§ãã ããã§ã¯ã¯ãšãªããŒã¢ã³ã䟿å©ã§ããŠãŒã¶ãŒã¯åçŽãªThrift APIã䜿çšããŠãã¬ãŒã¹ãæ€çŽ¢ããã³ååŸã§ããŸãã Thriftãã¡ã€ã«ã®äŸãåç §ããŠãã ããã
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹
ãŠãŒã¶ãŒã®ã»ãšãã©ã¯ãUIãä»ããŠããŒã¿ã«ã¢ã¯ã»ã¹ããŸãã ããã¯ã D3ã䜿çšããŠãã¬ãŒã¹ããŒã¿ãèŠèŠåããRailsã¢ããªã±ãŒã·ã§ã³ã§ãã ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã«ã¯èªèšŒæ©èœãçµã¿èŸŒãŸããŠããªãããšã«æ³šæããŠãã ããã
ã¢ãžã¥ãŒã«

èšçœ®
ããã«æ £ããã«ã¯ã Ubuntuã¯ã€ãã¯ã¹ã¿ãŒãããã³Macã¯ã€ãã¯ã¹ã¿ãŒããã¥ãŒããªã¢ã«ãã芧ãã ãã ã Zipkinã1å°ã®ã³ã³ãã¥ãŒã¿ãŒã§å®è¡ããŠãZipkinãè©Šãããšãã§ããŸãã
ã«ã¹ã¿ãã€ãºã«ã€ããŠå°ãã
ã«ãµã³ãã©
Zipkinã¯ãCassandraãšçµã¿åãããŠæããã䜿çšãããŸãã Redisçšã®ãã©ã°ã€ã³ããããŸããä»ã®ããŒã¿ããŒã¹ã®ãµããŒããåžæããŸãã
- ã¯ã©ã¹ã¿ãŒã®èµ·åæ¹æ³ã«ã€ããŠã¯ã Cassandra Webãµã€ãã«ã¢ã¯ã»ã¹ããŠãã ããã
- Zipkinã«é©åããåè·¯ã䜿çšããŸãã 次ã®
$ cassandra-cli -host localhost -port 9160 -f zipkin-cassandra/src/schema/cassandra-schema.txt
äœæã§ããŸãïŒ$ cassandra-cli -host localhost -port 9160 -f zipkin-cassandra/src/schema/cassandra-schema.txt
$ cassandra-cli -host localhost -port 9160 -f zipkin-cassandra/src/schema/cassandra-schema.txt
飌è²ä¿
Zipkinã¯ZooKeeperã䜿çšããŠèª¿æŽã§ããŸãã ããã§åç §å€ãä¿åãããµãŒããŒèªäœãç»é²ããŸãã
ã€ã³ã¹ããŒã«æé ã«ã€ããŠã¯ã ZooKeeper Webãµã€ãã«ã¢ã¯ã»ã¹ããŠãã ããã
ã¹ã¯ã©ã€ã
Scribeã¯ãTwitterã§ãã¬ãŒã¹ããŒã¿ã®ãã©ã³ã¹ããŒããšããŠäœ¿çšãããã®ã³ã°ãã¬ãŒã ã¯ãŒã¯ã§ãã Zipkinãã¬ãŒã¹ããŒã¿ãæž¡ãæ¹æ³ã¯ä»ã«ãããã€ããããŸãã ç¹ã«ãZipkinãè©ŠããŠã¿ããå Žåã¯ããã®æé ãå®å šã«ã¹ãããããŠãZipkinTracerãçŽæ¥Collectorã«è»¢éã§ããŸãã
Zipkinã§Scribeã䜿çšããã«ã¯ãã³ã¬ã¯ã¿ãŒããŒã¢ã³ã§æå®ããããããã¯ãŒã¯æ¥ç¶ã¹ãã¬ãŒãžãäœæããå¿ èŠããããŸãã Zipkinã§ã®ã¹ãã¬ãŒãžã®ã»ããã¢ããã¯æ¬¡ã®ããã«ãªããŸãã
<store> category=zipkin type=network remote_host=123.123.123.123 remote_port=9410 use_conn_pool=yes default_max_msg_before_reconnect=50000 allowable_delta_before_reconnect=12500 must_succeed=no </store>
ã³ã¬ã¯ã¿ã®IPã¢ãã¬ã¹ãããŒãã³ãŒãã£ã³ã°ããããªãå Žåã¯ãããã€ãã®ãªãã·ã§ã³ããããŸãã 1ã€ã¯ãã³ã¬ã¯ã¿ã«å éšDNSã¬ã³ãŒãã䜿çšããããšã§ãããã®ãããã³ã¬ã¯ã¿ãè¿œå ãŸãã¯åé€ãããšãã«ã¢ãã¬ã¹ãå€æŽããå¿ èŠããã1ã€ã®å ŽæããããŸãã ããã«ãScribeã®ä¿®æ£ããŒãžã§ã³ã䜿çšã§ããŸããããã¯ãZooKeeperãä»ããŠã³ã¬ã¯ã¿ãŒã®ã¢ãã¬ã¹ãååŸããŸãã ã³ã¬ã¯ã¿ãŒãèµ·åãããšãZooKeeperã«èªåèªèº«ãç»é²ããäœæ¥ãå®äºãããšèªåçã«åé€ãããŸãã å€æŽãããScribeã¯ãã³ã¬ã¯ã¿ãŒã§å€æŽãçºçãããšãã«éç¥ãåãåããŸãã ãã®ã¢ãŒããã¢ã¯ãã£ãã«ããã«ã¯ãæ§æå ã®
remote_host
ã«å€æŽããŸã
remote_host
zk://zookeeper-hostname:2181/scribe/zipkin
ãŸãã¯åæ§ã®ãã®ã
ZipkinãµãŒããŒ
Scala 2.9.1ãSBT 0.11.2ããã³JDK7ã§ZipkinãéçºããŸããã
Ubuntu Quickstartããã³Mac Quickstartã®ããã¥ã¢ã«ã§ã¯ãCollectorããã³QueryãµãŒãã¹ãã€ã³ã¹ããŒã«ããã³å®è¡ããæ¹æ³ã«ã€ããŠèª¬æããŠããŸãã
ãžããã³UI
UIã¯éåžžã®Rails 3ã¢ããªã±ãŒã·ã§ã³ã§ãã
- ZooKeeperãµãŒããŒæ§æãæŽæ°ããŸãã QueryããŒã¢ã³ã®æ€çŽ¢ã«äœ¿çšãããŸãã
- Railsã®äžã«é©åãªã¢ããªã±ãŒã·ã§ã³ãµãŒããŒããããã€ããŸãã ãã«ãã€ã³ã¯ãã¹ãã«ãé©ããŠããŸãïŒ
$ bundle install && bundle exec rails server
Gem Zipkin-tracerã¯ãRack Handlerãä»ããŠRailsã¢ããªã±ãŒã·ã§ã³ã«ãã¬ãŒã¹ãè¿œå ããŸãã config.ruã«è¿œå ããŸãã
use ZipkinTracer::RackHandler run <YOUR_APPLICATION>
Railsã¢ããªã±ãŒã·ã§ã³èªäœãéçã¢ã»ãããæäŸããå Žåããããã®ãªã¯ãšã¹ãã®ãã¬ãŒã¹ã¯ä¿åãããŸãã
Hadoopã§ã¿ã¹ã¯ãå®è¡ãã
Hadoopã«ããŒã¿ãä¿åããããã«Scribeãæ§æããããšãå¯èœã§ãã ãããè¡ããšãZipkinèªäœã§ãã®å Žã§ç°¡åã«åŠçã§ããªãããŒã¿ããããŸããŸãªã¬ããŒããäœæã§ããŸãã
Scaldingãšããã©ã€ãã©ãªã䜿çšããŠãScalaããHadoopã®ã¿ã¹ã¯ãæ§ç¯ããŸãã
- Hadoopã§ã¿ã¹ã¯ãéå§ããã«ã¯ãæåã«jarãäœæããå¿
èŠããããŸãã
$ sbt 'project zipkin-hadoop' compile assembly
- scald.rbã§ãjarã®ã³ããŒå ããŒãã®ååãå€æŽããã¿ã¹ã¯ãå®è¡ããŸãã
- å¿ èŠã«å¿ããŠãscald.rbã®jarããŒãžã§ã³ãæŽæ°ããŸãã
- ããã§ãscald.rbã¹ã¯ãªããã䜿çšããŠã¿ã¹ã¯ãå®è¡ã§ããŸãã
$ ./scald.rb --hdfs com.twitter.zipkin.hadoop.[classname] --date yyyy-mm-ddThh:mm yyyy-mm-ddThh:mm --output [dir]
ã©ã€ãã©ãªãæºåããæ¹æ³
ç§ãã¡ã¯ããã€ãã®ã©ã€ãã©ãªãšãããã³ã«ãç§ãã¡èªèº«ã«æ瀺ããŸãããããããã®æ°ãå¢ããã®ã«ããããã®å©ããåŸãããšããŸã æãã§ããŸãã å§ããåã«ããã¬ãŒã¹ããŒã¿ãã©ã®ããã«æ§æãããŠãããã«ã€ããŠããã€ãã®ããšãç¥ãå¿ èŠããããŸãã
- 泚é-ããã€ãã®å€ãã¿ã€ã ã¹ã¿ã³ããããŒãã¢ãã¬ã¹ãå«ãŸããŸãã
- ã¹ãã³-ç¹å®ã®RPCã«äžèŽãã泚éã®ã»ããã
- ãã¬ãŒã¹ã¯ãåäžã®ã«ãŒãã¹ãã³ãå ±æããã¹ãã³ã®ã»ããã§ãã
äžèšã¯ããã¬ãŒã¹ããŒã¿ãZipkinã«éä¿¡ãããšãã«äœ¿çšãããŸãã ããã€ãã®è©³çŽ°ãããã§èª¬æããŸã ã
ãã¬ãŒã¹ã®ãã1ã€ã®éèŠãªéšåã¯ããµãŒãã¹éã§æ å ±ã転éããããã«äœ¿çšãã軜éããããŒã§ãã ããããŒã®æ§æã¯æ¬¡ã®ãšããã§ãã
- ãã¬ãŒã¹ID-ãã¬ãŒã¹ãèå¥ããŸãã
- ã¹ãã³ID-åã ã®ãªã¯ãšã¹ãã®èå¥åã
- ãªãã·ã§ã³ã®èŠªã¹ãã³ID-ãã®èŠæ±ãå¥ã®èŠæ±ã®äžéšãšããŠè¡ãããå Žåã«è¿œå ãããŸãã
- ãµã³ãã«ïŒããŒã«åãã£ãŒã«ãïŒ-ãã¬ãŒã¹ããŒã¿ãä¿æãããã©ããã瀺ããŸãã
ããŒã¿åã«ã€ããŠå°ãç¥ã£ãã®ã§ãã€ã³ã¹ãã«ã¡ã³ããŒã·ã§ã³ãã©ã®ããã«æ©èœãããã段éçã«èŠãŠãããŸãããã 以äžã®äŸã§ã¯ãFinagleã§HTTPãã¬ãŒã¹ãã©ã®ããã«æ©èœãããã説æããŸãã ä»ã®ã©ã€ãã©ãªããããã³ã«ã®å Žåããã¡ããã¢ã¯ã·ã§ã³ã¯ç°ãªãå ŽåããããŸãããäžè¬çãªååã¯å€ãããŸããã
ãµãŒããŒåŽ
- çä¿¡èŠæ±ã®ãã¬ãŒã¹ããããŒã確èªããŸãã ãã®å Žåããã®ãªã¯ãšã¹ãã«é¢é£ä»ããããèå¥åãåãå ¥ããŸãã ããã§ãªãå Žåã¯ããã¬ãŒã¹IDãã¹ãã³IDãçæããããŒã¿ãä¿åãããã©ããã決å®ããŸãã äŸã«ã€ããŠã¯ã HttpServerTracingFilterãåç §ããŠãã ããã
- çŸåšã®ãªã¯ãšã¹ããéžæã«é¢ä¿ããŠããå ŽåããµãŒãã¹åããã¹ãåãååSpanïŒhttp get / putãªã©ïŒãªã©ã®æ å ±ãçŽæ¥åéããŸãã ãªã¯ãšã¹ããåãåã£ããšãã«ãserver receivedããšããã¡ã¢ãäœæããåŠçãå®äºããŠçµæãéä¿¡ãããšãã«ãserver sendããšããã¡ã¢ãäœæããŸãã ç¹°ãè¿ããŸããã HttpServerTracingFilterã§äŸãèŠãããšãã§ããŸãã
- çæããããã¬ãŒã¹ããŒã¿ã¯ãServerBuilderã§æå®ããããã¬ãŒãµãŒãªããžã§ã¯ãã«æž¡ãããŸãã ããšãã°ãConsoleTracerã®å ŽåããããŸããããã®å Žåã¯ZipkinTracerã䜿çšãããŸãã ZipkinTracerã¯ãã¬ãŒã¹ããŒã¿ãåä¿¡ãããšãããããã¹ãã³IDã§ã°ã«ãŒãåããŸãã
- ZipkinTracerã¯ãããµãŒããŒãåä¿¡ãããã¡ã¢ãã¿ã€ã ã¢ãŠããªã©ã®ãã¹ãã³ã®çµãããã€ãã³ããåä¿¡ãããšããã«ãThriftæ§é ã®åœ¢åŒã§éèšããŒã¿ãScribeã«éä¿¡ããŸãã ãã®ãããªã€ãã³ããçºçããªãå Žåã§ããããŒã¿ã¯éä¿¡ãããŸãã ä»ã®ããŒã¿é ä¿¡æ¹æ³ãè¿œå ããããšãã§ããŸãããThriftãšScribeã¯çã«ããªã£ãŠããŸãããå Žåã«ãã£ãŠã¯JSONãšHttpã®æ¹ãããŸããããããããŸããã
ã¯ã©ã€ã¢ã³ãåŽ
- ãªã¯ãšã¹ããå®è¡ããåã«ããã§ã«ãã¬ãŒã¹ã«åå ããŠãããã©ããã確èªããŠãã ããã ãã¶ãããã®ã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒå ã§äœ¿çšããããã¬ãŒã¹IDã¯ãã§ã«å²ãåœãŠãããŠããŸãã ãã®Trace idãåå©çšããŸãããæ°ãããªã¯ãšã¹ãã«å¯ŸããŠæ°ããSpan IdãäœæããŸãã ãŸãã以åã®ã¹ãã³ã®èŠªã¹ãã³IDãããã°ã€ã³ã¹ããŒã«ããŸãã ãããšããã®ããã€ãã®äŸã
- ãµãŒããŒåŽã®ãªãã·ã§ã³ãšåæ§ã«ãçºä¿¡HttpèŠæ±ã«ãã¬ãŒã¹ããããŒãè¿œå ããHttpClientTracingFilterããããŸãã
- ãŸãããªã¯ãšã¹ãã®åã«ãã¯ã©ã€ã¢ã³ãéä¿¡ãããµãŒããŒããå¿çãåä¿¡ããåŸã«ãã¯ã©ã€ã¢ã³ãåä¿¡ããªã©ã®é©åãªã¡ã¢ãäœæããå¿ èŠããããŸãã
- ãµãŒããŒããŒãžã§ã³ãšåæ§ã«ãããŒã¿ã¯ZipkinTracerã«ãã£ãŠéä¿¡ãããZipkinã«éä¿¡ãããŸãã