工作中的java DTS 源码阅读
学习背景
公司使用的是java 做的DTS对接,这块代码很长时间没人维护,我希望自己能够扛起这点责任,去维护这个项目,于是在假期的时候对这份源码做了学习和点评
我只能说这是一份能用的代码,而不是一个优秀的项目,为什么这么说呢?
因为这个项目没有良好的监控、自制机群管理系统,以及集中化配置
我不是一个java专家,只是一个业余的学习者,但是由于c、c++、php的功底能够比较容易的看明白java的源码,总体理解比较业余
写这个项目的人是个新手,对多线程运用的不熟悉,为什么这么说呢?没有对线程做监管!!没有提供API监控线程健康状态!
项目核心代码解读
1.启动线程池
项目入口在哪里?
@Component
public class StartTask {
@PostConstruct
public void init(){
final List<ClientConfig> clientThreadList = clientTaskUtil.getClientTaskList();
for (int i=0;i<clientThreadList.size();i++){
// ClientThread clientThread = ApplicationContextProvider.getBean("clientTask",ClientThread.class);
ClientThread clientThread = ctx.getBean("clientTask",ClientThread.class);
clientThread.setClientConfig(clientThreadList.get(i));
clientThread.start();
LOGGER.info("第{}個客戶端通道ID:{}啟動!",(i+1),clientThreadList.get(i).getSubscribeInstanceID());
}
}
}
注意Spring中两个非常重要的注解
@Component 和 @PostConstruct
@Component
泛指各种组件,就是说当我们的类不属于各种归类的时候(不属于@Controller、@Services等的时候),我们就可以使用@Component来标注这个类。
@PostConstruct
该注解被用来修饰一个非静态的void()方法
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
也就是说@PostConstruct
综上所属,入口就在这里,也就是说这里是启动了一个线程池
2.每个线程一个DTS订阅器
阿里云老版本的DTS 订阅代码解读在
https://help.aliyun.com/document_detail/26645.html?spm=a2c4g.11186623.6.799.318c69622OOZ1Z
具体java多线程,请看《java核心卷》14章节,写这个项目的人是个新手,对多线程运用的不熟悉
@Override
public void run(){
RegionContext regionContext = new RegionContext();
regionContext.setAccessKey(clientConfig.getAccessKey());
regionContext.setSecret(clientConfig.getAccessSecret());
regionContext.setUsePublicIp(true);
ClusterClient clusterClient = new DefaultClusterClient(regionContext);
// modifyTimestamp(dtsConfig.getSubscribeInstanceID(), DateUtil.iso8601Format(new Date()));
// System.out.println(DateUtil.iso8601Format(new Date()));
ClusterListener listener = new ClusterListener() {
@Override
public void noException(Exception e) {
// TODO Auto-generated method stub
LOGGER.error("异常:",e);
}
@Override
public void notify(List<ClusterMessage> messages) {
//处理订阅任务收到的消息
for (ClusterMessage message : messages) {
replicateMessage(message);
}
}
};
clusterClient.addConcurrentListener(listener);
try {
clusterClient.askForGUID(clientConfig.getSubscribeInstanceID());
clusterClient.start();
LOGGER.info("clusterClient start :"+clientConfig.getSubscribeInstanceID());
} catch (Exception e) {
LOGGER.error("启动异常:",e);
LOGGER.error("clusterClient start error :"+clientConfig.getSubscribeInstanceID());
}
}
总体运行流程图
十分简单的一个线程池,也没有复杂的代码,只是把DTS数据转投到RocketMq中