RPC&Http

1. Http 的话要先走dns 再走lvs 再走nginx 链路太长,可用性SLA指标太低
2. http是文本协议比其他用在rpc上的序列化 二进制协议 如 thrift protobuf等来说性能太低 ,会造成应用rt太高。
举个例子就是,在美团研发时做的分布式ID系统leaf,用thrift的rt在1ms之内平均只有0.4ms,单台机器QPS 5w。同时也提供了http的方式,QPS最多达到1w,
rt在50ms左右。如果你的应用对SLA和rt要求都不高,怎么好用怎么用

3. 成熟的rpc库相对http容器,更多的是封装了“服务发现”,"负载均衡",“熔断降级”一类面向服务的高级特性。
可以这么理解,rpc框架是面向服务的更高级的封装。

DUBBO协议

协议概览

DUBBO框架定义了私有的RPC协议,其中请求和响应协议的具体内容我们使用表格来展示。

/dev-guide/images/dubbo_protocol_header.jpg

org.apache.dubbo.remoting.exchange.codec.ExchangeCodec#encodeRequest

org.apache.dubbo.remoting.exchange.codec.ExchangeCodec#encodeResponse

协议详情

  • Magic - Magic High & Magic Low (16 bits)

    标识协议版本号,dubbo 协议:0xdabb

  • Req/Res (1 bit)

    标识是请求或响应。请求: 1; 响应: 0。

  • 2 Way (1 bit)

    仅在 Req/Res 为1(请求)时才有用,标记是否期望从服务器返回值。如果需要来自服务器的返回值,则设置为1。

  • Event (1 bit)

    标识是否是事件消息,例如,心跳事件。如果这是一个事件,则设置为1。

  • Serialization ID (5 bit)

    标识序列化类型:比如 fastjson 的值为6。

  • Status (8 bits)

    仅在 Req/Res 为0(响应)时有用,用于标识响应的状态

    • 20 - OK
    • 30 - CLIENT_TIMEOUT
    • 31 - SERVER_TIMEOUT
    • 40 - BAD_REQUEST
    • 50 - BAD_RESPONSE
    • 60 - SERVICE_NOT_FOUND
    • 70 - SERVICE_ERROR
    • 80 - SERVER_ERROR
    • 90 - CLIENT_ERROR
    • 100 - SERVER_THREADPOOL_EXHAUSTED_ERROR
  • Request ID (64 bits)

    标识唯一请求。类型为long。

  • Data Length (32 bits)

    序列化后的内容长度(可变部分),按字节计数。int类型。

  • Variable Part

    被特定的序列化类型(由序列化 ID 标识)序列化后,每个部分都是一个 byte [] 或者 byte

    • 如果是请求包 ( Req/Res = 1),则每个部分依次为:
      • Dubbo version
      • Service name
      • Service version
      • Method name
      • Method parameter types
      • Method arguments
      • Attachments
    • 如果是响应包(Req/Res = 0),则每个部分依次为:
      • 返回值类型(byte),标识从服务器端返回的值类型:
        • 返回空值:RESPONSE_NULL_VALUE 2
        • 正常响应值: RESPONSE_VALUE 1
        • 异常:RESPONSE_WITH_EXCEPTION 0
      • 返回值:从服务端返回的响应bytes

**注意:**对于(Variable Part)变长部分,当前版本的dubbo框架使用json序列化时,在每部分内容间额外增加了换行符作为分隔,请选手在Variable Part的每个part后额外增加换行符, 如:

Dubbo version bytes (换行符)
Service name bytes  (换行符)
...

DUBBO协议的优缺点

优点

  • 协议设计上很紧凑,可用用 1 个 bit 表示的,不会用一个 byte 来表示,比如 boolean 类型的标识
  • 请求、响应的 header 一致,通过序列化器对 content 组装特定的内容,代码实现起来简单

参考:

https://www.zhihu.com/question/41609070

https://dubbo.apache.org/zh-cn/blog/dubbo-protocol.html

原文地址:https://www.cnblogs.com/parkdifferent/p/10880390.html