Spring Cloud 應用篇 之 Spring Cloud Sleuth + Zipkin(三)修改資料儲存方式
(一)簡介
預設情況下,Zipkin Server 會將跟蹤資訊儲存在記憶體中,每次重啟 Zipkin Server 都會使之前收集的跟蹤資訊丟失,並且當有大量跟蹤資訊時,記憶體儲存也會造成效能瓶頸,所以通常我們都需要將跟蹤資訊儲存到外部元件中,如 Mysql。
由於 Spring Boot 2.0 之後 Zipkin 不再推薦我們來自定義 Server 端了,那麼如何把 Zipkin Server 修改為 Mysql 儲存功能呢?答案還是和整合 RabbitMQ 一樣,在啟動 zipkin.jar 的時候,配置相關引數
(二)配置 zipkin server
2.1 建立資料庫、表資訊
既然資料儲存改為 Mysql,那麼肯定要建立相關的表,建表的指令碼檔案 mysql.sql 在 GitHub 官方地址能查到,連結如下:
這裡會建立三張表,如下,具體表結構資訊,大家可以自己檢視
2.2 啟動 zipkin
zipkin.jar 的 配置檔案內容可以檢視 GitHub 上官方的提供
為了方便,我在這裡展示部分內容:
- zipkin:
- collector:
- rabbitmq:
- # RabbitMQ server address list (comma-separated list of host:port)
- addresses: ${<span class="hljs-symbol"><span class="hljs-symbol">RABBIT_ADDRESSES:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">concurrency:</span></span> ${RABBIT_CONCURRENCY:
1} - # TCP connection timeout in milliseconds
- connection-timeout: ${<span class="hljs-symbol"><span class="hljs-symbol">RABBIT_CONNECTION_TIMEOUT:</span></span><span class="hljs-number"><span class="hljs-number">60000</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">password:</span></span> ${RABBIT_PASSWORD:
guest} - queue: ${<span class="hljs-symbol"><span class="hljs-symbol">RABBIT_QUEUE:</span></span>zipkin}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">username:</span></span> ${RABBIT_USER:guest}
- virtual-host: ${<span class="hljs-symbol"><span class="hljs-symbol">RABBIT_VIRTUAL_HOST:</span></span>/}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">useSsl:</span></span> ${RABBIT_USE_SSL:false}
- uri: ${<span class="hljs-symbol"><span class="hljs-symbol">RABBIT_URI:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">storage:</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> strict-trace-<span class="hljs-symbol"><span class="hljs-symbol">id:</span></span> ${STRICT_TRACE_ID:true}
- search-enabled: ${<span class="hljs-symbol"><span class="hljs-symbol">SEARCH_ENABLED:</span></span><span class="hljs-literal"><span class="hljs-literal">true</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">type:</span></span> ${STORAGE_TYPE:mem}
- mem:
- # Maximum number of spans to keep in memory. When exceeded, oldest traces (and their spans) will be purged.
- # A safe estimate is 1K of memory per span (each span with 2 annotations + 1 binary annotation), plus
- # 100 MB for a safety buffer. You’ll need to verify in your own environment.
- # Experimentally, it works with: max-spans of 500000 with JRE argument -Xmx600m.
- max-spans: 500000
- cassandra:
- # Comma separated list of host addresses part of Cassandra cluster. Ports default to 9042 but you can also specify a custom port with ‘host:port’.
- contact-points: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_CONTACT_POINTS:</span></span>localhost}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="28"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Name of the datacenter that will be considered "local" for latency load balancing. When unset, load-balancing is round-robin.</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> local-<span class="hljs-symbol"><span class="hljs-symbol">dc:</span></span> ${CASSANDRA_LOCAL_DC:}
- # Will throw an exception on startup if authentication fails.
- username: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_USERNAME:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="32"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">password:</span></span> ${CASSANDRA_PASSWORD:}
- keyspace: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_KEYSPACE:</span></span>zipkin}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="34"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Max pooled connections per datacenter-local host.</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> max-<span class="hljs-symbol"><span class="hljs-symbol">connections:</span></span> ${CASSANDRA_MAX_CONNECTIONS:8}
- # Ensuring that schema exists, if enabled tries to execute script /zipkin-cassandra-core/resources/cassandra-schema-cql3.txt.
- ensure-schema: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_ENSURE_SCHEMA:</span></span><span class="hljs-literal"><span class="hljs-literal">true</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="38"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># 7 days in seconds</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="39"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> span-<span class="hljs-symbol"><span class="hljs-symbol">ttl:</span></span> ${CASSANDRA_SPAN_TTL:604800}
- # 3 days in seconds
- index-ttl: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_INDEX_TTL:</span></span><span class="hljs-number"><span class="hljs-number">259200</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="42"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># the maximum trace index metadata entries to cache</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="43"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> index-cache-<span class="hljs-symbol"><span class="hljs-symbol">max:</span></span> ${CASSANDRA_INDEX_CACHE_MAX:100000}
- # how long to cache index metadata about a trace. 1 minute in seconds
- index-cache-ttl: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_INDEX_CACHE_TTL:</span></span><span class="hljs-number"><span class="hljs-number">60</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="46"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># how many more index rows to fetch than the user-supplied query limit</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="47"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> index-fetch-<span class="hljs-symbol"><span class="hljs-symbol">multiplier:</span></span> ${CASSANDRA_INDEX_FETCH_MULTIPLIER:3}
- # Using ssl for connection, rely on Keystore
- use-ssl: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_USE_SSL:</span></span><span class="hljs-literal"><span class="hljs-literal">false</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="50"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">cassandra3:</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="51"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Comma separated list of host addresses part of Cassandra cluster. Ports default to 9042 but you can also specify a custom port with 'host:port'.</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="52"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> contact-<span class="hljs-symbol"><span class="hljs-symbol">points:</span></span> ${CASSANDRA_CONTACT_POINTS:localhost}
- # Name of the datacenter that will be considered “local” for latency load balancing. When unset, load-balancing is round-robin.
- local-dc: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_LOCAL_DC:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="55"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Will throw an exception on startup if authentication fails.</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="56"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">username:</span></span> ${CASSANDRA_USERNAME:}
- password: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_PASSWORD:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="58"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">keyspace:</span></span> ${CASSANDRA_KEYSPACE:zipkin2}
- # Max pooled connections per datacenter-local host.
- max-connections: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_MAX_CONNECTIONS:</span></span><span class="hljs-number"><span class="hljs-number">8</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="61"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Ensuring that schema exists, if enabled tries to execute script /zipkin2-schema.cql</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="62"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword"><span class="hljs-keyword">ensure</span></span>-<span class="hljs-symbol"><span class="hljs-symbol">schema:</span></span> ${CASSANDRA_ENSURE_SCHEMA:true}
- # how many more index rows to fetch than the user-supplied query limit
- index-fetch-multiplier: ${<span class="hljs-symbol"><span class="hljs-symbol">CASSANDRA_INDEX_FETCH_MULTIPLIER:</span></span><span class="hljs-number"><span class="hljs-number">3</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="65"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-comment"><span class="hljs-comment"># Using ssl for connection, rely on Keystore</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="66"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> use-<span class="hljs-symbol"><span class="hljs-symbol">ssl:</span></span> ${CASSANDRA_USE_SSL:false}
- elasticsearch:
- # host is left unset intentionally, to defer the decision
- hosts: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_HOSTS:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="70"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">pipeline:</span></span> ${ES_PIPELINE:}
- max-requests: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_MAX_REQUESTS:</span></span><span class="hljs-number"><span class="hljs-number">64</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="72"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">timeout:</span></span> ${ES_TIMEOUT:10000}
- index: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_INDEX:</span></span>zipkin}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="74"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> date-<span class="hljs-symbol"><span class="hljs-symbol">separator:</span></span> ${ES_DATE_SEPARATOR:-}
- index-shards: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_INDEX_SHARDS:</span></span><span class="hljs-number"><span class="hljs-number">5</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="76"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> index-<span class="hljs-symbol"><span class="hljs-symbol">replicas:</span></span> ${ES_INDEX_REPLICAS:1}
- username: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_USERNAME:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="78"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">password:</span></span> ${ES_PASSWORD:}
- http-logging: ${<span class="hljs-symbol"><span class="hljs-symbol">ES_HTTP_LOGGING:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="80"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> legacy-reads-<span class="hljs-symbol"><span class="hljs-symbol">enabled:</span></span> ${ES_LEGACY_READS_ENABLED:true}
- mysql:
- host: ${<span class="hljs-symbol"><span class="hljs-symbol">MYSQL_HOST:</span></span>localhost}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="83"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">port:</span></span> ${MYSQL_TCP_PORT:3306}
- username: ${<span class="hljs-symbol"><span class="hljs-symbol">MYSQL_USER:</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="85"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">password:</span></span> ${MYSQL_PASS:}
- db: ${<span class="hljs-symbol"><span class="hljs-symbol">MYSQL_DB:</span></span>zipkin}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="87"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> max-<span class="hljs-symbol"><span class="hljs-symbol">active:</span></span> ${MYSQL_MAX_CONNECTIONS:10}
- use-ssl: ${<span class="hljs-symbol"><span class="hljs-symbol">MYSQL_USE_SSL:</span></span><span class="hljs-literal"><span class="hljs-literal">false</span></span>}</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="89"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">ui:</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="90"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-symbol"><span class="hljs-symbol">enabled:</span></span> ${QUERY_ENABLED:true}
- ## Values below here are mapped to ZipkinUiProperties, served as /config.json
- # Default limit for Find Traces
- query-limit: 10
- # The value here becomes a label in the top-right corner
- environment:
- # Default duration to look back when finding traces.
- # Affects the “Start time” element in the UI. 1 hour in millis
- default-lookback: 3600000
- # When false, disables the “find a trace” screen
- search-enabled: ${SEARCH_ENABLED:true}
- # Which sites this Zipkin UI covers. Regex syntax. (e.g. http:\/\/example.com\/.*)
- # Multiple sites can be specified, e.g.
- # - .*example1.com
- # - .*example2.com
- # Default is “match all websites”
- instrumented: .*
- # URL placed into the <base> tag in the HTML
- base-path: /zipkin
從它的配置檔案可以看出,storage 預設採用的是記憶體儲存,所以我們要設定 zipkin.storage.type=mysql,除此之外還要設定 zipkin.storage.mysql.host、port、username、password、db 等
下面貼出我的啟動命令:
- java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=localhost --zipkin.storage.type=mysql
- --zipkin.storage.mysql.host=localhost --zipkin.storage.mysql.port=3306 --zipkin.storage.mysql.username=root
- --zipkin.storage.mysql.password=mysql --zipkin.storage.mysql.db=zipkin
大家可以根據自己的資料庫資訊,修改相關配置即可
(三)驗證
至於 Zipkin Client 端,是不需要相關修改的,按照上面命令啟動 zipkin 後,訪問 http://localhost:8481/service1,檢視資料庫資訊,表 zipkin_annotations 和表 zipkin_spans 中已經資料儲存了
表 zipkin_annotations :
表 zipkin_spans :
表中所儲存的資訊我們已經非常熟悉,之前分析的內容都可以在這兩張表中體現出來。
從 GitHub 的官方配置檔案中,我們可以看到,Zipkin 在儲存方面除了對 Mysql 有擴充套件元件之外,還實現了對 CassCassandra 和 ElasElasticSearch 的支援擴充套件,具體的整合方式與 Mysql 的整合類似。