運行環境
以下就是這個示例的運行環境,如果版本號不一樣,區別也應該不會很大,可以根據實際情況做相應調整。
- JDK 8
- spring boot 2.0.7.RELEASE
- cat-client 3.0.0
- apollo-client 1.3.0
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
去除Apollo對CAT的依賴
眾所周知,Apollo對CAT是有依賴的,但不是強依賴,而是使用了SPI技術,只有項目里引用了cat-client才會生效。目前我們想把CAT客戶端配置放在Apollo里,也就是在CAT客戶端初始化之前從Apollo讀取相應配置,這就形成了循環依賴,所以首先要去除Apollo對CAT客戶端的依賴。
查看Apollo客戶端的源碼,我發現有一個叫做MessageProducerManager
的接口,再看一下META-INF\services\com.ctrip.framework.apollo.tracer.spi.MessageProducerManager文件,發現這個接口的默認實現是DefaultMessageProducerManager
,如果發現CAT客戶端被引入時,這個類就會初始化CAT客戶端並向CAT客戶端發送消息。MessageProducerManager
接口還有另外一個實現,就是NullMessageProducerManager
類,這個類返回的是NullMessageProducer實例,任何消息都不發送。
想要去除CAT的依賴,在項目里使用NullMessageProducerManager
的實現就可以了。在META-INF\services\文件夾中創建如下文件:
com.ctrip.framework.apollo.tracer.spi.MessageProducerManager
並添加如下內容:
com.ctrip.framework.apollo.tracer.internals.NullMessageProducerManager
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
引入CAT客戶端
引入CAT客戶端時,我遇到的一個大坑,所以告誡大家:千萬不要使用源碼中cat-client打包出來的客戶端。因為源碼中的cat-client是舊代碼,已經不維護了。這里吐槽一下:不維護了為什么不馬上刪除,害的我讀了一個星期的舊代碼。最新的源碼在lib/java目錄下,可以自己用maven打包,或者在pom.xml添加Maven依賴:
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.0</version>
</dependency>
另外,還有在repositories節點中增加如下庫,否則是無法下載到jar包的。
<repository>
<id>Unidal</id>
<url>http://unidal.org/nexus/content/repositories/releases</url>
</repository>
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
初始化CAT客戶端
初始化CAT客戶端,我們要做的就是在spring boot初始化時,讀取Apollo配置,再初始化CAT客戶端。示例如下:
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.dianping.cat.Cat;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
/**
* @author 萬貓學社
*/
@Slf4j
@Configuration
@EnableApolloConfig
public class AppConfig {
/**
* 每個項目的domain都是不同的
* 所以不要從Apollo中讀取
* 這里使用的Apollo的app.id
*/
@Value("${app.id}")
private String domain;
/**
* CAT服務端的端口,從Apollo中讀取
*/
@Value("${cat.server.port}")
private int port;
/**
* CAT服務端的HTTP端口,從Apollo中讀取
*/
@Value("${cat.server.http.port}")
private int httpPort;
/**
* CAT服務端的IP列表,多個以逗號分隔,從Apollo中讀取
*/
@Value("${cat.server.servers}")
private String servers;
/**
* 初始化CAT客戶端
*/
@PostConstruct
public void initCat() {
try {
Cat.initializeByDomain(domain, port, httpPort, servers.split(","));
} catch (Exception e) {
log.error("Initialization of CAT client failed", e);
}
}
}
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。
總結
總結一下,CAT客戶端從Apollo中讀取配置,總共分3步:
- 去除Apollo對CAT的依賴:
MessageProducerManager
接口使用NullMessageProducerManager
類實現。 - 引入CAT客戶端:源碼的lib/java目錄下自己打包,或者添加Maven依賴。
- 初始化CAT客戶端:讀取Apollo配置,調用Cat.initializeByDomain方法初始化。
歡迎關注微信公眾號:萬貓學社,每周一分享Java技術干貨。