Dubbo 新特性

和 cloud 区别

  • dubbo 存入的是接口名:url,cloud 存入的是应用: url,这样 dubbo 存入的数据量会多很多
  • dubbo 改变会很频繁,cloud 存入的应用级的所以不关心单个接口更新
  • dubbo3.0 也转换为应用级注册,也方便去调用 cloud 服务
  • springcloud 因为只保存应用,如果调用 rest 接口,消费者需要配置 url 路径

协议

Dubbo3.0 将 dubbo 协议更新为 Triple 协议

协议简析

http1 协议

image-20230222110153366

  • 每次都会三次握手
  • 请求格式为请求行、请求头、请求体
  • 每次都需要将其拼成对应格式,再转换为 ascii 码,用 socket 传送字节
缺点
  • 含有过多冗余数据(格式、回车符、换行符等)
  • 异步同时发送两个请求,无法得知响应的来源,所以需要单线执行,tomcat 默认开启 6 个 socket

dubbo 协议

image-20230222110139862

  • 0-7,8-15:魔数,代表 dubbo 请求
  • 16-20:序列化 id
  • 21:序列法方式
  • 22:表示消息是单向或者双向,如需要服务器返回值,需要设置为 1
  • 23:标记响应还是请求
  • 24-31:响应状态
  • 32-95:请求 ID/ 响应 ID,可以异步发送
  • 96-127:串行化内容长度,以字节计算
  • 之后就是可变的传输数据
缺点
  • 协议不通用,只适用于 dubbo 自己通信

Triple 协议

  • 基于 http2 开发,兼容性更好
  • 和 gRPC 互通,几乎一致
  • 流式调用异步有问题
流式调用
  1. 普通类型 —— 发送一次返回一次

  2. SERVER_STREAM(服务端流) 响应式模型,服务端可分批次返参 ——发送一次返回多次

    服务端:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    // 服务端 
    public void sayHelloServerStream(String name, StreamObserver<String> response) {
    System.out.println(" 处理请求:" + name);
    // 分批次返参
    response.onNext(" 结果 1");
    try {
    Thread.sleep(3000);
    } catch (Exception e) {
    System.out.println(e);
    }
    response.onNext(" 结果 2");
    response.onNext(" 结果 3");
    response.onCompleted();
    }

    // 客户端
    userService.sayHelloServerStream("111", new StreamObserver<String>() {
    @Override
    public void onNext(String data) {
    System.out.println(" 获取数据 " + data);
    result.append(data);
    System.out.println(result);
    }
    @Override
    public void onError(Throwable throwable) {
    System.out.println(" 出现异常 ");
    }
    @Override
    public void onCompleted() {
    System.out.println(" 获取所有响应数据 ");
    }
    });
  3. CLIENT_STREAM(客户端流 ) —— 发送多次返回多次

  4. BI_STREAM(双端流) java 中等价于客户端流,即双向发送数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    // 服务端 
    public StreamObserver<String> sayHelloStream(StreamObserver<String> response) {
    return new StreamObserver<String>() {
    @Override
    public void onNext(String data) {
    System.out.println(" 接到请求数据 " + data);
    response.onNext(" 接到请求数据:" + data + 4);
    response.onNext(" 接到请求数据:" + data + 5);
    response.onNext(" 接到请求数据:" + data + 6);
    if (data.contains("2")) {
    response.onCompleted();
    }
    }
    @Override
    public void onError(Throwable throwable) {

    }
    @Override
    public void onCompleted() {
    System.out.println(" 完成客户请求 ");
    }
    };
    }

    // 客户端
    public String create2() {
    StreamObserver streamObserver = userService.sayHelloStream(new StreamObserver<String>(){
    @Override
    public void onNext(String data) {
    System.out.println(" 获取响应数据 "+data);
    }
    @Override
    public void onError(Throwable throwable) {

    }
    @Override
    public void onCompleted() {
    System.out.println(" 完成双向传输 ");
    }
    });
    streamObserver.onNext("request 1");
    streamObserver.onNext("request 2");
    streamObserver.onCompleted();
    return "succeeded in creating the order";
    }

grpc