go 连接 kafka 写 mysql

引言

上一篇中提到了,go 连接 kafka 进行消息的生产和消费过程。在这一篇中,将对 go 连接 kafka 写 mysql 进行简单的设计和实现。

本文主要针对的是 Mac 系统,如果使用其它操作系统,操作过程可能有所差异,请注意区别。

一、环境安装

可以根据上一篇的介绍搭建好 kafka,在这里不做赘述。

安装 mysql

我安装的是 mysql 的5.8版本,在 mysql 官网下载安装即可。
http://www.mysql.com/
详细的安装过程,可以参考下面的链接:
https://www.jianshu.com/p/07a9826898c0

二、代码

go 语言访问 mysql,需要第三方依赖,我采用的是 go-sql-driver/mysql,在这里也针对 go-sql-driver/mysql 进行操作。可以使用以下命令获得该依赖:

go get github.com/go-sql-driver/mysql

建立 test.go 文件,代码如下:

func main() {
	// 用户名:密码@tcp(ip:port)/dbname
	db, err := sql.Open("mysql", "root:12345678@tcp(localhost:3306)/test")
	if err != nil {
		panic(err.Error())
	}
	defer db.Close()

	err = db.Ping()
	if err != nil {
		panic(err.Error())
	}
	fmt.Println("connected to MySQL...")

	stmtIns, err := db.Prepare("INSERT INTO datadump (`topic`,`partition`,`offset`,`key`,`value`,`processedby`,`createdat`) VALUES(?,?,?,?,?,?,?)")

	if err != nil {
		panic(err.Error())
	}
	defer stmtIns.Close()

	ehcsBroker := os.Getenv("OEHCS_EXTERNAL_CONNECT_STRING")
	if ehcsBroker == "" {
		ehcsBroker = "localhost:9092"
	}

	ehcsTopic := os.Getenv("OEHCS_TOPIC")
	if ehcsTopic == "" {
		ehcsTopic = "test"
	}

	config := cluster.NewConfig()
	config.Consumer.Return.Errors = true
	config.Group.Return.Notifications = true

	brokers := []string{ehcsBroker}
	topics := []string{ehcsTopic}
	fmt.Println("Connecting to EHCS cluster at " + ehcsBroker)

	consumer, err := cluster.NewConsumer(brokers, "test-consumer-group", topics, config)
	if err != nil {
		panic(err)
	}

	fmt.Println("connected to Kafka...")
	defer consumer.Close()

	//get ACCS app instance name
	appName := os.Getenv("ORA_APP_NAME")
	if appName == "" {
		appName = "accsgokafkamysql"
	}

	appInstance := os.Getenv("ORA_INSTANCE_NAME")
	if appInstance == "" {
		appInstance = "instance1"
	}

	processedby := appName + "_" + appInstance

	fmt.Println("Processed by instance " + processedby)

	signals := make(chan os.Signal, 1)
	signal.Notify(signals, os.Interrupt)

	go func() {
		for err := range consumer.Errors() {
			log.Printf("Error: %s\n", err.Error())
		}
	}()

	go func() {
		for ntf := range consumer.Notifications() {
			log.Printf("Rebalanced: %+v\n", ntf)
		}
	}()

	for {
		select {
		case msg, ok := <-consumer.Messages():
			if ok {
				fmt.Fprintf(os.Stdout, "%s/%d/%d\t%s\t%s\n", msg.Topic, msg.Partition, msg.Offset, msg.Key, msg.Value)

				_, err = stmtIns.Exec(msg.Topic, msg.Partition, msg.Offset, msg.Key, msg.Value, processedby, time.Now().Local())
				if err != nil {
					panic(err.Error())
				} else {
					fmt.Println("Detailed pushed to MySQL")
				}

				consumer.MarkOffset(msg, "")
			}
		case <-signals:
			return
		}
	}

}

说明:代码包括两个部分,一个是建立与 mysql 的连接,另一个是启动 kafka 消费者接收消息并插入到 datadump 表格中。

创建 send.go 文件

func syncProducer(address []string, count int)  {
	log.Println("this count is %d", count)
	t1 := time.Now() // get current time
	config := sarama.NewConfig()
	config.Producer.Return.Successes = true
	config.Producer.Timeout = 5 * time.Second
	p, err := sarama.NewSyncProducer(address, config)
	if err != nil {
		log.Printf("sarama.NewSyncProducer err, message=%s \n", err)
		return
	}
	defer p.Close()
	topic := "test"
	srckey := "%d"
	srcValue := "this value is index=%d"

	for i:=0; i<10; i++ {
		key := fmt.Sprintf(srckey,i)
		value := fmt.Sprintf(srcValue, i)
		msg := &sarama.ProducerMessage{
			Topic:topic,
			Key:sarama.ByteEncoder(key),
			Value:sarama.ByteEncoder(value),
		}
		part, offset, err := p.SendMessage(msg)
		if err != nil {
			log.Printf("send message(%s) err=%s \n", value, err)
		}else {
			fmt.Fprintf(os.Stdout, value + "发送成功,partition=%d, offset=%d \n", part, offset)
		}
		time.Sleep(2*time.Second)
	}
	elapsed := time.Since(t1)
	log.Println("发送消息时间耗时: %d", elapsed)
}

datadump表

 CREATE TABLE `datadump` (
        `uid` INT(10) NOT NULL AUTO_INCREMENT,
        `topic` VARCHAR(64) NULL DEFAULT NULL,
        `partition` INT(64) NULL DEFAULT NULL,
		`offset` INT(64) NULL DEFAULT NULL,
		`key` VARCHAR(64) NULL DEFAULT NULL,
		`value` VARCHAR(64) NULL DEFAULT NULL,
		`processedby` VARCHAR(64) NULL DEFAULT NULL,
        `createdat` VARCHAR(64) NULL DEFAULT NULL,
        PRIMARY KEY (`uid`)
    );

三、流程说明

具体的操作过程如下:

  • 启动 zookeeper 和 kafka
  • 启动 mysql

使用命令

mysql -u root -p

在这里插入图片描述
创建数据库

create DATABASE test;

切换到 test 数据库

 use test;

在这里插入图片描述
输入要创建的表 datadump内容

 CREATE TABLE `datadump` (
        `uid` INT(10) NOT NULL AUTO_INCREMENT,
        `topic` VARCHAR(64) NULL DEFAULT NULL,
        `partition` INT(64) NULL DEFAULT NULL,
		`offset` INT(64) NULL DEFAULT NULL,
		`key` VARCHAR(64) NULL DEFAULT NULL,
		`value` VARCHAR(64) NULL DEFAULT NULL,
		`processedby` VARCHAR(64) NULL DEFAULT NULL,
        `createdat` VARCHAR(64) NULL DEFAULT NULL,
        PRIMARY KEY (`uid`)
    );

在这里插入图片描述

  • 启动一个终端,到代码目录下运行 go run send.go
    在这里插入图片描述
  • 新启动一个终端,到目录运行 go run test.go
    在这里插入图片描述
  • 查表select * from datadump
    在这里插入图片描述
    如图所示,kafka 发送的消息,被写入了 mysql 的表中。

四、问题说明

1、mysql 无法连接,sql.Open 失败;
2、mysql 连接拒绝,Ping() 不同;
以上问题可以尝试重新安装 mysql 后,重启电脑尝试;
3、mysql “table doesn’t exist”,进入 mysql, 新建数据库和表。

操作过程中遇到问题难免,沉住气,多尝试,可以搜索一下看是否能够获取到解决问题的思路。

五、参考资料

https://github.com/abhirockzz/accs-go-kafka-mysql
http://www.runoob.com/mysql/mysql-create-tables.html

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值