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

 更新时间:2024年01月17日 09:06:34   作者: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

从这组数据可以看出:

  • 在数据量比较小的场景下,使用 json 和 proto-buffer 性能差异很小。 在数据量比较大的情况下,proto-buffer 的性能明显好于 json
  • 在业务时延比较大(>100ms)的时候, 序列化的时延可以忽略。

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

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

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

  • 使用 REST 协议是绝大多数场景的最优选择,能够最好的兼顾性能、可靠性、韧性等方面的要求。
  • 对于数据量比较大,业务时延很低(<100ms),并且业务比较稳定,业务接口不需要频繁变动的场景,可以采用 proto-buffer来优化性能,按需调整。

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

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

相关文章

  • spring boot集成mongodb的增删改查的示例代码

    spring boot集成mongodb的增删改查的示例代码

    这篇文章主要介绍了spring boot集成mongodb的增删改查的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java中转换器设计模式深入讲解

    Java中转换器设计模式深入讲解

    这篇文章主要给大家介绍了关于Java中转换器设计模式的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • springboot2.1.7去除json返回字段中为null的字段

    springboot2.1.7去除json返回字段中为null的字段

    这篇文章主要介绍了springboot2.1.7去除json返回字段中为null的字段,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Spring 面向切面编程AOP实现详解

    Spring 面向切面编程AOP实现详解

    这篇文章主要介绍了Spring 面向切面编程AOP实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • ThreadLocal工作原理及用法案例

    ThreadLocal工作原理及用法案例

    本文详细讲解了ThreadLocal工作原理及用法案例,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • Java实战之在线寄查快递系统的实现

    Java实战之在线寄查快递系统的实现

    这篇文章主要介绍了如何利用Java制作一个在线寄查快递系统,文中采用的技术有java、SpringBoot、FreeMarker、Mysql,需要的可以参考一下
    2022-02-02
  • shrio中hashedCredentialsMatcher密码匹配示例详解

    shrio中hashedCredentialsMatcher密码匹配示例详解

    shrio是一个轻量级权限管理框架,密码的匹配由框架内部完成。密码是否匹配由接口CredentialsMatcher定义实现类完成,CredentialsMatcher实现类有SimpleCredentialsMatcher和HashedCredentialsMatcher两个
    2021-10-10
  • Java实现连接kubernates集群的两种方式详解

    Java实现连接kubernates集群的两种方式详解

    这篇文章主要为大家详细介绍了Java实现连接kubernates集群的两种方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01
  • SpringCloud Feign远程调用实现详解

    SpringCloud Feign远程调用实现详解

    Feign是Netflix公司开发的一个声明式的REST调用客户端; Ribbon负载均衡、 Hystrⅸ服务熔断是我们Spring Cloud中进行微服务开发非常基础的组件,在使用的过程中我们也发现它们一般都是同时出现的,而且配置也都非常相似
    2022-11-11
  • Java常用类库StringBuffer,Runtime,日期操作类等类库总结

    Java常用类库StringBuffer,Runtime,日期操作类等类库总结

    这篇文章主要介绍了Java常用类库StringBuffer,Runtime,日期操作类等类库总结,需要的朋友可以参考下
    2020-02-02

最新评论