一、去除Apollo对CAT的依赖
Apollo对CAT是有依赖的,但不是强依赖,而是使用了SPI技术,只有项目里引用了cat-client才会生效。目前我们想把CAT客户端配置放在Apollo里,也就是在CAT客户端初始化之前从Apollo读取相应配置,这就形成了循环依赖,所以首先要去除Apollo对CAT客户端的依赖。
1、接口:MessageProducerManager
DefaultMessageProducerManager
:默认实现类
如果发现CAT客户端被引入时,这个类就会初始化CAT客户端并向CAT客户端发送消息。NullMessageProducerManager
:实现类,
类返回的是NullMessageProducer实例,任何消息都不发送。
2、创建文件
去除CAT的依赖,在项目里使用
NullMessageProducerManager
的实现类。
在META-INF/services
文件夹中创建如下文件:
com.ctrip.framework.apollo.tracer.spi.MessageProducerManager
并添加如下内容:
com.ctrip.framework.apollo.tracer.internals.NullMessageProducerManager
二、引入CAT客户端
1、pom依赖
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-client</artifactId>
<version>3.0.0</version>
</dependency>
三、初始化CAT客户端
1、apollo配置
2、初始化CAT
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 Created by xiaoxian 2021/01/22.
* @version v0.1.0
* @see <font color="#0000FF">house-parent</font>
*/
@Slf4j
@Configuration
public class CatConfig {
/**
* 每个项目的domain都是不同的
* 所以不要从Apollo中读取
* 建议使用的Apollo的app.id
*/
@Value("${spring.application.name}")
private String domain;
@Value("${app.id}")
private String appId;
/**
* 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 {
log.info("Initialization of CAT client port:{},httpPort:{},domain:{},appId:{},servers:{}", port, httpPort, domain, appId, servers);
Cat.initializeByDomain(domain != null && !"unknown".equalsIgnoreCase(domain) ? domain : appId, port, httpPort, servers.split(","));
} catch (Exception e) {
log.error("Initialization of CAT client failed", e);
}
}
}