在 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 上注册的全过程。