创建proto中间文件

go get google.golang.org/protobufgo get google.golang.org/grpcE:\protoc\bingo install google.golang.org/protobuf/cmd/protoc-gen-go
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;  // 商品库存
}
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
protoc --go_out=plugins=grpc:services .\pbfiles\Prod.proto -I .\pbfiles\
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}"
    };
  }
}

protoc --go_out=plugins=grpc:services .\pbfiles\Prod.proto -I .\pbfiles\protoc --grpc-gateway_out=logtostderr=true:services .\pbfiles\Prod.proto -I .\pbfiles\
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接口