go-micro框架一文速通
Go Micro 满足分布式系统开发的核心需求,包括 RPC 和事件驱动通信(pub/sub)。Go Micro的主要特点是可插拔的架构,每个分布式系统都是可插拔的,有合理的默认值,且可以轻松替换。此外,它的消息编码支持protobuf和json,有诸如服务注册和发现、负载均衡等功能,且支持异步消息传递的发布订阅模式。
快速入门
bash
go get "go-micro.dev/v5"服务注册
简单创建一个服务并注册处理程序:
go
package main
import (
"context"
"go-micro.dev/v5"
)
type Request struct {
Name string `json:"name"`
}
type Response struct {
Greeting string `json:"greeting"`
}
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *Request, rsp *Response) error {
rsp.Greeting = "Hello " + req.Name
return nil
}
func main() {
service := micro.New("helloworld")
service.Handle(new(Say))
service.Run()
}运行之后输出日志:
2025-10-27 10:11:42 file=go-micro-demo/main.go:31 level=info Starting [service] helloworld
2025-10-27 10:11:42 file=service/service.go:95 level=info Transport [http] Listening on [::]:41184
2025-10-27 10:11:42 file=service/service.go:95 level=info Broker [http] Connected to 127.0.0.1:41185
2025-10-27 10:11:43 file=server/rpc_server.go:561 level=info Registry [mdns] Registering node: helloworld-165cd449-0a4d-4bf9-9eae-75b5894ef7e3可以看到自动分配了两个端口:
- 服务的网络监听端口(Transport [http] Listening on [::]:41184): 微服务(Server)真正接收 RPC 调用的地址,默认HTTP协议,其他服务通过注册中心(如etcd/consul)可以发现这个地址,进行调用。
- 消息代理使用的端口(Broker [http] Connected to 127.0.0.1:41185):Broker 是 go-micro 中的消息总线(Pub/Sub 发布订阅系统),默认使用 HTTP Broker;负责接收或转发消息事件(异步通信)
遗憾的是自动分配的端口无法获取,所以推荐设置默认端口:
go
func main() {
service := micro.NewService(
micro.Name("helloworld"),
micro.Address(":8080"),
)
service.Handle(new(Say))
service.Run()
}当然,broker也可以设置:
go
func main() {
b := broker.NewHttpBroker(broker.Addrs(":8082"))
if err := b.Connect(); err != nil {
log.Fatal(err)
}
service := micro.NewService(
micro.Name("greeter"),
micro.Address(":8081"),
micro.Broker(b), // 使用我们自定义的 Broker
)
service.Handle(new(Say))
service.Run()
}我们使用curl来模拟一下http客户端请求:
bash
curl -XPOST -H 'Content-Type: application/json'-H 'Micro-Endpoint: Say.Hello' -d '{"name": "John"}' http://localhost:8081结果:
json
{"greeting":"Hello John"}发布订阅
前面的示例中,我们简单实现了一个自定义的http broker,监听8082端口。我们通过它来实现发布订阅。需要说明的是: http broker 不会接收自己发布的消息,因为go-micro 的设计是广播模型,不做本地回环,故而单进程内的 Pub/Sub 无效。 所以我们需要启动两个进程,来分别实现发布和订阅
发布者:
go
package main
import (
"encoding/json"
"log"
"time"
"go-micro.dev/v5/broker"
)
type Message struct {
Name string `json:"name"`
}
func PubMsg(b broker.Broker, topic string, msg any) (err error) {
data, err := json.Marshal(msg)
if err != nil {
log.Printf("消息序列化失败%v: \n", err)
return err
}
err = b.Publish(topic, &broker.Message{
Header: map[string]string{"Content-Type": "application/json"},
Body: data,
})
if err != nil {
log.Printf("发布消息失败%v: \n", err)
return err
}
println("发布消息: ", string(data))
return
}
func main() {
b := broker.NewHttpBroker(broker.Addrs(":8082"))
if err := b.Connect(); err != nil {
log.Fatal(err)
}
defer b.Disconnect()
for {
msg := Message{Name: "World" + time.Now().Format("15:04:05")}
PubMsg(b, "greeter.topic", msg)
time.Sleep(5 * time.Second)
}
}订阅者:
go
package main
import (
"log"
"go-micro.dev/v5/broker"
)
func main() {
b := broker.NewHttpBroker(broker.Addrs("127.0.0.1:8082"))
if err := b.Connect(); err != nil {
log.Fatal(err)
}
defer b.Disconnect()
// 订阅主题
println("sub2开始订阅主题 greeter.topic")
_, err := b.Subscribe("greeter.topic", func(p broker.Event) error {
msg := p.Message()
log.Printf("收到消息: %s\n", string(msg.Body))
return nil
})
if err != nil {
log.Fatalf("订阅失败: %v", err)
}
<-make(chan struct{})
}如果要实现多订阅,v5版本可能需要使用其他 broker(如 NATS、RabbitMQ、MQTT)。