java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java Chassis3序列化方式

Java Chassis3的多种序列化方式支持技术解密

作者:liubao68

这篇文章主要为大家介绍了Java Chassis 3多种序列化方式支持技术解密,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

打开一个简单的 REST 接口

@RestSchema(schemaId = "ProviderController")
@RequestMapping(path = "/")
public class ProviderController {
  @PostMapping("/benchmark")
  public DataModel sayHello(@RequestHeader("wait") int wait, @RequestBody DataModel dataModel) {
    if (wait > 0) {
      Thread.sleep(wait);
    }
    return dataModel;
  }
}

契约

openapi: 3.0.1
info:
  title: swagger definition for org.apache.servicecomb.samples.ProviderController
  version: 1.0.0
servers:
- url: /
paths:
  /benchmark:
    post:
      operationId: sayHello
      parameters:
      - name: wait
        in: header
        required: true
        schema:
          type: integer
          format: int32
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataModel'
          application/protobuf:
            schema:
              $ref: '#/components/schemas/DataModel'
          text/plain:
            schema:
              $ref: '#/components/schemas/DataModel'
        required: true
        x-name: dataModel
      responses:
        "200":
          description: response of 200
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataModel'
            application/protobuf:
              schema:
                $ref: '#/components/schemas/DataModel'
            text/plain:
              schema:
                $ref: '#/components/schemas/DataModel'
components:
  schemas:
    ChildDataModel:
      type: object
      properties:
        numInt:
          type: integer
          format: int32
        numLong:
          type: integer
          format: int64
        numDouble:
          type: number
          format: double
        numFloat:
          type: number
          format: float
        data:
          type: string
      x-java-class: org.apache.servicecomb.samples.ChildDataModel
    DataModel:
      type: object
      properties:
        data:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ChildDataModel'
      x-java-class: org.apache.servicecomb.samples.DataModel

可以看到 Java Chassis使用了Open API 3.0.1的协议规范,Request Body 和 responses 增加了 application/protobuf 、 text/plain 的支持。 这种使用形式,奠定了Java Chassis 3多序列化支持方式的基础,细心的读者应该很快能够发现这种方式与其他支持多序列化框架之间的差异。

Spring Boot

支持多序列化方式,需要实现 HttpMessageConverter 接口,并在 Controller 声明支持的 Content-Type。 如果使用 Spring Fox 或者 Spring Doc 等 Open API工具生成契约,契约内容只会包含 Controller 声明的序列化类型。 Spring Boot存在隐式的契约情况,这意味着契约并不能完全代表 Controller 服务的能力。 如果需要对接口增加或者减少序列化支持,都需要修改代码。

Dubbo

Dubbo 需要在 Provider 使用 dubbo:protocol 声明序列化方式, 在Consumer使用 dubbo:reference 声明序列化方式。 由于 Dubbo 是基于IDL的契约系统, 在使用 RPC 的场景下,可以通过配置动态调整序列化方式。 REST 支持在 Dubbo 是完全独立的单元, 序列化方式也独立于 RPC 接口, RPC 和 REST 不能互操作。

Open API基于 REST 的语义,来支持 IDL 的语义。 Java Chassis能够更加直观的支持通过第三方工具以HTTP协议族访问微服务, 只需要按照契约的描述构造HTTP的报文。 在编码侧, Java Chassis的客户端可以使用 REST 语义的接口,如 RestOperations,也可以使用 RPC 语义的接口访问服务端。

定义服务端接口

public interface ProviderService {
  DataModel sayHello(int wait, DataModel dataModel);
}

通过RPC访问

@RestSchema(schemaId = "ConsumerController")
@RequestMapping(path = "/")
public class ConsumerController {
  @RpcReference(schemaId = "ProviderController", microserviceName = "provider")
  private ProviderService providerService;

  @PostMapping("/benchmark")
  public DataModel sayHello(@RequestHeader("wait") int wait, @RequestBody DataModel dataModel) {
    return providerService.sayHello(wait, dataModel);
  }
}

Java Chassis以OpenAPI为基础的Edge Service部件,能够实现请求在通信协议、序列化方式上的自动转换。比如将HTTP协议转Highway协议、application/json转application/protobuf等。

基于 Java Chassis Benchmark ,做一个简单性能测试。该测试对比了两种场景:

场景一的默认配置:

servicecomb:
  rest:
    parameter:
      default-request-encoding: "application/json"
      default-response-encoding: "application/json"

场景二的默认配置:

servicecomb:
  rest:
    parameter:
      default-request-encoding: "application/protobuf"
      default-response-encoding: "application/protobuf"

测试结果参考下表。该数据主要用于说明序列化差异,因此省去了测试环境的描述。下表的平均时延统计了测试客户端计算的请求-响应时间的平均值。

版本数据单位等待时间线程数执行次数执行时间平均时延
protobuffer1010100066426
protobuffer100010100094189
protobuffer100001010002520524
protobuffer1101010001543215
protobuffer100101010001596515
protobuffer1000101010002592625
protobuffer1100101000105727105
protobuffer100100101000106376106
protobuffer1000100101000114452114
jason1010100067366
jason10001010001506314
jason100001010006975768
jason1101010001663216
jason100101010002003319
jason1000101010006610465
jason1100101000104868104
jason100100101000107439107
jason1000100101000132786131

从这组数据可以看出:

不同的序列化方式除了性能差异,在可维护方面也会存在很大的差异。比如 proto-buffer 在兼容性方面的表现会比 json 差,当修改接口定义的时候, 比如增加属性、删除属性、修改属性等,proto-buffer 更容易导致兼容性问题,做好兼容性防范对多数用户而言,都是比较困难的事情。

支持多协议、多序列化方式的另外一个考虑,是对接遗留系统。对接遗留系统会背负大量历史债务,使得新系统本身设计偏离预期的方向。在 Java Chassis 多序列化方式的选择上, 只提供了目前广泛使用的 json 和 proto-buffer 支持, 而没有选择支持其他序列化方案。 以架构的韧性去处理遗留系统问题,是 Java Chassis坚持的一个重要设计理念,对接遗留系统或者保持与遗留系统的兼容,不是它的主要设计目标。

在序列化方式选择上,简单的总结如下:

客户故事:某个客户的关键核心系统对于时延要求很高,因此需要采用私有协议和序列化方式来提升性能。但是对于一些非核心系统,需要使用REST接口,方便日常开发、调试。Java Chassis的解耦设计使得客户无需对代码进行任何改造,就可以满足两方面的要求。

以上就是Java Chassis 3多种序列化方式支持技术解密的详细内容,更多关于Java Chassis3序列化方式的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文