1、流程
2、Demo
2.1、grpc server实现
- proto
syntax = "proto3";
package helloworld;
import "google/api/annotations.proto";
service Greet {
rpc Say (HelloWorldRequest) returns (HelloWorldResponse) {
option (google.api.http) = {
post: "/say"
body: "Name"
};
}
}
message HelloWorldRequest{
string Name=1;
}
message HelloWorldResponse{
string HelloName=1;
}
- protoc(注意需要引入annotations.proto路径,负责无法编译通过,下载protoc,解压后包含include和bin文件夹)
protoc ./helloworld.proto -ID:\protoc-3.7.0-rc-3-win64\include -I. --go_out=plugins=grpc:.
- 根据编译后生成的helloworld.pb.go文件构建服务端
const (
port = ":8080"
)
type server struct{}
func (s *server) Say(ctx context.Context, request *helloworld.HelloWorldRequest) (*helloworld.HelloWorldResponse, error) {
return &helloworld.HelloWorldResponse{HelloName:"hello"+request.Name},nil
}
func main() {
fmt.Println("program starting......!")
lis, err := net.Listen("tcp", port)
if err != nil {
panic("failed to listen")
}
s := grpc.NewServer()
helloworld.RegisterGreetServer(s, &server{})
if err := s.Serve(lis); err != nil {
panic("failed to serve")
}
fmt.Println("program ending......")
}
- 构建服务端镜像(git项目中的build.sh文件,然后运行docker build构建即可)
在构建过程中遇到"undefined: proto.ProtoPackageIsVersion3",解决方案为:
set GO111MODULE=on
go get github.com/golang/protobuf@master
go mod vendor(revendor)
2.2、envoy代理实现
- envoy.yaml
admin:
access_log_path: /tmp/admin_access.log
address:
socket_address: { address: 0.0.0.0, port_value: 9901 }
static_resources:
listeners:
- name: main-listener
address:
socket_address: { address: 0.0.0.0, port_value: 51051 }
filter_chains:
- filters:
- name: envoy.http_connection_manager
config:
stat_prefix: grpc_json
codec_type: AUTO
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains: ["*"]
routes:
- match: { prefix: "/", grpc: {} }
route: { cluster: grpc-backend-services, timeout: { seconds: 60 } }
http_filters:
- name: envoy.grpc_json_transcoder
config:
proto_descriptor: "/tmp/envoy/helloworld.pb"
services: ["helloworld.Greet"]
print_options:
add_whitespace: true
always_print_primitive_fields: true
always_print_enums_as_ints: false
preserve_proto_field_names: false
- name: envoy.router
clusters:
- name: grpc-backend-services
connect_timeout: 1.25s
type: logical_dns
lb_policy: round_robin
dns_lookup_family: V4_ONLY
http2_protocol_options: {}
hosts:
- socket_address:
address: go-grpc.dev.svc.cluster.local
port_value: 8080
-
build envoy image and run
FROM envoyproxy/envoy:latest
COPY envoy.yaml /etc/envoy/envoy.yaml
COPY helloworld.pb /tmp/envoy/helloworld.pb
docker run -it --name envoy -p 9901:9901 -p 51051:51051 envoy:v1
- http test
http://*.*.*.*:51051/say {"Name":""jinyidong}