文章說明
本文內容整理自《孫哥說Dubbo系列視頻課程》,孫帥老師課程細致、全面、深入、性價比極高。B站搜孫帥suns可以找到對應的試聽視頻,或者直接添加老師微信號suns45與他直接聯系
一:序列化概念
補充說明:
Kyro和Fst這兩種優秀的序列化方案都是適用于Java體系,換句話說,換個Go語言編寫的端就不好使了。
ProtoBuf這中序列化方式可以支持其他的語言。Java、go、php都是可以支持的。GRPC另外一種RPC的底層實現方式。
二:ProtoBuf序列化方式
1:引入依賴
(一):ProtoBuf依賴
<dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java</artifactId><version>3.22.2</version></dependency><dependency><groupId>com.google.protobuf</groupId><artifactId>protobuf-java-util</artifactId><version>3.22.2</version></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-serialization-protobuf</artifactId><version>2.7.23</version><exclusions><exclusion><artifactId>dubbo-common</artifactId><groupId>org.apache.dubbo</groupId></exclusion><exclusion><artifactId>dubbo-serialization-api</artifactId><groupId>org.apache.dubbo</groupId></exclusion><exclusion><artifactId>protobuf-java</artifactId><groupId>com.google.protobuf</groupId></exclusion><exclusion><artifactId>protobuf-java-util</artifactId><groupId>com.google.protobuf</groupId></exclusion></exclusions></dependency></dependencies><build><extensions><extension><groupId>kr.motd.maven</groupId><artifactId>os-maven-plugin</artifactId><version>1.7.1</version></extension></extensions><plugins><plugin><groupId>org.xolstice.maven.plugins</groupId><artifactId>protobuf-maven-plugin</artifactId><version>0.6.1</version><configuration><protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}</protocArtifact><outputDirectory>${basedir}/src/main/java</outputDirectory><clearOutputDirectory>false</clearOutputDirectory><protocPlugins><protocPlugin><id>dubbo</id><groupId>org.apache.dubbo</groupId><artifactId>dubbo-compiler</artifactId><version>0.0.2</version><mainClass>org.apache.dubbo.gen.dubbo.Dubbo3Generator</mainClass></protocPlugin></protocPlugins></configuration><executions><execution><goals><goal>compile</goal><goal>compile-custom</goal></goals></execution></executions></plugin></plugins></build>
protobuf-java、protobuf-java-uitl這兩個是Dubbo項目支持Protobuf的話,這兩個依賴是必有的。dubbo-serialization-protobuf這個是ProtoBuf的序列化依賴。需要排除自帶的Dubbo依賴。另外還需要把java和util這兩個依賴給排除掉。
此依賴配置是放到父項目的Pom.xml里邊。
(二):解決依賴編譯問題
Consumer和provider之間是通過網絡進行通信的,兩者有可能不同的語言編寫的。那兩者通信的時候都得將數據轉換為ProtoBuf這種中間格式來進行通訊。這樣就做到了跨語言的數據傳輸。一旦應用了ProtoBuf這種序列化方式。
ProtoBuf作為數據傳輸的中間格式,一旦應用了ProtoBuf作為序列化方式的。IDL是ProtoBuf作為中間的格式,是ProtoBuf的特有的預發,里邊都稱之為Message。這里邊涉及到一個編譯的問題,需要使用ProtoC進行編譯,使用ProtoC進行編譯的話,有兩種使用方式。1是直接本地安裝protoC,另外一種是使用maven插件的方式。我們maven插件即可。
應用這個插件的時候,我們需要注意這個版本必須與上述的protobuf-java版本保持一致,使用MAC操作系統的話,其中的版本不能低于3.17.3,低于這個版本是對這個蘋果的ARM架構是不支持的。Nacos是也有這個問題
2:ProtoBuf?件的編寫
ProtoBuf作為序列化方案,需要有一個傳輸數據的中間類型,這個中間類型就是ProtoBuf里邊的IDL,這個IDL大致有三塊內容:參數(請求數據)返回值(返回參數)這是兩個非常核心的內容,也稱之為Message。
當然還有第三個內容,那就是服務接口。服務接口溝通了Provider和Confumer,一個基于服務接口提供實現,另外一個通過服務接口創建代理。如果基于ProtoBuf來實現序列化的話,那么這個服務接口也需要在定義在IDL當中的。
ProtoBuf的IDL是.protobuf的這樣的一個文件。首先,我們使用的語法是proto3三個Java配置可選項。
這個文件叫做HelloService.proto,放到與API項目下和Java平級的proto目錄下。這個將來會被consumer和provider共用。
然后,這個proto文件會被protoC插件翻譯成Java類。
syntax = "proto3";生成的Java類放到不同的文件里
option java_multiple_files = true;
生成的代碼放到那個包下
option java_package = "com.suns";
最外層的類叫什么名字?
option java_outer_classname = "HelloProtocol";message HelloRequest {
string name = 1;
}
message HelloResponse {
string result = 1;
}
service HelloService {
rpc sayHello (HelloRequest) returns (HelloResponse);
}
3:ProtoC生成的Java接口
public class HelloServiceImpl implements HelloService {@Overridepublic HelloResponse sayHello(HelloRequest request) {System.out.println("HelloServiceImpl.sayHello request " + request.getName());return HelloResponse.newBuilder().setResult("this is sayHello result").build();}//異步的@Overridepublic CompletableFuture<HelloResponse> sayHelloAsync(HelloRequest request) {return CompletableFuture.completedFuture(sayHello(request));}
}
4:XML的配置方式
<dubbo:protocol name="dubbo" port="-1" serialization="protobuf"/>
<bean id="helloService" class="com.suns.service.HelloServiceImpl"/>
<dubbo:service interface="com.suns.HelloService" ref="helloService"/>
5:Boot的配置方式
dubbo:protocol:name: dubboport: -1serialization: protobuf
6:Consumer端調用
<dubbo:reference interface="com.suns.service.HelloService" id="helloSe
rvice"
url="dubbo://192.168.50.62:20880/com.suns.HelloServic
e?serialization=protobuf"/>
?7:Boot的方式
@DubboReference(url = "dubbo://192.168.50.62:20880/com.suns.HelloServi
ce?serialization=protobuf")