序列化是Dubbo在RPC中非常重要的一个组成部分,其核心作用就是把网络传输中的数据,按照特定的格式进行传输。减小数据的体积,从而提高传输效率。
Dubbo制定了Serialization接口,然后有不同的实现。
序列化方式 | 备注 |
---|---|
Hessian | Dubbo协议中默认的序列化实现方案。 |
Java Serialization | JDK的序列化方式。 |
Dubbo序列化 | 阿里尚未开发成熟的高效Java序列化实现,目前不建议我们在生产环境使用它。 |
Json序列化 | 目前有两种实现:一种是采用阿里的fastjson库;一种是采用Dubbo中自己实现的简单json库。 |
Kryo | Java序列化方式,后续替换Hessian2,是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛使用。 |
FST | Java序列化方式,后续替换Hessian2,是一种较新的序列化实现,目前还缺乏足够多的成熟使用案例。 |
跨语言序列化方式 | ProtoBuf,Thirft,Avro,MsgPack(它更快更小。短整型被编码成一个字节)。 |
基于Java的方式序列化对比(没有对比protobuf)下图来自官方文档:
<dependency>
<groupId>org.apache.dubbo.extensionsgroupId>
<artifactId>dubbo-serialization-kryoartifactId>
<version>1.0.1version>
dependency>
在配置文件中书写下面的内容:
<dubbo:protocol name="dubbo" port="20880" serialization="kryo"/>
启动起来观看效果:
dubbo://192.168.96.1:20880/com.sjdwz.service.UserService?anyhost=true&application=dubbo-02-provider&background=false&bind.ip=192.168.96.1&bind.port=20880&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=com.sjdwz.service.UserService&methods=login&pid=13136&prefer.serialization=kryo&release=3.2.0&serialization=kryo&side=provider×tamp=1695216749509, dubbo version: 3.2.0, current host: 192.168.96.1
在配置文件中添加配置
<dubbo:reference interface="com.sjdwz.service.UserService" id="userService"
url="dubbo://192.168.96.1:20880/com.sjdwz.service.UserService?serialization=kryo"/>
运行效果:
在配置文件中书写下面的内容:
spring:
application:
name: dubbo-04-provider
dubbo:
protocol:
name: dubbo
port: -1
serialization: kryo
注解
@DubboReference(url = "dubbo://192.168.96.1:20880/com.sjdwz.service.UserService?serialization=kryo")
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-serialization-fstartifactId>
<version>2.7.23version>
<exclusions>
<exclusion>
<artifactId>dubbo-commonartifactId>
<groupId>org.apache.dubbogroupId>
exclusion>
exclusions>
dependency>
其他操作类似Kryo序列化方式的使用。
<dependency>
<groupId>com.alibaba.fastjson2groupId>
<artifactId>fastjson2artifactId>
<version>2.0.23version>
dependency>
其他操作类似Kryo序列化方式的使用。
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-javaartifactId>
<version>3.22.2version>
dependency>
<dependency>
<groupId>com.google.protobufgroupId>
<artifactId>protobuf-java-utilartifactId>
<version>3.22.2version>
dependency>
<dependency>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-serialization-protobufartifactId>
<version>2.7.23version>
<exclusions>
<exclusion>
<artifactId>dubbo-commonartifactId>
<groupId>org.apache.dubbogroupId>
exclusion>
<exclusion>
<artifactId>dubbo-serialization-apiartifactId>
<groupId>org.apache.dubbogroupId>
exclusion>
<exclusion>
<artifactId>protobuf-javaartifactId>
<groupId>com.google.protobufgroupId>
exclusion>
<exclusion>
<artifactId>protobuf-java-utilartifactId>
<groupId>com.google.protobufgroupId>
exclusion>
exclusions>
dependency>
<build>
<extensions>
<extension>
<groupId>kr.motd.mavengroupId>
<artifactId>os-maven-pluginartifactId>
<version>1.7.1version>
extension>
extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.pluginsgroupId>
<artifactId>protobuf-maven-pluginartifactId>
<version>0.6.1version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}protocArtifact>
<outputDirectory>${basedir}/src/main/javaoutputDirectory>
<clearOutputDirectory>falseclearOutputDirectory>
<protocPlugins>
<protocPlugin>
<id>dubboid>
<groupId>org.apache.dubbogroupId>
<artifactId>dubbo-compilerartifactId>
<version>0.0.2version>
<mainClass>org.apache.dubbo.gen.dubbo.Dubbo3GeneratormainClass>
protocPlugin>
protocPlugins>
configuration>
<executions>
<execution>
<goals>
<goal>compilegoal>
<goal>compile-customgoal>
goals>
execution>
executions>
plugin>
plugins>
build>
在dubbo-01-api模块的main目录新建一个proto文件夹;
注意必须叫这个名字,这样才能被maven插件读取到;
新建一个HelloService.proto的文件,在文件中编写如下内容:
syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.sjdwz";
option java_outer_classname = "HelloServiceProto";
message HelloRequest{
string name = 1;
}
message HelloResponse{
string result = 1;
}
service HelloService{
rpc sayHello(HelloRequest) returns (HelloResponse);
}
在protobuf文件中右键
执行此命令:
注意:如果项目中有中文路径可能会报错,需要改成英文目录
可以clean一下把target目录下的内容删掉;
实现生成的service接口
<dubbo:application name="dubbo-02-provider"/>
<dubbo:protocol name="dubbo" port="20880" serialization="protobuf"/>
<bean id="helloService" class="com.sjdwz.service.HelloServiceImpl"/>
<dubbo:service interface="com.sjdwz.HelloService" ref="helloService"/>
运行结果如下:
<dubbo:reference interface="com.sjdwz.HelloService" id="helloService"
url="dubbo://192.168.96.1:20880/com.sjdwz.HelloService?serialization=protobuf"/>
public class ClientApplication {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-consumer.xml");
HelloService hellService = applicationContext.getBean(HelloService.class);
HelloResponse response = hellService.sayHello(HelloRequest.newBuilder().setName("sjdwz").build());
System.out.println("response.getResult() = " + response.getResult());
System.in.read();
}
}
spring:
application:
name: dubbo-04-provider
dubbo:
protocol:
name: dubbo
port: -1
serialization: protobuf
@DubboReference(url = "dubbo://192.168.96.1:20880/com.sjdwz.HelloService?serialization=protobuf")