二、go-kit 与 grpc 结合开发微服务

本贴最后更新于 2399 天前,其中的信息可能已经时移俗易

介绍

go-kit 是一个微服务的开发工具集,微服务系统中的大多数常见问题,因此,使用者可以将精力集中在业务逻辑上。

grpc 缺乏服务治理的功能,我们可以通过 go-kit 结合 grpc 来实现我们的完整需求。go-kit 抽象的 endpoint 设计让我们可以很容易包装其它微服务框架使用的协议。

go-kit 提供以下功能:

1、Circuit breaker(熔断器)

2、Rate limiter(限流器)

3、Logging(日志)

4、Metrics(Prometheus 统计)

5、Request tracing(请求跟踪)

6、Service discovery and load balancing(服务发现和负载均衡)


安装 go 包

git clone https://github.com/go-kit/kit.git

封装 grpc 服务

之前已经搭建过 grpc 的一个微服务实例 BookServer,我们在此服务的基础上包装 go-kit

go-kit [TransportServer]

一个 Transport 的 Server 必须要拥有 endPoint、decodeRequestFunc、encodeResponseFunc

1、 endPoint 一个端点代表一个 RPC,也就是我们服务接口中的一个函数

2、 decodeRequestFunc 请求参数解码函数

3、 encodeResponseFunc 返回参数编码函数

请求流程:
请求->decodeRequestFunc -> endPoint -> encodeResponseFunc -> 返回输出

/**
bookListHandler := grpc_transport.NewServer(
   makeGetBookListEndpoint(),
   decodeRequest,
   encodeResponse,
)
*/

// 创建一个endPoint
func makeGetBookInfoEndpoint() endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (interface{}, error) {
		req := request.(*book.BookInfoParams)
		b := new(book.BookInfo)
		b.BookId = req.BookId
		b.BookName = "21天精通php"
		return b, nil
	}
}

// 请求数据解码函数
func decodeRequest(_ context.Context, req interface{}) (interface{}, error) {
	return req, nil
}

// 返回数据编码函数
func encodeResponse(_ context.Context, rsp interface{}) (interface{}, error) {
	return rsp, nil
}

完整代码

package main

import (
	"context"
	"github.com/go-kit/kit/endpoint"
	grpc_transport "github.com/go-kit/kit/transport/grpc"
	"google.golang.org/grpc"
	"grpc-test/pb"
	"net"
)

type BookServer struct {
	bookListHandler grpc_transport.Handler
	bookInfoHandler grpc_transport.Handler
}

// 通过grpc调用GetBookInfo时,GetBookInfo只做数据透传, 调用BookServer中对应Handler.ServeGRPC转交给go-kit处理
func (s *BookServer) GetBookInfo(ctx context.Context, in *book.BookInfoParams) (*book.BookInfo, error) {
	_, rsp, err := s.bookInfoHandler.ServeGRPC(ctx, in)
	if err != nil {
		return nil, err
	}
	return rsp.(*book.BookInfo), err
}

// 通过grpc调用GetBookList时,GetBookList只做数据透传, 调用BookServer中对应Handler.ServeGRPC转交给go-kit处理
func (s *BookServer) GetBookList(ctx context.Context, in *book.BookListParams) (*book.BookList, error) {
	_, rsp, err := s.bookListHandler.ServeGRPC(ctx, in)
	if err != nil {
		return nil, err
	}
	return rsp.(*book.BookList), err
}

// 创建bookList的EndPoint
func makeGetBookListEndpoint() endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (interface{}, error) {
		//请求列表时返回 书籍列表
		bl := new(book.BookList)
		bl.BookList = append(bl.BookList, &book.BookInfo{BookId: 1, BookName: "21天精通php"})
		bl.BookList = append(bl.BookList, &book.BookInfo{BookId: 2, BookName: "21天精通java"})
		return bl, nil
	}
}

// 创建bookInfo的EndPoint
func makeGetBookInfoEndpoint() endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (interface{}, error) {
		//请求详情时返回 书籍信息
		req := request.(*book.BookInfoParams)
		b := new(book.BookInfo)
		b.BookId = req.BookId
		b.BookName = "21天精通php"
		return b, nil
	}
}

func decodeRequest(_ context.Context, req interface{}) (interface{}, error) {
	return req, nil
}

func encodeResponse(_ context.Context, req interface{}) (interface{}, error) {
	return req, nil
}

func main() {
	//包装BookServer

	bookServer := new(BookServer)
	//创建bookList的Handler
	bookListHandler := grpc_transport.NewServer(
		makeGetBookListEndpoint(),
		decodeRequest,
		encodeResponse,
	)
	//bookServer 增加 go-kit流程的 bookList处理逻辑
	bookServer.bookListHandler = bookListHandler

	//创建bookInfo的Handler
	bookInfoHandler := grpc_transport.NewServer(
		makeGetBookInfoEndpoint(),
		decodeRequest,
		encodeResponse,
	)
	//bookServer 增加 go-kit流程的 bookInfo处理逻辑
	bookServer.bookInfoHandler = bookInfoHandler

	//启动grpc服务
	serviceAddress := ":50052"
	ls, _ := net.Listen("tcp", serviceAddress)
	gs := grpc.NewServer()
	book.RegisterBookServiceServer(gs, bookServer)
	gs.Serve(ls)
}

测试

启动服务端,客户端代码不做改变还以我们之前的 grpc 客户端实例代码启动。

GOROOT=D:\Go #gosetup

GOPATH=D:\go\gopath #gosetup
D:\Go\bin\go.exe build -i -o C:\Users\Administrator\AppData\Local\Temp\___8373go_build_main_go.exe D:/go/gopath/src/grpc-test/client/main.go #gosetup
D:\软件\GoLand\bin\runnerw.exe C:\Users\Administrator\AppData\Local\Temp\___8373go_build_main_go.exe #gosetup
获取书籍详情
bookId: 1  =>  bookName: 21天精通php
获取书籍列表
bookId: 1  =>  bookName: 21天精通php
bookId: 2  =>  bookName: 21天精通java

Process finished with exit code 0
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 285 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • gRpc
    11 引用 • 9 回帖 • 73 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...