Dubbo 之自定义系列

>>>>>>>>>>>>>  码云中有封装号的:https://gitee.com/chxlay/iserver-common.git   <<<<<<<<<<<<<<<<<<<<<

版本:Dubbo 3.0.8 版本 , Dubbo 的使用这里就不多言了

具体代码在 码云中: iserver-common-rpc  模块

问题点:

Dubbo  的默认系列化方式为: hessian2 ( Hessian2Serialization implements Serialization )

当我们类中没有无参构造函数时, 框架将会寻找最少参数的构造函数,参数以 null 处理,普通类处理起来倒是简单,增加一个无参构造函数即可,若无法添加无参构造函数的就有点麻烦

比如:某项目中,金额使用,我设计的统一使用货币最小单位,分 作为存储单位(以前端交互时需要 编写全局 的 分 与 元的转换,确保前端得到的 元,后端 得到分 )

如:这个场景下,添加一个无参构造函数就不太合适,dubbo 服务调用者得到的金额将会 为  0 

public class MoneyPenny extends BigDecimal {
    private static final long serialVersionUID = 1L;
    private static final BigDecimal ROUTE = new BigDecimal("100");
    public static final MoneyPenny ZERO = new MoneyPenny(BigInteger.ZERO);

    public MoneyPenny(BigInteger intVal) {
        super(intVal, 0);
    }

    public MoneyPenny(int in) {
        super(in);
    }
    public MoneyPenny(int in, MathContext mc) {
        super(in, mc);
    }
    public MoneyPenny(Long in, MathContext mc) {
        super(in, mc);
    }
    public MoneyPenny(Long in) {
        super(in);
    }
    public MoneyPenny(String in) {
        super(in);
    }

    public MoneyPenny(Double in) {
        super(in);
    }
    public MoneyPenny(Double in, MathContext mc) {
        super(in, mc);
    }
    public MoneyPenny(char[] in) {
        super(in);
    }
    public BigDecimal toYuan() {
        return this.divide(ROUTE, 2, RoundingMode.DOWN);
    }

    public static MoneyPenny toThis(String yuan) {
        if (null == yuan) return MoneyPenny.ZERO;
        BigDecimal penny = new BigDecimal(yuan).multiply(ROUTE);
        return new MoneyPenny(penny.toString());
    }

    public static MoneyPenny toThis(BigDecimal value) {
        if (null == value) return MoneyPenny.ZERO;
        return new MoneyPenny(value.toString());
    }

}

所以需要配置  Dubbo 的系列化(当然后很多方式)

以下示例选择的是 将    hessian2   变更为   kryo   系列化

注意,Dubbo  官网中给出的方式并不太好使,

依赖:

<!-- Dubbo 系列化方式 kryo -->
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-serialization-kryo</artifactId>
</dependency>

注册自定义类

/**
 * Kryo 注册实例化的类信息
 *
 * @author Alay
 * @date 2022-06-19 01:37
 */
public class ISerializationOptimizer implements SerializationOptimizer {

    @Override
    public Collection<Class<?>> getSerializableClasses() {
        List<Class<?>> clazzs = new LinkedList<>();
        clazzs.add(MoneyPenny.class);
        return clazzs;
    }
}

 配置文件配置(开发中移到 Nacos 中较为方便):

# Dubbo 配置
dubbo:
  protocol:
    # 端口号,每个服务需要独立配置
    # port: 6101
    # Dubbo3 的新特性协议 Triple(tri)/dubbo(dubbo)
    name: tri
    # 系列化方式(默认Hessian2Serialization,当类中没有无参构造器时,会以 null 作为参数调用最少参数的构造器,造成异常)
    serialization: kryo
    # 注册系列化类
    optimizer: com.iserver.common.rpc.dubbo.serialization.ISerializationOptimizer
  # dubbo 的注册中心配置
  registry:
    # 服务组名(以项目组名为)
    group: @project.groupId@
    # Nacos 作为注册中心配置
    #address: ${spring.cloud.nacos.discovery.server-addr}
    #protocol: nacos
    # zookeeper 作为注册中心地址配置
    address: ${ZOOKEEPER_HOST:iserver-zookeeper}
    protocol: zookeeper
    port: 2181
    timeout: 10000

  application:
    # 引用名称
    name: ${spring.application.name}
    # 注册模式,应用及的注册 interface(3.x版本之前是以接口方式进行注册)/ instance
    register-mode: instance
  scan:
    base-packages: com.iserver.demo.*.service
  consumer:
    # 是否检查 consumer 在线状态
    check: false
  provider:
    # 系列化方式(默认Hessian2Serialization,当类中没有无参构造器时,会以 null 作为参数调用最少参数的构造器,造成异常)
    serialization: kryo

 

posted @ 2022-06-20 23:13  Vermeer  阅读(211)  评论(0)    收藏  举报