Go 语言和事件驱动架构

1,177 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

原文:Golang and Event-Driven Architecture - DZone Microservices

作者: Tamimi Ahmad 有删改

对于我们这些 Go 爱好者来说,我们真正意义上理解使用 Go 开发应用和微服务的美是因为它的轻量性、高性能、优雅的语法等等。

假设使用你最喜欢的编程语言(没错,说的是Go),你喜欢的架构(没错,说的是事件驱动的架构) - 怎么开始编写代码?继续阅读并进一步探索。

等一等,什么是事件驱动架构(EDA)?

问得好!网上有大量的文章谈到了eda。其核心本质是,事件驱动的架构涉及应用程序之间的异步通信,使用一个消息中介基于消息订阅交换数据。

举几个例子,比如MQTT,AMQP和JMS。

更深入的了解事件驱动架构请参考 什么是事件驱动架构.

fmt.Println("Show me the CODE!")

我们从宏观上说明了EDA的概念,现在让我们从业务代码中看看具体的使用。从下面的这个开始。

  1. Paho MQTT 的 Golang 库.

代码可以在该 Github仓库查看。

开始动手

新建一个 go mod 并初始化。

MQTT

根据定义:“MQTT是用于物联网的OASIS标准消息传输协议(IOT)。它是一种极其轻型的发布/订阅消息传递传输,它是低带宽设备的完美选择。

Eclipse Paho提供开源的以各种编程语言实现的 MQTT客户端。今天的代码中,我们要使用Eclipse Paho MQTT Go Client.

安装 MQTT 库

go get github.com/eclipse/paho.mqtt.golang

创建一个新的文件,并用你最喜欢的 IDE 打开. 我把这个命名成了 go_mqtt.go.

编辑文件导入相关的必要包:

package main

import (
    "fmt"
    "time"

    mqtt "github.com/eclipse/paho.mqtt.golang"
)

main() 函数, 通过如下方式开始:

  1. 创建一个 MQTT client 并完成配置.

  2. 添加相关的事件回调函数:

    1. 接受消息.
    2. 连接服务器成功.
    3. 与服务器失联.
  3. 订阅 topic.

  4. 向 topic 发布.

func main() {
    var broker = "public.messaging.solace.cloud"
    var port = 1883
    opts := mqtt.NewClientOptions()
    opts.AddBroker(fmt.Sprintf("tcp://%s:%d", broker, port))
    opts.SetUsername("conf42")
    opts.SetPassword("public")
    opts.SetDefaultPublishHandler(messageHandler)
    opts.OnConnect = connectHandler
    opts.OnConnectionLost = connectLostHandler
    client := mqtt.NewClient(opts)
    if token := client.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
    }

    sub(client)
    publish(client)

    client.Disconnect(250)
}

像如下方式定义回调函数:

var messageHandler mqtt.MessageHandler = func(client mqtt.Client, msg mqtt.Message) {
    fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
}

var connectHandler mqtt.OnConnectHandler = func(client mqtt.Client) {
    options := client.OptionsReader()
    fmt.Println("Connected to: ", options.Servers())
}

var connectLostHandler mqtt.ConnectionLostHandler = func(client mqtt.Client, err error) {
    fmt.Printf("Connect lost: %v", err)
}

值得注意的是,这些函数会被特别的操作触发。比如说,MQTT client 通过 MQTT.MESSAGEHANDERNLER 接受消息,将触发MessageHandler 函数。

最后,定义发布和订阅函数,如下:

func publish(client mqtt.Client) {
    num := 10
    for i := 0; i < num; i++ {
        text := fmt.Sprintf("Message %d", i)
        token := client.Publish("conf42/go", 0, false, text)
        token.Wait()
        time.Sleep(time.Second)
    }
}

func sub(client mqtt.Client) {
    topic := "conf42/#"
    token := client.Subscribe(topic, 1, nil)
    token.Wait()
    fmt.Printf("Subscribed to topic: %s\n", topic)
}

OK,现在尝试运行并观察结果。

go run go_mqtt.go

大功告成