「Java分享客棧」隨時用隨時翻:微服務鏈路追蹤之zipkin搭建

来源:https://www.cnblogs.com/fulongyuanjushi/archive/2022/05/20/16292756.html
-Advertisement-
Play Games

前言 微服務治理方案中,鏈路追蹤是必修課,SpringCloud的組件其實使用很簡單,生產環境中真正令人頭疼的往往是軟體維護,介面在微服務間的調用究竟哪個環節出現了問題,哪個環節耗時較長,這都是項目上線後一定會遇到的問題,為瞭解決這些問題鏈路追蹤便應運而生了。 主流方案 1)、SkyWalking: ...


前言

微服務治理方案中,鏈路追蹤是必修課,SpringCloud的組件其實使用很簡單,生產環境中真正令人頭疼的往往是軟體維護,介面在微服務間的調用究竟哪個環節出現了問題,哪個環節耗時較長,這都是項目上線後一定會遇到的問題,為瞭解決這些問題鏈路追蹤便應運而生了。


主流方案

1)、SkyWalking:這應該是目前最主流的方案了,我所在公司今年的新項目就開始使用這個,效果確實很顯著,功能強大,最重要還是國產的,後面不用看了我們支持國產吧!開個玩笑哈哈,其實這個框架也有缺點,就是稍微有點重,比較適合稍大一點的項目,但可預見後面幾年都是最受歡迎的方案;

2)、Zipkin:這個是老牌鏈路追蹤方案,已經被非常多項目驗證過實用性,相比較於SkyWalking,我個人更喜歡這個框架,因為更輕量級,安裝也非常簡單,是中小規模的微服務項目首選方案。


用法

1、zipkin環境搭建

官方提供了docker版本,十分簡單。也可以下載編譯好的zipkin.jar來運行,是springboot項目。

官網:https://zipkin.io/pages/quickstart.html

1)、啟動

預設埠號啟動zipkin服務,預設埠9411.

java -jar zipkin.jar

2)、指定埠號

java -jar zipkin.jar --server.port=8080

3)、指定訪問RabbitMQ

java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=127.0.0.1

4)、啟動效果

111.png


2、SpringCloud整合zipkin

springcloud其它基礎依賴包引入這裡省略,直接模擬場景。

會員服務:zipkin_member

訂單服務:zipkin_order

消息服務:zipkin_msg

過程:會員服務調用訂單服務,訂單服務調用消息服務。

1)、引入依賴
<!-- zipkin -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
2)、application.yml配置

註意事項:

a)、加上服務名,RestTemplate調用時會用到;

b)、加上zipkin服務端地址;

c)、加上probability採集率設置,預設0.1,測試環境改為1.0保證每次都採集,生產環境適當抽樣即可。(因為10000個請求抽樣1000個也能發現問題了,沒必要全部都採集)

222.png

3)、引入RestTemplate

這裡restTemplate主要用來進行介面調用查看鏈路追蹤是否生效

@Component
public class RestTemplateConfig {
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
4)、controller調用

會員調用訂單

333.png

訂單調用消息

444.png

消息處理具體業務

555.png

5)、查看效果

啟動Zipkin服務端,訪問:http://127.0.0.1:9411

666.png

執行controller介面

777.png

查看鏈路追蹤,可以看到,介面調用的鏈路已經在zipkin顯現了。

888.png

999.png


3、zipkin整合RabbitMQ非同步採集

springboot2.0之後,官方不再推薦使用自建的zipkin server,而是直接使用編譯好的zipkin.jar來給我們使用。

zipkin.jar中的yml配置可以參考:https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

1)、指定RabbitMQ為伺服器

啟動zipkin服務時指定rabbitmq為伺服器即可,得先啟動rabbitmq伺服器。

java -jar zipkin.jar --zipkin.collector.rabbitmq.addresses=192.168.239.132

啟動之後,可以發現rabbitmq中會自動新增一個zipkin隊列,表示綁定成功。

1010.png

2)、引入中間依賴

給每個微服務引入stream和rabbitmq的中間件依賴

<!-- 引入和rabbitmq的中間依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
3)、yml配置

修改每個微服務的application.yml,加上rabbitmq的配置。

rabbitmq: 
    host: 192.168.239.132
    port: 5672
    username: guest
    password: guest
4)、啟動和調用

啟動微服務,執行調用。

1111.png

5)、MQ是否收到消息

看rabbitmq是否有收消息,隊列有反應說明rabbitmq收到消息了。

1212png.png

6)、Zipkin是否採集信息

看zipkin是否採集了鏈路信息

1313.png

7)、驗證積壓消息

關掉zipkin服務,看消息是否會積壓在rabbitmq,再啟動zipkin服務,看消息是否會被消費並且獲取到鏈路信息。

1414.png

獲取消息查看,發現獲取到的就是traceId相關的json數據,證明整個過程都是正常的。

1515.png

重新再啟動zipkin服務,發現rabbitmq積壓的消息就被消費了。

1616.png

並且也能獲取到鏈路信息

1717.png


4、zipkin使用MySQL存儲

zipkin.jar中的yml配置可以參考,裡面有關於mysql的配置或者其他如elasticsearch的配置:

https://github.com/openzipkin/zipkin/blob/master/zipkin-server/src/main/resources/zipkin-server-shared.yml

這節我們在上一節MQ的基礎上增加MySQL的啟動配置項

1)、指定MySQL

命令看著很長,其實仔細看發現很簡單,都是見名知義,不必死記硬背。

java -jar zipkin.jar

--zipkin.collector.rabbitmq.addresses=192.168.239.132

--zipkin.storage.type=mysql

--zipkin.storage.mysql.host=127.0.0.1

--zipkin.storage.mysql.port=3306

--zipkin.storage.mysql.username=root

--zipkin.storage.mysql.password=123456

--zipkin.storage.mysql.db=zipkin

2)、創建zipkin資料庫

根據1中命令配置的信息,創建zipkin資料庫,並執行語句創建zipkin採集記錄的三張表。

參考官網:https://github.com/apache/incubator-zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

這裡我也貼出來 zipkin-mysql.sql

1818.png

CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL,
  `id` BIGINT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `remote_service_name` VARCHAR(255),
  `parent_id` BIGINT,
  `debug` BIT(1),
  `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';

CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` VARCHAR(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` BLOB COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` INT NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';

CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL,
  `parent` VARCHAR(255) NOT NULL,
  `child` VARCHAR(255) NOT NULL,
  `call_count` BIGINT,
  `error_count` BIGINT,
  PRIMARY KEY (`day`, `parent`, `child`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;
3)、效果

啟動微服務,執行controller請求,看是否成功。

RabbitMQ

1919.png

zipkin

2020.png

MySQL

2121.png


至此,springcloud sleuth + zipkin + rabbitmq + mysql 就全部整合成功了!


總結

微服務的治理方案有很多,學習方向根據個人喜好決定,我的經驗就是不必盲目跟從這種用於輔助的方案,比如現在有SkyWalking,以後可能還有SkyFlying、SkySwimming。

走向高級軟體工程師都要有一個意識,就是在層出不窮的開源框架如雨後春筍般出現的時候,你得有信心用到哪個花點時間就能自己搭建起來,這才是提升自己的最有效方法。

一個項目使用什麼治理方案最重要的絕不是跟風,而是哪款最適合就用哪款,就像你找女朋友一樣,不單單是找漂亮的,而是找最能一起過日子的,否則就是貌合神離。


分享

本篇實際上是我8年多工作及學習過程中在雲筆記中記錄的內容之一,其實還有很多我閑暇之餘都做了下整理,有感興趣的朋友可以私信我獲取,什麼時候用到了翻開說不定就能節省很多時間。



本人原創文章純手打,專註於分享主流技術及實際工作經驗,覺得有一滴滴幫助的話就請點個推薦吧!


喜歡就點一下推薦吧~~
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. Netty源碼研究筆記(2)——Bootstrap系列 顧名思義,Bootstrap是netty提供給使用者的腳手架,類似於Spring的ApplicationContext,通過Bootstrap我們使用一些自定義選項,將相關的組件打包起來,從而快速的啟動伺服器、客戶端。 Bootstrap ...
  • ZooKeeper知識點總結 一、ZooKeeper 的工作機制 二、ZooKeeper 中的 ZAB 協議 三、數據模型與監聽器 四、ZooKeeper 的選舉機制和流程 本文將以如下內容為主線講解ZooKeeper中的學習重點,包括 ZooKeeper 中的角色、ZAB協議、數據模型、選舉機制、 ...
  • 現在驗證碼登錄已經成為很多應用的主流登錄方式,但是對於OAuth2授權來說,手機號驗證碼處理用戶認證就非常繁瑣,很多同學卻不知道怎麼接入。 認真研究胖哥Spring Security OAuth2專欄的都會知道一個事,OAuth2其實不管資源擁有者是如何認證的,只要資源擁有者在授權的環節中認證了就可 ...
  • 來源:csdn.net/xiaojin21cen/article/details/78587425 ZeroC ICE的Java版,Netty2作者的後續之作Apache MINA,Crmky的Cindy之外,還有個超簡單的QuickServer,讓你專心編寫自己的業務代碼,不用編寫一行TCP代碼。 ...
  • 1.創建線程池相關參數 線程池的創建要用ThreadPoolExecutor類的構造方法自定義創建,禁止用Executors的靜態方法創建線程池,防止記憶體溢出和創建過多線程消耗資源。 corePoolSize: 線程池核心線程數量,不會自動銷毀,除非設置了參數allowCoreThreadTimeO ...
  • 我們在上一篇博客中介紹了Linux系統Shell命令行下可執行程式應該遵守的傳參規範(包括了各種選項及其參數)。Python命令行程式做為其中一種,其傳參中也包括了位置參數(positional和可選參數(optional)。Python程式中我們解析在命令行中提供的各種選項(選項保存在sys.ar... ...
  • 1. Netty源碼研究筆記(1)——開篇 1.1. Netty介紹 Netty是一個老牌的高性能網路框架。在眾多開源框架中都有它的身影,比如:grpc、dubbo、seata等。 裡面有著非常多值得學的東西: I/O模型 記憶體管理 各種網路協議的實現:http、redis、websocket等等 ...
  • Kafka 簡介 Kafka 是一種高吞吐、分散式、基於發佈和訂閱模型的消息系統,最初是由 LinkedIn 公司採用 Scala 和 java 開發的開源流處理軟體平臺,目前是 Apache 的開源項目。 Kafka 用於離線和線上消息的消費,將消息數據按順序保存在磁碟上,併在集群內以副本的形式存 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文將以 C# 語言來實現一個簡單的布隆過濾器,為簡化說明,設計得很簡單,僅供學習使用。 感謝@時總百忙之中的指導。 布隆過濾器簡介 布隆過濾器(Bloom filter)是一種特殊的 Hash Table,能夠以較小的存儲空間較快地判斷出數據是否存在。常用於允許一定誤判率的數據過濾及防止緩存 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 「簡單有價值的事情長期堅持做」 這是成功最簡單,但也最難學的秘訣。不經過訓練,人很難意識到時間複利的威力。 仙劍奇俠傳的「十里坡劍神」和金庸群俠傳的「十級野球拳」,就是簡單的事情持之以恆反覆做,最後就有巨大的威力 唐家三少成為網文收入第一,最重要的一步是十四年從未斷日更 這樣的案例很多,一開始可能成 ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“我愛加班”。 面試開始,直入正題。 面試官: 看你簡歷上面寫著精通MySQL,我先問你事務的特性是什麼? 老生常談,這個還有誰不會背的嗎? 我: ...
  • 基礎知識 python是一門腳本語言,它是解釋執行的。 python使用縮進做為語法,而且python2環境下同一個py文件中不能同時存在tab和空格縮進,否則會出錯,建議在IDE中顯示縮進符。 python在聲明變數時不寫數據類型,可以type(xx)來獲取欄位的類型,然後可以int(),list ...
  • 為什麼要多線程下載 俗話說要以終為始,那麼我們首先要明確多線程下載的目標是什麼,不外乎是為了更快的下載文件。那麼問題來了,多線程下載文件相比於單線程是不是更快? 對於這個問題可以看下圖。 橫坐標是線程數,縱坐標是使用對應線程數下載對應文件時花費的時間,藍橙綠代表下載文件的大小,每個線程下載對應文件2 ...
  • 詳細講解python爬蟲代碼,爬微博搜索結果的博文數據。 爬取欄位: 頁碼、微博id、微博bid、微博作者、發佈時間、微博內容、轉發數、評論數、點贊數。 爬蟲技術: 1、requests 發送請求 2、datetime 時間格式轉換 3、jsonpath 快速解析json數據 4、re 正則表達式提... ...
  • 背景: 一般我們可以用HashMap做本地緩存,但是HashMap功能比較弱,不支持Key過期,不支持數據範圍查找等。故在此實現了一個簡易的本地緩存,取名叫fastmap。 功能: 1.支持數據過期 2.支持等值查找 3.支持範圍查找 4.支持key排序 實現思路: 1.等值查找採用HashMap2 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • 本章是系列文章的第八章,用著色演算法進行寄存器的分配過程。 本文中的所有內容來自學習DCC888的學習筆記或者自己理解的整理,如需轉載請註明出處。周榮華@燧原科技 寄存器分配 寄存器分配是為程式處理的值找到存儲位置的問題 這些值可以存放到寄存器,也可以存放在記憶體中 寄存器更快,但數量有限 記憶體很多,但 ...