├── .gitignore
├── README.md
├── pom.xml
└── src
└── main
├── java
├── CanalStarter.java
├── canal
│ ├── CanalChangeInfo.java
│ ├── CanalMsg.java
│ ├── CanalMsgContent.java
│ ├── CanalMsgHandler.java
│ ├── CanalMsgMQHandlerImpl.java
│ ├── CanalPool.java
│ └── CanalService.java
├── consts
│ └── CommonConstant.java
├── elasticsearch
│ ├── User.java
│ └── UserRepository.java
└── rabbitmq
│ ├── MessageReceiver.java
│ └── MessageSender.java
└── resources
├── canal
└── example.properties
├── elasticsearch
└── elasticsearch.xml
├── rabbitmq
├── rabbitmq.properties
└── rabbitmq.xml
└── spring
└── applicationContext.xml
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # IDE
3 | .idea/
4 | *.iml
5 | target/
6 |
7 |
8 |
9 | *.class
10 |
11 | # Mobile Tools for Java (J2ME)
12 | .mtj.tmp/
13 |
14 | # Package Files #
15 | *.jar
16 | *.war
17 | *.ear
18 |
19 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
20 | hs_err_pid*
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # jeet-search
2 | 一套基于ES的搜索方案
3 |
4 | ## 环境
5 | - 系统环境:MacOS 10.12
6 | - 数据库:MySQL 5.7.16
7 | - ES版本:stable 2.4.4
8 | - binlog订阅消费组件:canal-1.0.23
9 | - 消息队列:RabbitMQ 3.6.6(注:在canal比较新的版本里已自带投递到MQ的功能)
10 |
11 | ## 原理
12 | - 业务方更新MySQL表记录
13 | - canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
14 | - mysql master收到dump请求,开始推送binary log给slave(也就是canal)
15 | - canal解析binary log对象(原始为byte流)
16 | - canal客户端将解析后数据发送到到RabbitMQ
17 | - 业务方消费MQ,调用ES API更新索引,实现索引的实时更新
18 |
19 | ## MySQL配置
20 | 修改my.cnf,开启binlog
21 | ```
22 | [mysqld]
23 | log-bin=mysql-bin #添加这一行就ok
24 | binlog-format=ROW #选择row模式
25 | server_id=1 #配置mysql replaction需要定义,不能和canal的slaveId重复
26 | ```
27 | 新建canal用户并分配权限
28 | ```sql
29 | CREATE USER canal IDENTIFIED BY 'canal';
30 | GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
31 | -- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
32 | FLUSH PRIVILEGES;
33 | ```
34 |
35 | ## canal配置
36 | 修改instance.properties,更多配置[戳此](https://github.com/alibaba/canal/wiki/AdminGuide)
37 | ```
38 | ## mysql serverId
39 | canal.instance.mysql.slaveId = 1234
40 |
41 | # position info,需要改成自己的数据库信息
42 | canal.instance.master.address = 127.0.0.1:3306
43 | canal.instance.master.journal.name =
44 | canal.instance.master.position =
45 | canal.instance.master.timestamp =
46 |
47 | #canal.instance.standby.address =
48 | #canal.instance.standby.journal.name =
49 | #canal.instance.standby.position =
50 | #canal.instance.standby.timestamp =
51 |
52 | # username/password,需要改成自己的数据库信息
53 | canal.instance.dbUsername = canal
54 | canal.instance.dbPassword = canal
55 | canal.instance.defaultDatabaseName =
56 | canal.instance.connectionCharset = UTF-8
57 |
58 | # table regex
59 | canal.instance.filter.regex = .*\\..*
60 | ```
61 |
62 | ## elasticsearch配置
63 | 修改elasticsearch.yml
64 | ```yml
65 | cluster.name: jeet-search
66 | ```
67 |
68 | ## 踩坑
69 | - RabbitMQ topic exchange 路由键a.*无法匹配a.b.c,只有a.*.*才能匹配a.b.c
70 | - spring-data-elasticsearch 暂时不支持ES5,所以最后选择了2.4.4版本
71 |
72 | ## RoadMap
73 | - 2017.3.18
74 | * 启动项目
75 | * 搭建canal,rabbitmq,es环境
76 | - 2017.3.19
77 | * 实现canal和rabbitmq部分逻辑
78 | - 2017.3.25
79 | * 引入Spring框架重构代码
80 | - 2017.4.2
81 | * ES5.x 很多配套的组件不支持,改用2.4.4
82 | * 实现索引构建
83 | - 2017.9.8
84 | * 优化代码,规范项目结构
85 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.bug1024
8 | jeet-search
9 | 1.0-SNAPSHOT
10 |
11 |
12 | jeet-search
13 | 4.2.3.RELEASE
14 | 2.8.8
15 | 1.0.22
16 | 4.11
17 | 1.1.7
18 | 1.6.2
19 | 1.6.2
20 |
21 |
22 |
23 |
24 |
25 | org.springframework
26 | spring-tx
27 | ${spring.version}
28 |
29 |
30 | org.springframework
31 | spring-beans
32 | ${spring.version}
33 | jar
34 |
35 |
36 | org.springframework
37 | spring-context
38 | ${spring.version}
39 | jar
40 |
41 |
42 | org.springframework
43 | spring-aspects
44 | ${spring.version}
45 |
46 |
47 | org.springframework
48 | spring-orm
49 | ${spring.version}
50 |
51 |
52 | org.springframework
53 | spring-test
54 | ${spring.version}
55 |
56 |
57 | org.springframework
58 | spring-web
59 | ${spring.version}
60 |
61 |
62 | org.springframework
63 | spring-webmvc
64 | ${spring.version}
65 |
66 |
67 |
68 |
69 | com.fasterxml.jackson.core
70 | jackson-annotations
71 | ${jackson.version}
72 |
73 |
74 | com.fasterxml.jackson.core
75 | jackson-databind
76 | ${jackson.version}
77 |
78 |
79 |
80 |
81 | org.springframework.data
82 | spring-data-elasticsearch
83 | 2.0.4.RELEASE
84 |
85 |
86 |
87 |
88 | org.springframework.amqp
89 | spring-rabbit
90 | 1.7.1.RELEASE
91 |
92 |
93 |
94 |
95 | com.alibaba.otter
96 | canal.client
97 | ${canal.version}
98 |
99 |
100 |
101 |
102 | junit
103 | junit
104 | ${junit.version}
105 |
106 |
107 |
108 |
109 | org.projectlombok
110 | lombok
111 | 1.16.12
112 |
113 |
114 |
115 |
116 |
117 | spring-libs-snapshot
118 | Spring Snapshot Repository
119 | http://repo.spring.io/libs-snapshot
120 |
121 |
122 |
123 |
124 |
125 |
126 | org.apache.maven.plugins
127 | maven-compiler-plugin
128 | 3.1
129 |
130 | 1.8
131 | 1.8
132 |
133 |
134 |
135 |
136 |
137 |
--------------------------------------------------------------------------------
/src/main/java/CanalStarter.java:
--------------------------------------------------------------------------------
1 | import canal.CanalService;
2 | import org.slf4j.Logger;
3 | import org.slf4j.LoggerFactory;
4 | import org.springframework.context.support.ClassPathXmlApplicationContext;
5 |
6 | /**
7 | * 启动CanalService
8 | * @author bug1024
9 | * @date 2017-11-03
10 | */
11 | public class CanalStarter {
12 | private static Logger logger = LoggerFactory.getLogger(CanalStarter.class);
13 |
14 | public static void main(String[] args) {
15 | try {
16 | ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/spring/applicationContext.xml");
17 | CanalService canalService = (CanalService) context.getBean("canalService");
18 | canalService.start();
19 | } catch (Exception e) {
20 | logger.warn("canal service error", e);
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalChangeInfo.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import lombok.Data;
4 |
5 | /**
6 | *
7 | * @author bug1024
8 | * @date 2017-09-08
9 | */
10 | @Data
11 | public class CanalChangeInfo {
12 |
13 | private String name;
14 |
15 | private String value;
16 |
17 | private Object update;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalMsg.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import consts.CommonConstant;
4 | import lombok.Data;
5 |
6 | import java.util.Map;
7 |
8 | /**
9 | * canal消息
10 | *
11 | * @author bug1024
12 | * @date 2017-03-25
13 | */
14 | @Data
15 | public class CanalMsg {
16 |
17 | private String key;
18 |
19 | private CanalMsgContent canalMsgContent;
20 |
21 | CanalMsg(CanalMsgContent canalMsgContent) {
22 | this.key = CommonConstant.CANAL_MSG_KEY_PREFIX + CommonConstant.KEY_SEPARATOR + canalMsgContent.getDbName() + CommonConstant.KEY_SEPARATOR + canalMsgContent.getTableName();
23 | this.canalMsgContent = canalMsgContent;
24 | }
25 |
26 | CanalMsg() {
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalMsgContent.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import lombok.Data;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * Canal基础信息 包括表名等
9 | * @author bug1024
10 | * @date 2017-09-08
11 | */
12 | @Data
13 | public class CanalMsgContent {
14 |
15 | private String binLogFile;
16 | private Long binlogOffset;
17 | private String dbName;
18 | private String tableName;
19 | private String eventType;
20 | private List dataBefore;
21 | private List dataAfter;
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalMsgHandler.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | /**
4 | * canal消息处理
5 | *
6 | * @author bug1024
7 | * @date 2017-03-25
8 | */
9 | public interface CanalMsgHandler {
10 |
11 | Boolean handle(CanalMsg canalMsg);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalMsgMQHandlerImpl.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 | import rabbitmq.MessageSender;
8 |
9 | /**
10 | * 利用MQ处理canal消息处理
11 | *
12 | * @author bug1024
13 | * @date 2017-03-25
14 | */
15 | @Service
16 | public class CanalMsgMQHandlerImpl implements CanalMsgHandler {
17 |
18 | private static Logger logger = LoggerFactory.getLogger(CanalMsgMQHandlerImpl.class);
19 |
20 | @Autowired
21 | private MessageSender messageSender;
22 |
23 | @Override
24 | public Boolean handle(CanalMsg canalMsg) {
25 | return messageSender.sendMessage(canalMsg.getKey(), canalMsg.getCanalMsgContent());
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalPool.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import com.alibaba.otter.canal.client.CanalConnector;
4 | import com.alibaba.otter.canal.client.CanalConnectors;
5 | import com.alibaba.otter.canal.common.utils.AddressUtils;
6 | import consts.CommonConstant;
7 | import org.springframework.stereotype.Service;
8 |
9 | import java.net.InetSocketAddress;
10 |
11 | /**
12 | * @author bug1024
13 | * @date 2017-03-25
14 | */
15 | @Service
16 | public class CanalPool {
17 |
18 | public CanalConnector getConnector() {
19 | // @TODO 基于zookeeper动态获取canal server的地址
20 | com.alibaba.otter.canal.client.CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(AddressUtils.getHostIp(), CommonConstant.CANAL_PORT),
21 | CommonConstant.CANAL_DEST,
22 | "",
23 | "");
24 |
25 | return connector;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/java/canal/CanalService.java:
--------------------------------------------------------------------------------
1 | package canal;
2 |
3 | import com.alibaba.otter.canal.client.CanalConnector;
4 | import com.alibaba.otter.canal.protocol.CanalEntry;
5 | import com.alibaba.otter.canal.protocol.Message;
6 | import consts.CommonConstant;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Service;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * canal客户端服务
17 | *
18 | * @author bug1024
19 | * @date 2017-03-25
20 | */
21 | @Service
22 | public class CanalService {
23 |
24 | private static Logger logger = LoggerFactory.getLogger(CanalService.class);
25 |
26 | @Autowired
27 | private CanalMsgHandler canalMsgHandler;
28 |
29 | @Autowired
30 | private CanalPool canalPool;
31 |
32 | public void start() {
33 | int emptyCount = 0;
34 | CanalConnector canalConnector = canalPool.getConnector();
35 | try {
36 | canalConnector.connect();
37 | canalConnector.subscribe(".*\\..*");
38 | canalConnector.rollback();
39 |
40 | while (emptyCount < CommonConstant.CANAL_TOTAL_EMPTY_COUNT) {
41 | // 获取指定数量的数据
42 | Message message = canalConnector.getWithoutAck(CommonConstant.BATCH_SIZE);
43 | long batchId = message.getId();
44 | int size = message.getEntries().size();
45 | if (batchId == -1 || size == 0) {
46 | emptyCount++;
47 | System.out.println(emptyCount);
48 | try {
49 | Thread.sleep(1000);
50 | } catch (InterruptedException e) {
51 |
52 | }
53 | } else {
54 | emptyCount = 0;
55 | processEntry(message.getEntries());
56 | }
57 |
58 | // 提交确认
59 | canalConnector.ack(batchId);
60 | // 处理失败, 回滚数据
61 | // connector.rollback(batchId);
62 | }
63 | } catch (Exception e) {
64 | logger.warn("canal process error", e);
65 | } finally {
66 | canalConnector.disconnect();
67 | }
68 | }
69 |
70 | private void processEntry(List entries) {
71 | List msgList = convertToCanalMsgList(entries);
72 | for (CanalMsg msg : msgList) {
73 | canalMsgHandler.handle(msg);
74 | }
75 | }
76 |
77 | private List convertToCanalMsgList(List entries) {
78 | List msgList = new ArrayList();
79 | CanalMsgContent canalMsgContent = null;
80 | for (CanalEntry.Entry entry : entries) {
81 | if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {
82 | continue;
83 | }
84 |
85 | CanalEntry.RowChange rowChange = null;
86 | try {
87 | rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
88 | } catch (Exception e) {
89 | throw new RuntimeException("ERROR ## parse error, data:" + entry.toString(), e);
90 | }
91 |
92 | CanalEntry.EventType eventType = rowChange.getEventType();
93 | canalMsgContent = new CanalMsgContent();
94 | canalMsgContent.setBinLogFile(entry.getHeader().getLogfileName());
95 | canalMsgContent.setBinlogOffset(entry.getHeader().getLogfileOffset());
96 | canalMsgContent.setDbName(entry.getHeader().getSchemaName());
97 | canalMsgContent.setTableName(entry.getHeader().getTableName());
98 | canalMsgContent.setEventType(eventType.toString().toLowerCase());
99 |
100 | for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
101 | canalMsgContent.setDataBefore(convertToCanalChangeInfoList(rowData.getBeforeColumnsList()));
102 | canalMsgContent.setDataAfter(convertToCanalChangeInfoList(rowData.getAfterColumnsList()));
103 | CanalMsg canalMsg = new CanalMsg(canalMsgContent);
104 | msgList.add(canalMsg);
105 | }
106 | }
107 |
108 | return msgList;
109 | }
110 |
111 | private List convertToCanalChangeInfoList(List columnList) {
112 | List canalChangeInfoList = new ArrayList();
113 | for (CanalEntry.Column column : columnList) {
114 | CanalChangeInfo canalChangeInfo = new CanalChangeInfo();
115 | canalChangeInfo.setName(column.getName());
116 | canalChangeInfo.setValue(column.getValue());
117 | canalChangeInfo.setUpdate(column.getUpdated());
118 | canalChangeInfoList.add(canalChangeInfo);
119 | }
120 |
121 | return canalChangeInfoList;
122 | }
123 |
124 | }
125 |
--------------------------------------------------------------------------------
/src/main/java/consts/CommonConstant.java:
--------------------------------------------------------------------------------
1 | package consts;
2 |
3 | /**
4 | *
5 | * @author bug1024
6 | * @date 2017-09-10
7 | */
8 | public class CommonConstant {
9 | public final static String CANAL_MSG_KEY_PREFIX = "canal";
10 |
11 | public final static String KEY_SEPARATOR = ".";
12 |
13 | public final static int CANAL_TOTAL_EMPTY_COUNT = 300;
14 |
15 | public final static int CANAL_PORT = 11111;
16 | public final static String CANAL_DEST = "example";
17 |
18 | public final static int BATCH_SIZE = 1000;
19 | }
20 |
--------------------------------------------------------------------------------
/src/main/java/elasticsearch/User.java:
--------------------------------------------------------------------------------
1 | package elasticsearch;
2 |
3 | import com.fasterxml.jackson.annotation.JsonProperty;
4 | import lombok.Data;
5 | import org.springframework.data.annotation.Id;
6 | import org.springframework.data.elasticsearch.annotations.Document;
7 |
8 | import java.io.Serializable;
9 | import java.sql.Timestamp;
10 |
11 | /**
12 | * user实体类
13 | *
14 | * @author bug1024
15 | * @date 2017-04-02
16 | */
17 | @Data
18 | @Document(indexName="jeet-search", type="user", refreshInterval="-1")
19 | public class User implements Serializable {
20 |
21 | private static final long serialVersionUID = -2312110729335920029L;
22 |
23 | @Id
24 | private Integer id;
25 |
26 | private Integer username;
27 |
28 | @JsonProperty("real_name")
29 | private String realName;
30 |
31 | private Integer status;
32 |
33 | @JsonProperty("create_time")
34 | private Timestamp createTime;
35 |
36 | @JsonProperty("update_time")
37 | private Timestamp updateTime;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/elasticsearch/UserRepository.java:
--------------------------------------------------------------------------------
1 | package elasticsearch;
2 |
3 | import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
4 |
5 | import java.util.List;
6 |
7 | /**
8 | * user仓库
9 | *
10 | * @author bug1024
11 | * @date 2017-04-02
12 | */
13 | public interface UserRepository extends ElasticsearchRepository {
14 |
15 | List findByUsername(String username);
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/rabbitmq/MessageReceiver.java:
--------------------------------------------------------------------------------
1 | package rabbitmq;
2 |
3 | import canal.CanalChangeInfo;
4 | import canal.CanalMsgContent;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import com.rabbitmq.client.Channel;
7 | import elasticsearch.User;
8 | import elasticsearch.UserRepository;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.amqp.core.Message;
12 | import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
13 | import org.springframework.stereotype.Service;
14 |
15 | import javax.annotation.Resource;
16 | import java.sql.Timestamp;
17 | import java.util.HashMap;
18 | import java.util.List;
19 | import java.util.Map;
20 |
21 | /**
22 | * 接收消息
23 | *
24 | * @author bug1024
25 | * @date 2017-03-26
26 | */
27 | @Service
28 | public class MessageReceiver implements ChannelAwareMessageListener {
29 |
30 | private static Logger logger = LoggerFactory.getLogger(MessageReceiver.class);
31 |
32 | private static final ObjectMapper MAPPER = new ObjectMapper();
33 |
34 | @Resource
35 | private UserRepository repository;
36 |
37 | @Override
38 | public void onMessage(Message message, Channel channel) throws Exception {
39 | try {
40 | String jsonString = new String(message.getBody());
41 |
42 | User user = convertJsonToUser(jsonString);
43 |
44 | repository.save(user);
45 |
46 | // false只确认当前一个消息收到,true确认所有consumer获得的消息
47 | channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
48 | } catch (Exception e) {
49 | logger.warn("message consume failed: " + e.getMessage());
50 | // ack返回false,并重新回到队列
51 | channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
52 | }
53 | // 拒绝消息
54 | //channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
55 | }
56 |
57 | private User convertJsonToUser(String jsonString) throws Exception {
58 | CanalMsgContent content = null;
59 | try {
60 | content = MAPPER.readValue(jsonString, CanalMsgContent.class);
61 | } catch (Exception e) {
62 | logger.warn("json decode failed", e);
63 | throw e;
64 | }
65 |
66 | List afterList = content.getDataAfter();
67 | Map map = new HashMap<>();
68 | for (CanalChangeInfo changeInfo : afterList) {
69 | map.put(changeInfo.getName(), changeInfo.getValue());
70 | }
71 |
72 | User user = new User();
73 | user.setId(Integer.valueOf(map.get("id")));
74 | user.setStatus(Integer.valueOf(map.get("status")));
75 | user.setRealName(map.get("real_name"));
76 | user.setCreateTime((Timestamp.valueOf(map.get("create_time"))));
77 | user.setUpdateTime(Timestamp.valueOf(map.get("update_time")));
78 |
79 | return user;
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/src/main/java/rabbitmq/MessageSender.java:
--------------------------------------------------------------------------------
1 | package rabbitmq;
2 |
3 | import com.fasterxml.jackson.core.JsonProcessingException;
4 | import com.fasterxml.jackson.databind.ObjectMapper;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.amqp.core.AmqpTemplate;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Service;
10 |
11 | /**
12 | * 发送消息
13 | *
14 | * @author bug1024
15 | * @date 2017-03-26
16 | */
17 | @Service
18 | public class MessageSender {
19 |
20 | private static Logger logger = LoggerFactory.getLogger(MessageSender.class);
21 |
22 | private static final ObjectMapper MAPPER = new ObjectMapper();
23 |
24 | @Autowired
25 | private AmqpTemplate amqpTemplate;
26 |
27 | public Boolean sendMessage(String routingKey, Object message){
28 | try {
29 | String msg = MAPPER.writeValueAsString(message);
30 | amqpTemplate.convertAndSend(routingKey, msg);
31 | return true;
32 | } catch (JsonProcessingException e) {
33 | logger.warn("json encode failed", e);
34 | return false;
35 | } catch (Exception e) {
36 | logger.warn("send to mq failed", e);
37 | return false;
38 | }
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/resources/canal/example.properties:
--------------------------------------------------------------------------------
1 | host = 127.0.0.1
2 | port = 11111
3 | destination = example
--------------------------------------------------------------------------------
/src/main/resources/elasticsearch/elasticsearch.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/main/resources/rabbitmq/rabbitmq.properties:
--------------------------------------------------------------------------------
1 | mq.host = localhost
2 | mq.port = 5672
3 | mq.username = guest
4 | mq.password = guest
5 | mq.vhost = /
6 |
--------------------------------------------------------------------------------
/src/main/resources/rabbitmq/rabbitmq.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/main/resources/spring/applicationContext.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------