铁匠 铁匠
首页
golang
java
架构
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

铁匠

不予评判的专注当下
首页
golang
java
架构
常用算法
  • Java
  • nginx
  • 系统运维
  • 系统安全
  • mysql
  • redis
参考文档
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • golang 入门学习指南
  • go-kit

    • go-kit学习指南 - 基础概念和架构
    • go-kit学习指南 - 多协议支持
      • 多协议支持好处
      • 实现步骤
        • 安装 grpc 编译工具
        • 定义 protobuf 协议
        • 编译protobuf
        • 参考代码
        • 启动服务
        • 测试
    • go-kit学习指南 - 中间件
    • go-kit开发微服务 - 服务注册与发现
  • go
  • go-kit
fengjx
2024-04-19
目录

go-kit学习指南 - 多协议支持

在上一章节的基础上,增加grpc协议支持,而无需改动之前代码。

# 多协议支持好处

  • 灵活性和适应性:不同的微服务可能需要使用不同的通信协议,例如 HTTP、gRPC、Thrift 等,支持多种协议可以使得系统更加灵活,根据需求选择合适的通信方式。
  • 技术选型自由:通过支持多种通信协议,开发者可以更自由地选择技术栈,不受限于特定的技术选型,有助于满足不同场景的需求。
  • 互操作性:支持多种通信协议可以使得服务更易于与其他系统进行交互,不受限于特定的协议,提高了系统的互操作性。
  • 性能优化:不同的通信协议适用于不同的场景,例如 gRPC 适用于高性能的内部通信,而 HTTP 适用于与外部系统进行通信,通过选择合适的协议可以更好地优化系统的性能。

go-kit 分层设计湿的多协议支持非常简单,这也体现出了分层设计的好处。只需要在Transport层增加一个对应协议Server即可。

在系统维护过程中,唯一不变的是变化,你不知道未来系统架构如何演进,一个可插拔的系统机制在未来重构时更加灵活。

# 实现步骤

示例代码: https://github.com/fengjx/go-kit-demo/tree/master/greetgrpc (opens new window)

# 安装 grpc 编译工具

  • protoc 安装:https://grpc.io/docs/protoc-installation/ (opens new window)
  • protoc grpc 插件安装:https://grpc.io/docs/languages/go/quickstart/ (opens new window)

# 定义 protobuf 协议

syntax = "proto3";
package pb;
option go_package="github.com/fengjx/go-kit-demo/greetgrpc/pb";

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloReq) returns (HelloResp) {}
}

// The request message containing the user's name.
message HelloReq {
  string name = 1;
}

// The response message containing the greetings
message HelloResp {
  string msg = 1;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 编译protobuf

cd pb
bash build.sh
1
2

编译后会生成 greet.pb.go 和 greet_grpc.pb.go 两个文件

$ ls    
build.sh greet.pb.go greet.proto greet_grpc.pb.go
1
2

# 参考代码

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net"
	"net/http"

	"github.com/go-kit/kit/endpoint"
	grpctransport "github.com/go-kit/kit/transport/grpc"
	httptransport "github.com/go-kit/kit/transport/http"
	"google.golang.org/grpc"

	"github.com/fengjx/go-kit-demo/greetgrpc/pb"
)

func main() {

	svc := greetService{}
	helloEndpoint := makeHelloEndpoint(svc)

	satHelloHandler := httptransport.NewServer(
		helloEndpoint,
		decodeRequest,
		encodeResponse,
	)

	startHTTPServer := func() {
		log.Println("http server start")
		http.Handle("/say-hello", satHelloHandler)
		log.Fatal(http.ListenAndServe(":8080", nil))
	}
	go startHTTPServer()

	// grpc server
	grpcServer := grpc.NewServer(grpc.UnaryInterceptor(grpctransport.Interceptor))
	pb.RegisterGreeterServer(grpcServer, newGreeterServer(helloEndpoint))
	startGRPCServer := func() {
		log.Println("grpc server start")
		ln, err := net.Listen("tcp", ":8000")
		if err != nil {
			panic(err)
		}
		log.Fatal(grpcServer.Serve(ln))
	}
	startGRPCServer()
}

type greetService struct {
}

func (svc greetService) SayHi(_ context.Context, name string) string {
	return fmt.Sprintf("hi: %s", name)
}

func makeHelloEndpoint(svc greetService) endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (interface{}, error) {
		req := request.(*pb.HelloReq)
		msg := svc.SayHi(ctx, req.Name)
		return &pb.HelloResp{
			Msg: msg,
		}, nil
	}
}

func decodeRequest(_ context.Context, r *http.Request) (interface{}, error) {
	name := r.URL.Query().Get("name")
	req := &pb.HelloReq{
		Name: name,
	}
	return req, nil
}

func encodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	data := map[string]any{
		"status": 0,
		"msg":    "ok",
		"data":   response,
	}
	return json.NewEncoder(w).Encode(data)
}

type GreeterServer struct {
	pb.UnimplementedGreeterServer
	sayHello grpctransport.Handler
}

func newGreeterServer(e endpoint.Endpoint) pb.GreeterServer {
	svr := &GreeterServer{}
	svr.sayHello = grpctransport.NewServer(
		e,
		svr.decodeSayHello,
		svr.encodeSayHello,
	)
	return svr
}

func (s *GreeterServer) SayHello(ctx context.Context, req *pb.HelloReq) (*pb.HelloResp, error) {
	_, resp, err := s.sayHello.ServeGRPC(ctx, req)
	if err != nil {
		return nil, err
	}
	return resp.(*pb.HelloResp), nil
}

func (s *GreeterServer) decodeSayHello(_ context.Context, req interface{}) (interface{}, error) {
	helloReq := req.(*pb.HelloReq)
	return &pb.HelloReq{
		Name: helloReq.Name,
	}, nil
}

func (s *GreeterServer) encodeSayHello(_ context.Context, resp interface{}) (interface{}, error) {
	return resp, nil
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

# 启动服务

go run main.go
1

# 测试

http 协议

# sya-hello
curl http://localhost:8080/say-hello?name=fengjx

{"data":{"msg":"hi: fengjx"},"msg":"ok","status":0}
1
2
3
4

grpc 协议

go run cmd/greetcli/mian.go

message -> hi: fengjx
1
2
3
#go-kit
Last Updated: 2024/05/12, 15:25:49
go-kit学习指南 - 基础概念和架构
go-kit学习指南 - 中间件

← go-kit学习指南 - 基础概念和架构 go-kit学习指南 - 中间件→

最近更新
01
go-kit学习指南 - 中间件
04-19
02
go-kit开发微服务 - 服务注册与发现
04-19
03
go-kit学习指南 - 基础概念和架构
04-18
更多文章>
Theme by Vdoing | Copyright © 2016-2024 铁匠 | 粤ICP备15021633号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式