grpc-gateway
grpc-gateway 顧名思義是專門是grpc的網(wǎng)關(guān)。也是一個(gè)protobuf的編譯器,是一個(gè)proto的插件。 grpc-gateway就是將http請(qǐng)求處理后轉(zhuǎn)發(fā)到對(duì)應(yīng)grpc服務(wù)上。很多瀏覽器,或者客戶端開箱不支持grpc,只支持傳統(tǒng)的restful API。 grpc網(wǎng)關(guān)而且也支持負(fù)載,兼容不同版本。
官方文檔
grpc-gateway
源碼
架構(gòu)
大致流程如下
-
寫好服務(wù)的proto文件。(代理+grpc)
-
根據(jù)proto文件生成反向代理服務(wù)代碼
-
根據(jù)proto文件生成grpc服務(wù)存根
-
啟動(dòng)反向代理和grpc
-
客戶端使用http json訪問 或別的restful api形式
環(huán)境安裝
protobuf
protobuf鏈接
下載對(duì)應(yīng)環(huán)境的porotbuf。解壓后bin路徑配置環(huán)境變量
插件安裝
博主 go 用的 1.19 + windows,預(yù)先安裝好protobuf
go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc- gateway@v2.12.0
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.2
可以把對(duì)應(yīng)GO_PATH bin下插件的二進(jìn)制文件拷到對(duì)應(yīng)go安裝的bin目錄下
grpc+默認(rèn)網(wǎng)關(guān)測(cè)試
proto文件
echo.proto
syntax = "proto3";
package echo;
option go_package = "echo/proto";
message User{
int64 id = 1;
string name = 2;
int32 age = 3;
string phone = 4;
Addr addr = 5;
}
message Addr {
string province = 1;
string city = 2;
string county = 3;
}
service Echo{
rpc Get(User) returns (User) {}
rpc AddOrUpdate(User) returns (User) {}
rpc Delete(User) returns (User) {}
}
生成grpc stub
# 生成message
protoc --proto_path=proto --go_out=proto --go_opt=paths=source_relative proto/echo.proto
# 生成grpc service
protoc --proto_path=proto --go-grpc_out=proto --go-grpc_opt=paths=source_relative proto/echo.proto
生成默認(rèn)網(wǎng)關(guān)
# 生成gateway protoc --proto_path=proto --grpc-gateway_out=proto --grpc-gateway_opt logtostderr=true --grpc-gateway_opt paths=source_relative --grpc-gateway_opt generate_unbound_methods=true proto/echo.proto
grpc服務(wù)器代碼
server.go
package server
import (
"context"
"echo/proto"
"fmt"
)
type echoServer struct {
proto.UnimplementedEchoServer
}
func NewServer() proto.EchoServer {
return &echoServer{}
}
func (s *echoServer) Get(ctx context.Context, in *proto.User) (*proto.User, error) {
fmt.Printf("%+v\n", in)
return in, nil
}
func (s *echoServer) AddOrUpdate(ctx context.Context, in *proto.User) (*proto.User, error) {
fmt.Printf("%+v\n", in)
return in, nil
}
func (s *echoServer) Delete(ctx context.Context, in *proto.User) (*proto.User, error) {
fmt.Printf("%+v\n", in)
return in, nil
}
gateway代碼
這里直接用官網(wǎng)http代理的代碼。需要修改端口和引用自己的grpc服務(wù)和網(wǎng)關(guān)package
gateway.go
package gateway
import (
"context"
"flag"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
_ "google.golang.org/grpc/grpclog"
gw "echo/proto" // Update
)
var (
// command-line options:
// gRPC server endpoint
grpcServerEndpoint = flag.String("grpc-server-endpoint", "localhost:50051", "gRPC server endpoint")
)
func Run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// Register gRPC server endpoint
// Note: Make sure the gRPC server is running properly and accessible
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithTransportCredentials(insecure.NewCredentials())}
// 注冊(cè)對(duì)應(yīng)grpc服務(wù)端點(diǎn)handler
err := gw.RegisterEchoHandlerFromEndpoint(ctx, mux, *grpcServerEndpoint, opts)
if err != nil {
return err
}
// Start HTTP server (and proxy calls to gRPC server endpoint)
return http.ListenAndServe(":8081", mux)
}
測(cè)試
main.go
package main
import (
"context"
"echo/echo_server/gateway"
"echo/echo_server/server"
"echo/proto"
"fmt"
"google.golang.org/grpc"
"log"
"net"
"os"
"os/signal"
"time"
)
func main() {
// 先啟動(dòng)grpc service
go func() {
if err := run(); err != nil {
log.Fatal(err)
}
}()
time.Sleep(time.Second * 2)
//后啟動(dòng)gateway
go func() {
if err := gateway.Run(); err != nil {
log.Fatal(err)
}
}()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, os.Kill)
defer stop()
<-ctx.Done()
}
func run() error {
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatal(err)
}
s := grpc.NewServer()
userServiceServer := server.NewServer()
proto.RegisterEchoServer(s, userServiceServer)
fmt.Println("listening ")
return s.Serve(lis)
}
默認(rèn)路由
路由為proto文件中{包名}.{服務(wù)名}/{方法}。 gateway對(duì)外默認(rèn)是post方法
PS D:\GIT\gorun\grpc-gateway-practice\echo> Invoke-RestMethod -Uri "http://10.5.81.57:8081/echo.Echo/Get" -Method Post
id : 0
name :
age : 0
phone :
addr :
用postman更方便些
總結(jié)
-
grpc-gateway 只是提供一個(gè)反向代理,可以通過配置進(jìn)行g(shù)rpc版本兼容。文章來源:http://www.zghlxwxcb.cn/news/detail-719417.html
-
grpc-gateway對(duì)外提供restful API風(fēng)格的http接口,更好兼容各種客戶端接入,無需grpc客戶端文章來源地址http://www.zghlxwxcb.cn/news/detail-719417.html
到了這里,關(guān)于golang 工程組件:grpc-gateway 環(huán)境安裝+默認(rèn)網(wǎng)關(guān)測(cè)試的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!