后台內部通訊采用的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,
https://yq.aliyun.com/articles/277584?utm_content=m_36090
https://help.aliyun.com/document_detail/32460.html?spm=a2c4g.11186623.6.547.254963270z7HbG
但是反向代理給業務的時候還是用的http1.1,grpc服務端只能識別http2的,所以完蛋。。。
nginx早在2018年就支持grpc代理了,阿里雲的支持不知何年何月。。。
