[consul]微服务注册和发现

161 阅读2分钟

yiyan.baidu.com/chat/MjEzMT…

在 Go 中使用 Thrift 这种rpc框架编写一个微服务并在 Consul 上注册,涉及到几个步骤。

以下是完整的代码示例,包括 Thrift IDL 定义、服务实现(代码开发)、以及 Consul 注册逻辑。

1. 安装依赖

首先,确保你已经安装了以下依赖:

  • Go (1.16+)
  • Thrift (0.14+)
  • Consul (1.9+)
  • Consul SDK for Go

你可以使用以下命令安装 Go 依赖:

go get github.com/apache/thrift/lib/go/thrift

go get github.com/hashicorp/consul/api

定义

创建一个名为 service.thrift 的文件,定义你的 Thrift 服务:

namespace go my_service
 
service MyService {
    string Ping(),
}

3/生成 Thrift 代码

使用 Thrift 编译器生成 Go 代码:

thrift --gen go service.thrift

这将在当前目录生成一个 gen-go 目录,其中包含 Thrift 生成的代码。

4/实现 Thrift 服务

创建一个名为 server.go 的文件,并实现你的 Thrift 服务:

package main
 
import (
    "flag"
    "fmt"
    "log"
    "net"
 
    "github.com/apache/thrift/lib/go/thrift"
    "github.com/hashicorp/consul/api"
    myservice "path/to/your/gen-go/my_service"
)
 
// Implementation of the MyService interface
type MyServiceHandler struct{}
 
func (h *MyServiceHandler) Ping() (r string, err error) {
    return "pong", nil
}
 
func main() {
    port := flag.Int("port", 9090, "Server port")
    consulAddr := flag.String("consul", "127.0.0.1:8500", "Consul address")
    serviceName := flag.String("service", "my_service", "Service name")
    flag.Parse()
 
    // Register service with Consul
    consulClient, err := api.NewClient(api.DefaultConfig())
    if err != nil {
        log.Fatalf("Error creating Consul client: %v", err)
    }
    catalog := consulClient.Catalog()
    registration := &api.AgentServiceRegistration{
        ID:      *serviceName,
        Name:    *serviceName,
        Address: "127.0.0.1",
        Port:    *port,
        Tags:    []string{"thrift"},
        Check: &api.AgentServiceCheck{
            TTL: "15s",
        },
    }
    if err := catalog.Register(registration, nil); err != nil {
        log.Fatalf("Error registering service with Consul: %v", err)
    }
 
    // Set up Thrift server
    processor := myservice.NewMyServiceProcessor(new(MyServiceHandler))
    transportFactory := thrift.NewTBufferedTransportFactory(8192)
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
 
    serverSocket, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
    if err != nil {
        log.Fatalf("Unable to listen on port %d: %v", *port, err)
    }
 
    server := thrift.NewTSimpleServer4(processor, serverSocket, transportFactory, protocolFactory)
 
    // Start a goroutine to keep the service registered in Consul
    go func() {
        checkID := *serviceName + "-check"
        check := &api.AgentCheckRegistration{
            ID:        checkID,
            Name:      checkID,
            ServiceID: *serviceName,
            TTL:       "15s",
        }
        if err := consulClient.Agent().CheckRegister(check); err != nil {
            log.Fatalf("Error registering TTL check with Consul: %v", err)
        }
        for {
            if err := consulClient.Agent().PassTTL(checkID, ""); err != nil {
                log.Printf("Error passing TTL check: %v", err)
            }
            time.Sleep(10 * time.Second)
        }
    }()
 
    fmt.Printf("Starting the simple server...\n")
    if err := server.Serve(); err != nil {
        log.Fatalf("Error starting server: %v", err)
    }
}

注意:

  • 请将 path/to/your/gen-go/my_service 替换为实际生成的 Thrift Go 代码路径。
  • TTL 检查确保服务在 Consul 中保持注册状态。

5. 运行服务

确保 Consul 正在运行,然后运行你的 Go 服务: go run server.go -port=9090 -consul=127.0.0.1:8500 现在,你的 Thrift 服务应该正在运行并在 Consul 上注册。你可以使用 Consul 的 Web UI 或 CLI 工具来验证服务注册情况。

6/测试服务

创建一个客户端来测试你的服务。例如,创建一个名为 client.go 的文件:

package main
 
import (
    "flag"
    "fmt"
    "log"
    "net"
 
    "github.com/apache/thrift/lib/go/thrift"
    myservice "path/to/your/gen-go/my_service"
)
 
func main() {
    address := flag.String("address", "127.0.0.1:9090", "Thrift server address")
    flag.Parse()
 
    transport, err := thrift.NewTSocket(net.JoinHostPort(*address, "9090"))
    if err != nil {
        log.Fatalf("Error creating socket: %v", err)
    }
    transportFactory := thrift.NewTBufferedTransportFactory(8192)
    transport = transportFactory.GetTransport(transport)
    protocolFactory := thrift.NewTBinaryProtocolFactoryDefault()
    client := myservice.NewMyServiceClientFactory(transport, protocolFactory)
 
    if err := transport.Open(); err != nil {
        log.Fatalf("Error opening transport: %v", err)
    }
    defer transport.Close()
 
    pingResult, err := client.Ping()
    if err != nil {
        log.Fatalf("Error calling Ping: %v", err)
    }
    fmt.Printf("Ping result: %s\n", pingResult)
}

运行客户端来测试服务:


go run client.go -address=127.0.0.1:9090

如果一切正常,你应该会看到输出 Ping result: pong。

这样,你就完成了一个使用 Thrift 框架编写的微服务,并在 Consul 上注册的全过程。