RPC 流程
- 1始绍、服務(wù)調(diào)用方(Client)將遠(yuǎn)程方法的信息(如類名捏题、方法方法名抹沪、方法傳入的參數(shù))封裝為統(tǒng)一的請求體洋闽;
- 2、序列化請求對象休涤,轉(zhuǎn)化為二進(jìn)制串产艾,方便傳輸;
- 3滑绒、通過 Client Stub 發(fā)送消息到指定的服務(wù)提供方;
- 4隘膘、Server Stub 接收來自 Client 的消息疑故;
- 5、反序列化二進(jìn)制串弯菊,轉(zhuǎn)化為對象纵势,方便使用;
- 6、根據(jù)請求體钦铁,執(zhí)行本地方法软舌;
- 7、封裝方法執(zhí)行結(jié)果為統(tǒng)一的響應(yīng)體牛曹;
- 8佛点、序列化響應(yīng)體對象,轉(zhuǎn)化為二進(jìn)制串黎比;
- 9超营、通過 Server Stub 將消息發(fā)送給對應(yīng)的 Client;
- 10阅虫、Client Stub 接受消息演闭;
- 11、反序列化二進(jìn)制串颓帝,轉(zhuǎn)化為對象米碰;
- 12、得到方法執(zhí)行的結(jié)果购城。
spring-boot-starter-grpc 技術(shù)實(shí)現(xiàn)
gRPC 遠(yuǎn)程調(diào)用
gRPC 提供了 proto3 代碼直接生成 Java 代碼的 Maven 插件吕座,在 proto 文件定義的請求體、響應(yīng)體工猜、服務(wù)米诉、服務(wù)方法等信息,會生成對應(yīng)的 Java 類篷帅。
// 語法類型
syntax = "proto3";
// 指定包名
option java_package = "com.anoyi.rpc";
// 指定類名
option java_outer_classname = "GrpcService";
option java_multiple_files = false;
// 定義通用的 Grpc 服務(wù)
service CommonService {
// 處理請求
rpc handle ( Request ) returns ( Response ) {}
}
// 定義通用的 Grpc 請求體
message Request {
bytes request = 1;
}
// 定義通用的 Grpc 響應(yīng)體
message Response {
bytes reponse = 1;
}
會生成如下 Java 類:(只列出常用重要的)
- [父類] GrpcService
- [子類] Request :統(tǒng)一請求體
- [子類] Response :統(tǒng)一響應(yīng)體
- [父類] CommonServiceGrpc
- [子類] CommonServiceImplBase :抽象類史侣,遠(yuǎn)程方法調(diào)用的具體實(shí)現(xiàn)繼承此類,實(shí)現(xiàn)
handle()
方法 - [子類] CommonServiceBlockingStub :阻塞方式
- [子類] CommonServiceFutureStub :異步方式
- [子類] CommonServiceImplBase :抽象類史侣,遠(yuǎn)程方法調(diào)用的具體實(shí)現(xiàn)繼承此類,實(shí)現(xiàn)
根據(jù)生成的代碼魏身,實(shí)現(xiàn) CommonServiceImplBase 抽象類惊橱,通過請求體提供的 ServiceName,從 Spring 容器中獲取 ServiceBean箭昵,然后使用 Java 反射調(diào)用 Service Method税朴。
序列化與反序列化
選用 protostuff 作為序列化與反序列化工具,因?yàn)樗悄壳巴愰_源的工具中性能最好的家制。相關(guān)數(shù)據(jù) https://github.com/eishay/jvm-serializers/wiki
相關(guān)代碼 ProtobufUtils
@GrpcServeice 注解的 Bean 的注入
- 1正林、Spring Boot 啟動時(shí),掃描指定(或默認(rèn))的包颤殴,獲取
@GrpcServeice
注解的接口觅廓; - 2、使用動態(tài)代理(cglib)涵但,代理
@GrpcServeice
注解的接口杈绸,并將代理類注冊到 Spring 容器中帖蔓;
相關(guān)代碼 ClassPathGrpcServiceScanner / GrpcAutoConfiguration / GrpcServiceProxy
服務(wù)發(fā)現(xiàn)
spring-boot-starter-grpc 為容器化而生,不內(nèi)嵌服務(wù)注冊與發(fā)現(xiàn)功能瞳脓,服務(wù)發(fā)現(xiàn)通過容器化的平臺的服務(wù)發(fā)現(xiàn)機(jī)制(一般為 DNS 塑娇、iptables、 IPVS 等技術(shù))來獲取遠(yuǎn)程服務(wù)的地址劫侧。
異常處理
目前的做法是捕獲所有類型的異常埋酬,封裝到統(tǒng)一的響應(yīng)體,后期可能會用更優(yōu)雅的方式來處理異常板辽。