grpc gateway 使用以及docker compose 集成
1. grpc gateway 安装
参考,比较简单,有需要的依赖可以参考相资料
mkdir tmp
cd tmp
git clone https://github.com/google/protobuf
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger
go get -u github.com/golang/protobuf/protoc-gen-go
2. 简单项目
a. 项目结构
├── Dockerfile
├── Gopkg.lock
├── Gopkg.toml
├── README.md
├── docker-compose.yml
├── main.go
├── pb
│ └── echoservice.proto
├── rpcserver
│ ├── Dockerfile
│ ├── Gopkg.lock
│ ├── Gopkg.toml
│ ├── main.go
├── service
│ └── pb
│ ├── echoservice.pb.go
│ └── echoservice.pb.gw.go
b. probu编写(pb/echoservice.proto)
syntax="proto3";
package echoservice;
option go_package="echoservice";
import "google/api/annotations.proto";
service EchoService {
rpc Echo(EchoMessage) returns (EchoResponse) {
option (google.api.http) = {
post: "/v1/echo"
body: "*"
};
}
}
message EchoMessage{
string message=1;
}
message EchoResponse{
string message=1;
}
c. 生成gRPC stub以及gateway code
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:./service \
pb/echoservice.prot
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--grpc-gateway_out=logtostderr=true:./service \
pb/echoservice.prot
d. 实现grpc server
rpcserver/main.go
package main
import "context"
import pb "github.com/rongfengliang/restyapp/service/pb"
import grpc "google.golang.org/grpc"
import "net"
import "log"
type server struct{}
func (s *server) Echo(ctx context.Context, in *pb.EchoMessage) (*pb.EchoResponse, error) {
return &pb.EchoResponse{
Message: in.Message,
}, nil
}
func main() {
lis, err := net.Listen("tcp", "0.0.0.0:9000")
if err != nil {
log.Fatal("some wrong")
}
s := grpc.NewServer()
pb.RegisterEchoServiceServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatal("some wrong")
}
}
e. rpcserver dockerfile
# build stage
FROM golang:1.9-alpine AS build-env
RUN apk --no-cache add build-base git bzr mercurial gcc
ENV D=/go/src/github.com/rongfengliang/restyapp
ADD . $D
RUN cd $D && go build -o rpcserver && cp rpcserver /tmp/
FROM alpine:latest
WORKDIR /app
EXPOSE 9000
COPY --from=build-env /tmp/rpcserver /app/rpcserver
CMD ["./rpcserver"]
f. gateway code
package main
import (
"context"
"flag"
"net/http"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
gw "github.com/rongfengliang/restyapp/service/pb"
grpc "google.golang.org/grpc"
)
var (
echoEndpoint = flag.String("echo_endpoint", "rpcserver:9000", "endpoint of YourService")
)
func run2() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := gw.RegisterEchoServiceHandlerFromEndpoint(ctx, mux, *echoEndpoint, opts)
if err != nil {
return err
}
return http.ListenAndServe(":8089", mux)
}
func main() {
flag.Parse()
defer glog.Flush()
if err := run2(); err != nil {
glog.Fatal(err)
}
}
g. gateway dockerfile
# build stage
FROM golang:1.9-alpine AS build-env
RUN apk --no-cache add build-base git bzr mercurial gcc
ENV D=/go/src/github.com/rongfengliang/restyapp
ADD . $D
RUN cd $D && go build -o gwserver && cp gwserver /tmp/
FROM alpine:latest
WORKDIR /app
EXPOSE 8089
COPY --from=build-env /tmp/gwserver /app/gwserver
CMD ["./gwserver"]
h. docker-compose file
version: '3'
services:
rpcserver:
image: rpcserver
build:
context: ./rpcserver
gwserver:
image: gwserver
ports:
- 8089:8089
build:
context: .
depends_on:
- rpcserver
备注:构建使用了docker stage 依赖使用vendor 方式,简单依赖的处理
3. 运行
docker-compose build
docker-compose up -d
从构建的大小来看,还是比较小的,可以节省好多资源
4. 测试
post http://localhost:8089/v1/echo
content-type:application/json
data: {"message":"demoinfo"}
5. 参考资料
https://github.com/grpc-ecosystem/grpc-gateway
https://github.com/rongfengliang/restyapp