Apache Dubbo是一个流行的Java RPC框架,尤其是在中国。有很多项目使用Dubbo。虽然它正在通过适配Reactive StreamsService Mesh来实现未来的新版本Dubbo 3.0,但有许多遗留项目不可能在短期之内被彻底修改。

RSocket是一个支持Reactive Streams语义的二进制通讯协议,主要支持的通讯层包括TCP, WebSocketsAeron(UDP)。与传统RPC相比,它能够提高性能和可靠性。

1.什么是网关?

网关(或代理)是服务消费者和服务提供者之间的一个额外的协议转换器。
通常,该协议转换器将执行一些在两端都不容易完成的工作,以证明额外的协议转换器是正常的。例如,Spring Cloud最近发布了spring-cloud-gateway-rsocketWebSocket/RSocket)网关。网关作用是在两个协议之间进行转换。这样一来,REST客户端就不必修改代码,仍然可以享受RSocket的好处。

2.为什么我们需要一个网关?

没有人喜欢代码更改。更不用说大的代码更改了。RSocket为不同的语言提供了sdk。Java SDK基于Reactive Streams项目。functional programming(函数式编程风格)不仅对许多开发者来说具有较深的学习曲线,而且还为调试和跟踪带来了挑战。

因此,网关的需求是非常有必要的。网关将减少了客户端的代码更改。它适用于服务已经在RSocket中,而客户端仍然在传统RPC中案例。虽然它的效率不如点对点RSocket连接,但它是一个很好的折衷方案。

3.网关是如何工作的?

以下的两点必须牢记:

  • Dubbo是一个传统的RPC框架。转化成RSocket,它只有Mono返回类型,没有stream/Flux类型。

  • 服务提供者必须提供RSocket服务。否则,在两者之间添加网关就没有任何意义了。如果你们说同一种语言,为什么需要翻译?

4.Dubbo的工作原理

为了理解网关是如何工作的,我们需要回顾Dubbo是如何工作的。

image

节点角色说明

节点角色说明
Provider暴露服务的服务提供方
Consumer调用远程服务的服务消费方
Registry服务注册与发现的注册中心
Monitor统计服务的调用次数和调用时间的监控中心
Container服务运行容器

调用关系说明

  1. 服务容器负责启动,加载,运行服务提供者。
  2. 服务提供者在启动时,向注册中心注册自己提供的服务。
  3. 服务消费者在启动时,向注册中心订阅自己所需的服务。
  4. 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  5. 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  6. 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

Dubbo 架构具有以下几个特点,分别是连通性、健壮性、伸缩性、以及向未来架构的升级性。详细的参考Apache Dubbo官网。

使用网关,服务的提供者现在不需要向注册中心注册。相反,它将在网关上创建一个接口并将该接口注册到注册中心。当服务的消费者请求服务时,它将获得网关上的接口。然后,网关将该请求分发给服务提供者。

让我们来看下面的代码:

这是一个Dubbo服务接口

public interface DemoService {
    String findNickById(Integer id);
}

注意,DemoService服务只是在网关上创建的一个接口,并将该接口注册到注册中心

服务的消费者现在发送一个RPC请求:

 public ApplicationRunner runner() throws Exception {
        return args -> {
            DemoService demoService = (DemoService) Proxy.newProxyInstance(
                    DemoService.class.getClassLoader(),
                    new Class[]{DemoService.class},
                    new DubboServiceCallInvocationHandler(proxyService, DemoService.class, ""));
            System.out.println(demoService.findNickById(1));
        };
    }

因为,它不知道这个服务现在是一个RSocket服务。它不使用MonoFlux

在网关上,它将把请求发送到具有相同名称的RSocket服务。

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        return dubbo2ReactiveProxy.invoke(serviceName, method.getName(), version, args);
    }

这就是RSocket服务接口。请记住它只有Mono类型。

public interface ReactiveUserService {
   Mono<User> findUserById(Long id);
}

我们不需要将ReactiveUserService注册到注册中心。

5.结论

在这个简单的示例中,我们演示了如何使用网关在Dubbo RPC服务消费者去调用RSocket服务提供者的服务。RSocket有非常多的用例,这些用例并不需要我们在两端(服务提供方和服务消费方)都修改代码。网关架构可以扩展到连接到其他协议和产品,如数据库消息队列

参考代码:https://github.com/apache/dubbo-samples/blob/3.x/dubbo-samples-rsocket

参考链接:https://dzone.com/articles/dubbo-rsocket-gateway

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐