使用Maxwell 和 RabbitMQ监听MySQL BinLog

  最近要做一个运营管理新系统,要求把原来的一些旧的子系统的数据(MySQL)抽取出来放到数据中心,并要求把子系统的增量数据实时同步到数据中心;一听这需求觉得一次性同步倒不是很难,难就是难在增量数据要实时同步;数据库这块本来就不是强项,加上是刚开始用MySQL所以一下子想不出什么好的解决方案。

  经过Google一个上午终于找到了一个自己觉得可行的方案,使用Maxwell来监听MySQL的BinLog文件。Maxwell的具体介绍请参考 https://blog.csdn.net/wwwdc1012/article/details/88388552。这里主要记录下在本机搭建环境时遇到的一些问题。

  先说下本机环境:

    Docker Desktop:  Linux Containers

    MySQL: 安装在 Docker Desktop里面;

    RabbitMQ: 安装在Docker Desktop里面;

  同样的Maxwell也将安装在 Docker Desktop里

  

docker pull zendesk/maxwell

  开启MySQL的 BinLog:

  在Powershell 使用 docker ps 查看 mysql的容器ID或者容器名字

  使用 docker exec -it   容器名/容器ID /bin/bash 进入到MySQL容器

  登录 MySQL: mysql -u root -h 127.0.0.1 -p

  执行以下命令开启MySQL的BinLog:

mysql> set global binlog_format=ROW;
mysql> set global binlog_row_image=FULL;

  将Maxwell连接到MySQL:

docker run -ti --rm zendesk/maxwell bin/maxwell --user='root' --password='123456' --host='172.17.0.2'  --producer=stdout

  --user: mysql 登录用户名

  --password: mysql 登录密码

  --host: mysql 服务IP

  --producer: maxwell 输出方式, 默认为stdout:控制台输出

  --port: mysql的端口, 默认为3306

  这里特别强调下,因为我这里都是用docker 来安装的所以每个应用都会有一个独立的容器,刚开始的时候没有考虑到这点 --host 使用了 127.0.0.1 就一直失败;所以这里不能使用127.0.0.1或者localhost,只能使用容器IP,如果做了映射也可以用你本机的IP。

以下是连接成功

 

当我们对数据库做增、删、改时控制台输出如下

 接下来将把这个输出,输出到RabbitMQ:

docker run -ti --rm zendesk/maxwell bin/maxwell --user='root' 
--password='123456' 
--host='172.17.0.2'  
--producer=rabbitmq 
--rabbitmq_user='guest' 
--rabbitmq_pass='guest' 
--rabbitmq_host='172.17.0.3' 
--rabbitmq_port='5672' 
--rabbitmq_exchange='databaselogs'  
--rabbitmq_exchange_type='fanout'

  --producer改为 rabbitmq;

  --rabbitmq_user:  mq登录名;

  --rabbitmq_pass: mq登录密码;

  --rabbitmq_host:  mq服务器地址,我这里的172.17.0.3 为mq的容器IP, 也可以写本机的IP,  也不能使用 localhost和127.0.0.1

  --rabbitmq_port: mq端口;

  --rabbitmq_exchange: mq交换器名称,这里可以自定义,只要跟后台的程序一致就行了;

  --rabbitmq_exchange_type: mq交换类型;

后台接收代码:

var factory = new ConnectionFactory() { HostName = "localhost", UserName= "guest", Password= "guest" , Port= 5672 };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
          // 这里的 exchange 要跟前面命令一致 channel.ExchangeDeclare(exchange: "databaselogs", type: "fanout"); channel.QueueBind(queue: "task_queue", exchange: "databaselogs", routingKey: ""); //channel.QueueDeclare(queue: "task_queue", // durable: true, // exclusive: false, // autoDelete: false, // arguments: null); channel.BasicQos(prefetchSize: 0, prefetchCount: 1, global: false); Console.WriteLine(" [*] Waiting for messages."); var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body; var message = Encoding.UTF8.GetString(body); Console.WriteLine(" [x] Received {0}", message); Console.WriteLine(" [x] Done"); channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); }; channel.BasicConsume(queue: "task_queue", autoAck: false, consumer: consumer); Console.WriteLine(" Press [enter] to exit."); Console.ReadLine();

  控制台输出如下:

猜你喜欢

转载自www.cnblogs.com/lao-tang/p/11353080.html