乐趣区

关于阿里云:如何用一个端口同时暴露-HTTP12gRPCDubbo-协议

作者:华钟明

本文咱们将介绍 Apache Dubbo 灵便的多协定设计准则,基于这一设计,在 Dubbo 框架底层可灵便的选用 HTTP/2、HTTP/REST、TCP、gRPC、JsonRPC、Hessian2 等任一 RPC 通信协议,同时享受对立的 API 与对等的服务治理能力。同时,咱们还介绍了 Dubbo 的单端口多协定能力,也就是在单个端口同时监听、解决多个协定,这对于简化多协定同时公布的场景十分有用。

不绑定 RPC 协定的设计准则

Dubbo 框架不绑定任何通信协议,你能够依据业务场景抉择 HTTP/2 通信协议,也能够选用 HTTP/REST、TCP(Dubbo2)、gRPC、JsonRPC、Hessian2 等官网反对的通信协议,如果以上协定都不能满足需要,还能够十分不便的通过定制形式接入自定义协定。如果你想在一个利用内应用多个协定,也能够非常容易的做到,比方一个接口应用 HTTP/2 通信,另一个接口应用 TCP 通信,一个利用内公布或调用多个应用不同协定的服务。

通过 Dubbo 框架的多协定反对,你能够做到:

  • 将任意通信协议无缝地接入 Dubbo 服务治理体系。Dubbo 体系下的所有通信协议,都能够享受到 Dubbo 的编程模型、服务发现、流量管控等劣势。比方 gRPC over Dubbo 的模式,服务治理、编程 API 都可能零老本接入 Dubbo 体系。
  • 兼容不同技术栈,业务零碎混合应用不同的服务框架、RPC 框架。比方有些服务应用 gRPC 或者 Spring Cloud 开发,有些服务应用 Dubbo 框架开发,通过 Dubbo 的多协定反对能够很好的实现互通。
  • 让协定迁徙变的更简略。通过多协定、注册核心的协调,能够疾速满足公司内协定迁徙的需要。比方如从自研协定降级到 Dubbo 协定,Dubbo 协定本身降级,从 Dubbo 协定迁徙到 gRPC,从 HTTP 迁徙到 Dubbo 协定等。

官网接入的支流协定

HTTP/2 (Triple)

Triple 协定是 Dubbo3 公布的面向云原生时代的通信协议,它基于 HTTP/2 并且齐全兼容 gRPC 协定,原生反对 Streaming 通信语义,自 Triple 协定开始,Dubbo 还反对基于 Protobuf 的服务定义与数据传输。Triple 具备更好的网关、代理穿透性,因而非常适合于跨网关、代理通信的部署架构,如服务网格等。Triple 协定的外围个性如下:

  • 反对 TLS 加密、Plaintext 明文数据传输
  • 反对反压与限流
  • 反对 Streaming 流式通信

在编程与通信模型上,Triple 协定反对如下模式:

  • 生产端异步申请(Client Side Asynchronous Request-Response)
  • 提供端异步执行(Server Side Asynchronous Request-Response)
  • 生产端申请流(Request Streaming)
  • 提供端响应流(Response Streaming)
  • 双向流式通信(Bidirectional Streaming)

TCP (Dubbo2)

Dubbo2 协定是基于 TCP 传输层协定之上构建的一套 RPC 通信协议,因为其紧凑、灵便、高性能的特点,在 Dubbo2 时代获得了十分宽泛的利用,是企业构建高性能、大规模微服务集群的要害通信计划。在云原生时代,咱们更举荐应用通用性、穿透性更好的 Triple 协定。

gRPC

你能够用 Dubbo 开发和治理微服务,而后设置应用 gRPC 协定进行底层通信。但为什么要这么做那,与间接应用 gRPC 框架比照有什么劣势?简略的答案是,这是应用 gRPC 进行微服务开发的罕用模式,具体请往下看。

gRPC 是谷歌开源的基于 HTTP/2 的通信协议,如同咱们在 产品比照 [ 1] 文档中提到的,gRPC 的定位是通信协议与实现,是一款纯正的 RPC 框架,而 Dubbo 定位是一款微服务框架,为微服务实际提供解决方案。因而,相比于 Dubbo,gRPC 绝对欠缺了微服务编程模型、服务治理等能力的形象。

在 Dubbo 体系下应用 gRPC 协定 (gRPC over Dubbo Framework) 是一个十分高效和轻量的抉择,它让你既能应用原生的 gRPC 协定通信,又防止了基于 gRPC 进行二次定制与开发的复杂度 (二次开发与定制 gRPC,是很多企业规模化实际后证实不可避免的环节,Dubbo 框架替开发者实现了这一步,让开发者能够间接以最简略的形式应用 gRPC)。

REST

微服务畛域罕用的一种通信模式是 HTTP + JSON,包含 Spring Cloud、Microprofile 等一些支流的微服务框架都默认应用的这种通信模式,Dubbo 同样提供了对基于 HTTP 的编程、通信模式的反对。

其余通信协议

除了以上介绍的几种协定之外,你还能够将以下协定运行在 Dubbo 之上。对 Dubbo 而言,只须要批改一行简略的配置,就能够切换底层服务的通信协议,其余外围 API 和治理能力不受影响。

  • Hessian2
  • Thrift
  • JsonRPC

单端口多协定

自 Dubbo 3.2 版本开始,Dubbo 提供了单个端口上的协定复用能力,通过调整 Protocol 配置即可实现。

比方在开启 HTTP/2 (Triple) 协定 或  gRPC 协定后,如咱们同时启动端口复用,还能够在雷同的端口上为服务减少 TCP (Dubbo2) 协定、Qos 协定的反对。这些所有流量的入口都在一个对立 port 端口,Dubbo 框架负责在端口之上辨认不同的 RPC 协定,并进行处理器散发,从而实现单个端口上的协定复用。

对于须要解决多个协定的场景,端口复用十分有价值。它能够用于服务的协定迁徙,并且能够节约端口以及相干的资源,缩小运维的复杂性等。

实现原理

以下是端口复用实现的原理图

  • 在服务的创立阶段,通过从 Config 层获取到服务导出的协定配置从而创立不同的 Protocol 对象进行导出。在导出的过程中,如果不是第一次创立端口复用的 Server,那么 Exchanger 会将 Protcol 层传递的数据保留到 Server,用于后续解决该协定类型的音讯。
  • 当客户端的消息传递过去后,首先会通过 Server 传递给 ProtocolDetector,如果实现了辨认,那么就会标记该客户端为对应的协定。并通过 WireProtocol 配置对应的解决逻辑,最初交给 ChannelOperator 实现底层的 IO 框架和对应的 Dubbo 框架的解决逻辑的绑定。
  • 以上的协定辨认实现之后,Channel 曾经确定了如何解决近程的客户端音讯,通过对应的 ServerPipeline 进行解决即可(在解决的过程中也会依据配置信息决定音讯的解决线程)。

应用场景

以下是几种常见的应用场景。

  • 最罕用的是用于服务发现。这容许应用程序通过网络发现服务,而后应用同一端口与它们通信,有助于升高网络通信的复杂性,并使其更易于治理。
  • 能够用于负载平衡。这容许应用程序在多个近程服务或服务集群之间均衡负载,有助于进步服务的可扩展性、可靠性和可用性。
  • 能够用于服务监控。这容许应用程序监督近程服务的运行状况,并在服务呈现故障或变得不可用时收回警报,有助于确保服务的可用性并缩小停机工夫。

参考用例:
https://github.com/apache/dubbo-samples/tree/master/dubbo-samples-port-unification

应用形式

在同一主机上部署多个服务或须要通过负载均衡器拜访多个服务。

对于 Dubbo 反对的配置形式 配置阐明 [ 2]

服务多协定导出

ext-protocol 参数反对配置多个不同的协定,协定之间通过 ”,” 进行分隔。

xml 配置

<dubbo:protocol name="dubbo" port="-1" ext-protocol="tri,"/>

<bean id="greetingService" class="org.apache.dubbo.demo.provider.GreetingServiceImpl"/>

<dubbo:service delay="5000" version="1.0.0" group="greeting" timeout="5000" interface="org.apache.dubbo.demo.GreetingService" ref="greetingService" protocol="dubbo"/>

API 配置

ProtocolConfig config = new ProtocolConfig(CommonConstants.TRIPLE, -1);

config.setExtProtocol(CommonConstants.DUBBO+",");

yaml 配置

dubbo:
  application:
    name: dubbo-springboot-demo-provider
  protocol:
    name: tri
    port: -1
    ext-protocol: dubbo,

properties 配置

dubbo.protocol.name=tri
dubbo.protocol.ext-protocol=dubbo,
dubbo.protocol.port=20880

Qos 接入

Qos 模块导入

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-qos</artifactId>
</dependency>

实现 Qos 模块的导入之后,相干的配置项可参考 Qos 操作手册 [ 3] 进行配置。

默认状况下,基于端口复用的 Qos 服务在模块导入后是启动的。

Qos 应用

将 Qos 协定接入到端口复用的场景下,须要在建设连贯之后,客户端先向服务端发送音讯,比照将 Qos 协定通过单个端口提供服务,端口复用版的 Qos 协定在解决 telnet 连贯的状况下须要用户执行一些操作,实现协定辨认(二选一)。

1. 间接调用命令
间接调用 telnet 反对的命令也能够实现辨认,在用户不相熟的状况下能够调用 help 指令实现辨认

  1. 发送 telnet 命令辨认
    通过 telnet 命令建设连贯之后,执行以下几个步骤:
    1. 应用 crtl + “]” 进入到 telnet 交互界面(telnet 默认的 escape character)

      1. 调用 “send ayt” 向服务端发送非凡识别字段(为 telnet 协定的一个非凡字段)
      2. 回车实现音讯发送并进入到 dubbo 的交互界面

服务援用

以 dubbo-samples-port-unification [ 4] 中的例子作为根底, 援用不同协定的服务和非端口复用状况下的配置是统一的,上面通过 Consumer 端的 InvokerListener 输入调用过程中的 URL 信息。

ReferenceConfig<GreetingService> reference = new ReferenceConfig<>();
reference.setInterface(GreetingService.class);
reference.setListener("consumer");
reference.setProtocol(this.protocol);
// reference.setProtocol(CommonConstants.DUBBO);
// reference.setProtocol(CommonConstants.TRIPLE);

总结

对于微服务实际中常常会遇到的多协定通信的场景,Dubbo 不绑定协定的设计让用户能够灵便的抉择通信协议,整个协定抉择过程对下层 API 编码与运维治理齐全通明;对于要在一个集群内同时解决多个协定的场景,Dubbo 的多协定反对也能够从容应对,而单端口的多协定复用反对进一步简化了这一过程。

在接下来的一篇文章中,咱们将具体介绍如何在 Dubbo 框架中开发 gRPC 协定通信的服务,极大的简化了 gRPC 微服务开发成本,防止了二次开发,为原生 gRPC 提供了对立的编程 API 与开箱即用的服务治理能力。

相干链接:

[1]产品比照

https://cn.dubbo.apache.org/zh-cn/overview/what/xyz-difference/

[2]配置阐明

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/r…

[3]Qos 操作手册

https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/qos/overview/

[4]dubbo-samples-port-unification

https://github.com/apache/dubbo-samples/tree/master/3-extensions/protocol/dubbo-samples-port-unification

退出移动版