Introduction to Dubbo RSocket Gateway
Learn more about implementing the Apache Dubbo RSocket gateway in your applications.
Join the DZone community and get the full member experience.
Join For FreeApache Dubbo is a famous Java RPC framework, especially in China. There are a lot of projects using Dubbo. While it’s getting a modernized into the future by adapting reactive streams and service mesh, there are many legacy projects that cannot be overhauled in one day.
RSocket is application protocol providing Reactive Streams semantics. What it offers compared to traditional RPC are enhanced performance and reliability.
What Is a Gateway?
A gateway, or proxy, is an additional hop between consumer and service provider. Normally, that hop will perform some work that’s not easily done on either end to justify the additional hop. For example, Spring Cloud recently released the WebSocket/RSocket gateway. What that gateway does is translate between the two protocols. This is so that REST clients don’t have to modify the code and can still enjoy the benefits of RSocket.
Why Do We Need a Gateway?
Nobody likes code changes. Let alone big code changes. RSocket has SDKs for different languages. The Java SDK is based on the Reactor project. The functional programming style not only has a deep learning curve for many engineers, but it also creates challenges for debugging and tracing.
Hence, it is necessary to provide a gateway. The gateway will minimize the code changes on client sides. It's for the use case where the service is already in RSocket and the client is still in traditional RPC. Although it is less efficient than point-to-point RSocket connection, it is a good compromise.
How Does the Gateway Work?
There are two things to remember:
- Dubbo is a traditional RPC framework. Translating to RSocket language, it has only
Mono
return type and not the stream/Flux
type. - The server side has to provide RSocket service. Otherwise, there is no meaning to add a gateway in between. Why do you need a translator if you two speak the same language?
How Dubbo Works
To understand how the gateway works, we need to review how Dubbo works.
Dubbo uses a service registry. When a service is created, it needs to register itself on the registry. The consumer would query the registry for the service and then reach the service.
With the gateway, the provider now does not need to register to the registry. Instead, it will create an interface on the gateway and register that interface to the registry. When the consumer requests the service, it will get the interface on the gateway. And then, the gateway will dispatch that request to the service provider.
Let's look at some code:
This is a Dubbo style service :
public interface DemoService {
String findNickById(Integer id);
}
Notice that service is just a skeleton. This service stays on the gateway and will register to the registry.
The consumer now makes a request in the RPC style:
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));
};
}
It doesn't know that the service now is an RSocket service. It doesn't use Mono or Flux.
On the gateway, it will then dispatch the request to the RSocket service bearing the same name.
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return dubbo2ReactiveProxy.invoke(serviceName, method.getName(), version, args);
}
This is what an RSocket service interface looks like. Keep in mind it only has the Mono
type.
public interface ReactiveUserService {
Mono<User> findUserById(Long id);
}
And we don't need to register it.
Conclusion
In this simple example, we demonstrated how to use a gateway to handle Dubbo RPC style client with an RSocket server. RSocket has a wide range of use cases that do not necessarily require us to change the code on both ends. The gateway architecture can be extended to connect to other protocols and products such as databases or message queues.
Opinions expressed by DZone contributors are their own.
Comments