增减jmx状态控制

This commit is contained in:
mcy
2019-07-11 21:34:12 +08:00
parent 015026ea91
commit 23209f24ed
6 changed files with 256 additions and 59 deletions

View File

@@ -16,6 +16,7 @@ public class CanalConstants {
public static final String CANAL_IP = ROOT + "." + "ip";
public static final String CANAL_PORT = ROOT + "." + "port";
public static final String CANAL_METRICS_PULL_PORT = ROOT + "." + "metrics.pull.port";
public static final String CANAL_ADMIN_JMX_PORT = ROOT + "." + "admin.jmx.port";
public static final String CANAL_ZKSERVERS = ROOT + "." + "zkServers";
public static final String CANAL_WITHOUT_NETTY = ROOT + "." + "withoutNetty";

View File

@@ -3,6 +3,9 @@ package com.alibaba.otter.canal.deployer;
import java.io.FileInputStream;
import java.util.Properties;
import com.alibaba.otter.canal.deployer.mbean.CanalServerAgent;
import com.alibaba.otter.canal.deployer.mbean.CanalServerMXBean;
import com.alibaba.otter.canal.deployer.mbean.CanalServer;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -53,8 +56,8 @@ public class CanalLauncher {
}
}
final CanalStater canalStater = new CanalStater();
canalStater.start(properties);
final CanalStater canalStater = new CanalStater(properties);
canalStater.start();
if (remoteConfigLoader != null) {
remoteConfigLoader.startMonitor(new RemoteCanalConfigMonitor() {
@@ -63,8 +66,9 @@ public class CanalLauncher {
public void onChange(Properties properties) {
try {
// 远程配置canal.properties修改重新加载整个应用
canalStater.destroy();
canalStater.start(properties);
canalStater.stop();
canalStater.setProperties(properties);
canalStater.start();
} catch (Throwable throwable) {
logger.error(throwable.getMessage(), throwable);
}
@@ -72,10 +76,24 @@ public class CanalLauncher {
});
}
CanalServerAgent canalServerAgent = null;
String jmxPort = properties.getProperty(CanalConstants.CANAL_ADMIN_JMX_PORT);
if (StringUtils.isNotEmpty(jmxPort)) {
String ip = properties.getProperty(CanalConstants.CANAL_IP);
CanalServerMXBean canalServerMBean = new CanalServer(canalStater);
canalServerAgent = new CanalServerAgent(ip, Integer.parseInt(jmxPort), canalServerMBean);
Thread agentThread = new Thread(canalServerAgent::start);
agentThread.start();
}
while (running) {
Thread.sleep(1000);
}
if (canalServerAgent != null) {
canalServerAgent.stop();
}
if (remoteConfigLoader != null) {
remoteConfigLoader.destroy();
}

View File

@@ -32,14 +32,31 @@ public class CanalStater {
private CanalMQProducer canalMQProducer = null;
private Thread shutdownThread = null;
private CanalMQStarter canalMQStarter = null;
private volatile Properties properties;
private volatile boolean running = false;
public CanalStater(Properties properties){
this.properties = properties;
}
public boolean isRunning() {
return running;
}
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
/**
* 启动方法
*
* @param properties canal.properties 配置
* @throws Throwable
*/
synchronized void start(Properties properties) throws Throwable {
public synchronized void start() throws Throwable {
String serverMode = CanalController.getProperty(properties, CanalConstants.CANAL_SERVER_MODE);
if (serverMode.equalsIgnoreCase("kafka")) {
canalMQProducer = new CanalKafkaProducer();
@@ -64,8 +81,8 @@ public class CanalStater {
public boolean accept(File pathname) {
String filename = pathname.getName();
return pathname.isDirectory() && !"spring".equalsIgnoreCase(filename) &&
!"metrics".equalsIgnoreCase(filename);
return pathname.isDirectory() && !"spring".equalsIgnoreCase(filename)
&& !"metrics".equalsIgnoreCase(filename);
}
});
if (instanceDirs != null && instanceDirs.length > 0) {
@@ -113,6 +130,8 @@ public class CanalStater {
canalMQStarter.start(mqProperties);
controller.setCanalMQStarter(canalMQStarter);
}
running = true;
}
/**
@@ -120,7 +139,7 @@ public class CanalStater {
*
* @throws Throwable
*/
synchronized void destroy() throws Throwable {
public synchronized void stop() throws Throwable {
if (controller != null) {
controller.stop();
controller = null;
@@ -134,6 +153,7 @@ public class CanalStater {
canalMQStarter = null;
canalMQProducer = null;
}
running = false;
}
/**
@@ -206,7 +226,8 @@ public class CanalStater {
mqProperties.setProducerGroup(producerGroup);
}
String enableMessageTrace = CanalController.getProperty(properties, CanalConstants.CANAL_MQ_ENABLE_MESSAGE_TRACE);
String enableMessageTrace = CanalController.getProperty(properties,
CanalConstants.CANAL_MQ_ENABLE_MESSAGE_TRACE);
if (!StringUtils.isEmpty(enableMessageTrace)) {
mqProperties.setEnableMessageTrace(Boolean.valueOf(enableMessageTrace));
}
@@ -216,7 +237,8 @@ public class CanalStater {
mqProperties.setAccessChannel(accessChannel);
}
String customizedTraceTopic = CanalController.getProperty(properties, CanalConstants.CANAL_MQ_CUSTOMIZED_TRACE_TOPIC);
String customizedTraceTopic = CanalController.getProperty(properties,
CanalConstants.CANAL_MQ_CUSTOMIZED_TRACE_TOPIC);
if (!StringUtils.isEmpty(customizedTraceTopic)) {
mqProperties.setCustomizedTraceTopic(customizedTraceTopic);
}
@@ -226,17 +248,20 @@ public class CanalStater {
mqProperties.setNamespace(namespace);
}
String kafkaKerberosEnable = CanalController.getProperty(properties, CanalConstants.CANAL_MQ_KAFKA_KERBEROS_ENABLE);
String kafkaKerberosEnable = CanalController.getProperty(properties,
CanalConstants.CANAL_MQ_KAFKA_KERBEROS_ENABLE);
if (!StringUtils.isEmpty(kafkaKerberosEnable)) {
mqProperties.setKerberosEnable(Boolean.valueOf(kafkaKerberosEnable));
}
String kafkaKerberosKrb5Filepath = CanalController.getProperty(properties, CanalConstants.CANAL_MQ_KAFKA_KERBEROS_KRB5FILEPATH);
String kafkaKerberosKrb5Filepath = CanalController.getProperty(properties,
CanalConstants.CANAL_MQ_KAFKA_KERBEROS_KRB5FILEPATH);
if (!StringUtils.isEmpty(kafkaKerberosKrb5Filepath)) {
mqProperties.setKerberosKrb5FilePath(kafkaKerberosKrb5Filepath);
}
String kafkaKerberosJaasFilepath = CanalController.getProperty(properties, CanalConstants.CANAL_MQ_KAFKA_KERBEROS_JAASFILEPATH);
String kafkaKerberosJaasFilepath = CanalController.getProperty(properties,
CanalConstants.CANAL_MQ_KAFKA_KERBEROS_JAASFILEPATH);
if (!StringUtils.isEmpty(kafkaKerberosJaasFilepath)) {
mqProperties.setKerberosJaasFilePath(kafkaKerberosJaasFilepath);
}

View File

@@ -0,0 +1,67 @@
package com.alibaba.otter.canal.deployer.mbean;
import com.alibaba.otter.canal.deployer.CanalLauncher;
import com.alibaba.otter.canal.deployer.CanalStater;
public class CanalServer implements CanalServerMXBean {
private volatile int status;
private CanalStater canalStater;
public CanalServer(CanalStater canalStater){
this.canalStater = canalStater;
this.status = canalStater.isRunning() ? 1 : 0;
}
@Override
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
@Override
public synchronized boolean start() {
try {
if (!canalStater.isRunning()) {
canalStater.start();
status = 1;
return true;
}
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
@Override
public synchronized boolean stop() {
try {
if (canalStater.isRunning()) {
canalStater.stop();
status = 0;
return true;
}
} catch (Throwable e) {
e.printStackTrace();
}
return false;
}
@Override
public synchronized boolean restart() {
stop();
return start();
}
@Override
public synchronized boolean exit() {
stop();
CanalLauncher.running = false;
return true;
}
}

View File

@@ -0,0 +1,72 @@
package com.alibaba.otter.canal.deployer.mbean;
import org.apache.commons.lang.StringUtils;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.rmi.registry.LocateRegistry;
import javax.management.MBeanServer;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
public class CanalServerAgent implements NotificationListener {
private MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
private String ip = "0.0.0.0";
private int port;
private CanalServerMXBean canalServerMbean;
private volatile JMXConnectorServer cs;
public CanalServerAgent(String ip, int port, CanalServerMXBean canalServerMbean){
if (StringUtils.isNotEmpty(ip)) {
this.ip = ip;
}
this.port = port;
this.canalServerMbean = canalServerMbean;
}
@Override
public void handleNotification(Notification notification, Object handback) {
}
public synchronized void start() {
try {
if (cs == null) {
ObjectName name = new ObjectName("CanalServerAgent:type=CanalServerStatus");
mBeanServer.registerMBean(canalServerMbean, name);
LocateRegistry.createRegistry(port);
// 构造JMXServiceURL
JMXServiceURL jmxServiceURL = new JMXServiceURL(
"service:jmx:rmi:///jndi/rmi://" + ip + ":" + port + "/jmxrmi");
// 创建JMXConnectorServer
cs = JMXConnectorServerFactory.newJMXConnectorServer(jmxServiceURL, null, mBeanServer);
// 启动
cs.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void stop() {
if (cs != null) {
try {
cs.stop();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

View File

@@ -0,0 +1,14 @@
package com.alibaba.otter.canal.deployer.mbean;
public interface CanalServerMXBean {
int getStatus();
boolean start();
boolean stop();
boolean restart();
boolean exit();
}