后台内部通讯采用的grpc,最近要做一个外部业务,考虑是否也能使用grpc呢?
一、
先考虑的安全认证问题,看到一些资料,例如:
https://cloud.tencent.com/developer/article/1518977
https://www.jianshu.com/p/fa43c54df957
https://www.cnblogs.com/areful/p/10404982.html
基本就是两种:
1.ssl双向认证
2.通过拦截器,io.grpc.ClientInterceptor,io.grpc.ServerInterceptor
也就是安全方面没有问题
二、
简单写个例子,IDL描述
syntax = "proto3"; package payment; import "google/protobuf/wrappers.proto"; option java_package = "cn.company.grpc"; option java_multiple_files = true; option java_outer_classname = "PaymentPB"; message HelloResp { int32 res = 1; string msg = 2; } message HelloReq { google.protobuf.Int32Value id = 1; google.protobuf.Int32Value color = 2; google.protobuf.Int32Value type = 3; google.protobuf.Int32Value race = 4; google.protobuf.Int32Value cost = 5; } service payment { rpc hello(HelloReq) returns (HelloResp) {} }
客户端代码,先不带证书,单向认证尝试下
ManagedChannel channel = ManagedChannelBuilder.forTarget("pay.company.com").build(); paymentGrpc.newStub(channel).hello(HelloReq.newBuilder().setId(Int32Value.newBuilder().setValue(12345).build()).build(), new StreamObserver<HelloResp>() { @Override public void onNext(HelloResp value) { Trace.info("onNext {}", value); } @Override public void onError(Throwable t) { Trace.info("onError", t); } @Override public void onCompleted() { Trace.info("onCompleted"); } });
服务端代码
NettyServerBuilder.forAddress(new InetSocketAddress(NetUtils.getLocalIP(), port)).addService(new paymentGrpc.paymentImplBase() { @Override public void hello(HelloReq request, StreamObserver<HelloResp> responseObserver) { responseObserver.onNext(HelloResp.newBuilder().setRes(1).setMsg("my friend").build()); responseObserver.onCompleted(); }}).build().start();
开发环境测试,肯定是没有问题,都是成熟套路
三、
然而生产环境是在阿里云上,对外网关用的阿里云slb,查资料得知slb已经支持了http2,但是反向代理给业务的时候还是用的http1.1,
grpc服务端只能识别http2的,所以完蛋。。。
nginx早在2018年就支持grpc代理了,阿里云的支持不知何年何月。。。