我把所有学习Apache Camel找的PDF都上传了,需要的同学自取:
《Mastering Apache Camel》
《Red_Hat_Fuse-7.0-Apache_Camel_Development_Guide-en-US》
《Apache Camel Developer's Cookbook》
目录
前言
动态控制Apache Camel路由的注意点
1. 设置路由ID
2.禁止自动启动
动态控制Apache Camel路由
本篇文章对应的完整项目源码地址:14-ApacheCamel-DynamicControlRoutes
Apache Camel 系列完整项目代码地址:ApacheCamelDemo
如果觉得不错,麻烦点个Star
之前一篇文章《Apache Camel - 22 - Controlling route startup and shutdown(Camel控制路由的启动/关闭顺序)》,了解了如何控制路由的启动和关闭顺序。
下面了解下如何动态控制路由的启动与关闭。
在了解动态控制 Apache Camel 路由之前,首先要了解两个细节,这有助于更好地使用、管理路由。
通过路由ID,可以动态的控制路由启动与关闭。
有助于在日志中更快的查找问题。
如果应用程序庞大,可以将路由ID,注册至ZooKeeper或其他管理平台,以此更好地管理
使用方式:
Java DSL:
from("xxx").routeId("xxxID").process(...).to(...);
XML DSL:
一般情况,将路由添加到CamelContext中之后,随着camelContext的启动,它会自动启动路由。
既然咱们想动态控制,那就先将其设置为'禁止自动启动'
使用方式:
Java DSL:
from("xxx").routeId("xxxID").autoStartup(false).to(...);
XML DSL:
我们可以通过CamelContext对象中的startRoute()和stopRoute()方法控制路由的启动和停止。
看下关键代码:
DynamicControlRoutesMainApp
package com.server;
import com.server.conf.LogBackConfigLoader;
import com.server.routes.master.MasterHttpRoute;
import com.server.routes.slave.SlaveHttpRoute;
import org.apache.camel.CamelContext;
import org.apache.camel.impl.DefaultCamelContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 动态控制路由
*
* @author CYX
*/
public class DynamicControlRoutesMainApp {
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicControlRoutesMainApp.class);
private static final String LOGBACK_FILENAME = "./conf/logback.xml";
public static CamelContext camelContext;
public static void main(String[] args) {
// 初始化参数、异常直接kill程序
try {
LogBackConfigLoader.loadLogBack(LOGBACK_FILENAME);
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
LOGGER.info("===== 准备启动 CamelContext =====");
try {
// 创建CamelContext上下文
camelContext = new DefaultCamelContext();
camelContext.start();
// 将MasterHttpRoute路由加入CamelContext中
camelContext.addRoutes(new MasterHttpRoute());
// 将SlaveHttpRoute路由加入CamelContext中
// 其中'test-route-control-03'禁止自动启动,由Master路由进行控制
camelContext.addRoutes(new SlaveHttpRoute());
// 保证主线程不退出
synchronized (DynamicControlRoutesMainApp.class) {
DynamicControlRoutesMainApp.class.wait();
}
} catch (Exception e) {
LOGGER.error("error : {} , errorMessage : {}", new Object[]{e, e.getMessage()});
}
}
}
SlaveHttpRoute
package com.server.routes.slave;
import org.apache.camel.*;
import org.apache.camel.builder.RouteBuilder;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
/**
* Slave工作路由-Http
*
* @author CYX
* @date 2018/11/7 14:03
*/
public class SlaveHttpRoute extends RouteBuilder {
private static final Logger LOGGER = LoggerFactory.getLogger(SlaveHttpRoute.class);
@Override
public void configure() throws Exception {
/**
* 第一个路由(普通写法,不增加任何配置)
*/
from("jetty:http://127.0.0.1:8282/test-route-control").process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream inputStream = exchange.getIn().getBody(InputStream.class);
String bodyStr = IOUtils.toString(inputStream, "UTF-8");
LOGGER.info("bodyStr : {}", new Object[]{bodyStr});
inputStream.close();
// 存入到exchange的out区域
if (exchange.getPattern() == ExchangePattern.InOut) {
Message outMessage = exchange.getOut();
outMessage.setBody("消息收到" + "-已处理-slave-01");
}
}
});
/**
* 第二个路由(设置route id)
*/
from("jetty:http://127.0.0.1:8282/test-route-contro2").routeId("test-route-control-02").process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream inputStream = exchange.getIn().getBody(InputStream.class);
String bodyStr = IOUtils.toString(inputStream, "UTF-8");
LOGGER.info("bodyStr : {}", new Object[]{bodyStr});
inputStream.close();
// 存入到exchange的out区域
if (exchange.getPattern() == ExchangePattern.InOut) {
Message outMessage = exchange.getOut();
outMessage.setBody("消息收到" + "-已处理-slave-02");
}
}
});
/**
* 第三个路由(设置route id、设置禁止自动启动)
*/
from("jetty:http://127.0.0.1:8282/test-route-contro3").routeId("test-route-control-03").autoStartup(false).process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream inputStream = exchange.getIn().getBody(InputStream.class);
String bodyStr = IOUtils.toString(inputStream, "UTF-8");
LOGGER.info("bodyStr : {}", new Object[]{bodyStr});
inputStream.close();
// 存入到exchange的out区域
if (exchange.getPattern() == ExchangePattern.InOut) {
Message outMessage = exchange.getOut();
outMessage.setBody("消息收到" + "-已处理-slave-03");
}
}
});
}
}
Slave路由中,创建了三个路由,第一个路由没有什么特别的,第二个路由我们手动设置了路由ID。
第三个路由除了路由ID外,嗨设置了autoStartup(false),这个是禁止路由自动启动,由Master路由对它进行控制
MasterHttpRoute
package com.server.routes.master;
import com.server.DynamicControlRoutesMainApp;
import com.server.dto.PersonDTO;
import com.server.util.CommonUtils;
import org.apache.camel.CamelContext;
import org.apache.camel.Exchange;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.InputStream;
/**
* master路由-用来控制Slave路由的启动和停止
*
* @author CYX
* @date 2018/11/7 15:26
*/
public class MasterHttpRoute extends RouteBuilder {
private static final Logger LOGGER = LoggerFactory.getLogger(MasterHttpRoute.class);
private CamelContext camelContext = DynamicControlRoutesMainApp.camelContext;
@Override
public void configure() throws Exception {
/**
* master路由
* 该路由控制slave中的其他路由
*/
from("jetty:http://127.0.0.1:8282/masterRoute").routeId("masterRoute").process(new Processor() {
@Override
public void process(Exchange exchange) throws Exception {
InputStream bodyStream = exchange.getIn().getBody(InputStream.class);
String bodyStr = IOUtils.toString(bodyStream, "UTF-8");
LOGGER.info("bodyStr : {}", new Object[]{bodyStr});
PersonDTO personDTO = CommonUtils.toJavaObject(bodyStr, PersonDTO.class);
if ("0".equals(personDTO.getSlaveFlag())) {
//停止'test-route-control-03'路由
camelContext.stopRoute("test-route-control-03");
LOGGER.info("===== 停止 routeID:test-route-control-03 =====");
} else if ("1".equals(personDTO.getSlaveFlag())) {
//启动'test-route-control-03'路由
camelContext.startRoute("test-route-control-03");
LOGGER.info("===== 启动 routeID:test-route-control-03 =====");
} else if ("2".equals(personDTO.getSlaveFlag())) {
//暂停'test-route-control-03'路由
camelContext.suspendRoute("test-route-control-03");
LOGGER.info("===== 暂停 routeID:test-route-control-03 =====");
//设置暂停时间
//camelContext.suspendRoute("",3600, TimeUnit.SECONDS);
}
if (exchange.getPattern() == ExchangePattern.InOut) {
Message outMessage = exchange.getOut();
outMessage.setBody("消息收到" + "-已处理-00");
}
}
});
}
}
Master路由,camelContext成员变量,指向DynamicControlRoutesMainApp.camelContext。
Master路由,单独发布一个Master Http服务,通过调用这个http服务,来控制slave路由的开启、停止、暂停。
启动程序,查看控制台的日志。
一共四条路由信息。
第一条:Master路由,自己设定的路由ID
第二条:Slave普通路由,未设置任何参数,路由ID是系统给定的。
第三条:Slave普通路由,自己设定路由ID
第四条:Slave路由,自己设定路由ID,并且设定禁止自动启动,由Master控制。
调用测试方法:startRoute(),服务端接收到信息,解析后,启动 ID为'test-route-control-03'的路由
接着调用testOtherRoutes()方法,测试 ID为'test-route-control-03'的路由,是否能够成功调用。
没问题,该路由成功调用。
暂停路由
停止路由
ok,完结...
本篇文章对应的完整项目源码地址:14-ApacheCamel-DynamicControlRoutes
Apache Camel 系列完整项目代码地址:ApacheCamelDemo
如果觉得不错,麻烦点个Star