go语言grpc框架实战-01-客户端和服务端双向认证,借助grpc-gateway支持grpc和http服务

创建proto中间文件

  1. protobuf(protocol buffer)特点
    性能高、压缩好、传输快、维护方便,一些第三方rpc库都会支持protobuf

  2. 下载protobuf
    go get google.golang.org/protobuf
    注意:如果先下载grpc会默认下载protobuf
    go get google.golang.org/grpc

  3. 安装protoc编译器,将proto文件编译成指定语言的代码文件(通用编译器)
    下载网址
    protoc-3.20.1-win64.zip

  4. 下载解压后将protoc.exe所在的bin目录添加到系统环境变量当中去
    E:\protoc\bin

  5. 安装protobuf的编译器插件protoc-gen-go,等下我们执行protoc命令时就会自动调用这个插件生成go代码
    go install google.golang.org/protobuf/cmd/protoc-gen-go

  6. 安装goland的proto插件(goland 2022.1默认安装了grpc和proto的支持)

  7. 创建中间文件 hello.proto

syntax="proto3";  // 使用的proto 3的版本
package services;  // 生成go文件的包名
option go_package="../services";  // 指定生成go文件所在当前文件的路径

message ProdRequest{
  int32 prod_id = 1;  // 传入的商品id
}
message ProdResponse{
  int32 prod_stock = 1;  // 商品库存
}
  • 执行命令生成Prod.pb.go文件
    protoc --go_out=services .\pbfiles\Prod.proto
  1. 文件目录

创建grpc服务并运行

  1. 原Prod.proto文件增加一个服务
service ProdService{  // 获取商品库存服务
  rpc GetProdStock(ProdRequest) returns (ProdResponse);
}
  1. 生成支持grpc的Prod.pb.go文件还需要下载安装一个插件protoc-gen-go-grpc.exe
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
  1. 重新生成Prod.pb.go文件
    protoc --go_out=plugins=grpc:services .\pbfiles\Prod.proto -I .\pbfiles\

  2. 自行实现GetProdStock服务接口,在services目录创建文件:ProdService.go

package services

import (
	"context"
)

type ProdService struct {
	UnimplementedProdServiceServer
}

func (ProdService) GetProdStock(context.Context, *ProdRequest) (*ProdResponse, error) {
	return new(ProdResponse), nil
}
  1. 根目录创建server.go文件
package main

import (
	"google.golang.org/grpc"
	"grpc_test/services"
	"net"
)

func main() {
	// NewServer 创建一个未注册服务且尚未开始接受请求的 gRPC 服务器。
	rpcServer := grpc.NewServer()

	// 将当前产品服务注册到grpc服务当中去
	services.RegisterProdServiceServer(rpcServer, new(services.ProdService))

	// 监听套接字
	listener, _ := net.Listen("tcp", ":8080")

	// grpc服务器通过传入的监听套接字接收请求,开始基于http2.0提供服务
	rpcServer.Serve(listener)
}

自签证书,服务加入证书验证

使用自签ca server client证书和双向认证

客户端和服务端各自使用各自的证书,同时使用ca证书进行验签
参考文档

双向认证下rpc-gateway的使用(同时提供rpc和http接口)

  1. 安装
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
go get github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
go mod tidy
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway
go install 
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2
  1. 修改我们的Prod.proto文件,增加http接口支持
syntax = "proto3";  // 使用的proto 3的版本
package services;  // 生成go文件的包名
option go_package = "../services";  // 指定生成go文件所在当前文件的路径

import "google/api/annotations.proto";  // 新增加的

message ProdRequest{
  int32 prod_id = 1;  // 传入的商品id
}
message ProdResponse{
  int32 prod_stock = 1;  // 商品库存
}

service ProdService{// 获取商品库存服务
  rpc GetProdStock(ProdRequest) returns (ProdResponse) {
    option (google.api.http) = {  // 新增加的
      get : "/v1/prod/{prod_id}"
    };
  }
}

  1. 将相关的proto文件拷贝到我们的本地,如图

  2. 执行protoc命令,重新生成Prod.pb.go文件
    protoc --go_out=plugins=grpc:services .\pbfiles\Prod.proto -I .\pbfiles\

  3. 生成Prod.pb.gw.go文件
    protoc --grpc-gateway_out=logtostderr=true:services .\pbfiles\Prod.proto -I .\pbfiles\

  4. server.go代码提供grpc服务

点击查看代码
package main

import (
	"google.golang.org/grpc"
	"grpc_test/helper"
	"grpc_test/services"
	"net"
)

func main() {
	creds := helper.GetServerCreds()

	// NewServer 创建一个未注册服务且尚未开始接受请求的 gRPC 服务器。
	rpcServer := grpc.NewServer(grpc.Creds(creds))

	// 将当前产品服务注册到grpc服务当中去
	services.RegisterProdServiceServer(rpcServer, new(services.ProdService))

	// 监听套接字
	listener, _ := net.Listen("tcp", ":8080")
	//// grpc服务器接收请求,开始提供服务
	rpcServer.Serve(listener)

}

  1. httpserver.go代码提供http服务
点击查看代码
package main

import (
	"context"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc"
	"grpc_test/helper"
	"grpc_test/services"
	"log"
	"net/http"
)

func main() {
	gwmux := runtime.NewServeMux()
	opts := []grpc.DialOption{grpc.WithTransportCredentials(helper.GetClientCreds())}
	// endpoint: 是grpc服务器的地址
	err := services.RegisterProdServiceHandlerFromEndpoint(context.Background(), gwmux, "127.0.0.1:8080", opts)
	if err != nil {
		log.Fatal(err.Error())
	}

	httpServer := http.Server{Addr: "127.0.0.1:8081", Handler: gwmux}
	httpServer.ListenAndServe()
}

浏览器访问试试吧:http://127.0.0.1:8081/v1/prod/38
同时grpc客户端访问也可以,至此,借助grpc-gateway完成了同时提供grpc和http接口

posted @ 2022-05-08 14:38  专职  阅读(213)  评论(0编辑  收藏  举报