Skip to content
Browse files
docs: add blog about how to proxy apache dubbo with apache apisix (#1043
  • Loading branch information
lijing-21 committed Feb 28, 2022
1 parent 4e513c7 commit c065ccd78688c18b0da00decf2e3f1d130bcdbcc
Showing 3 changed files with 471 additions and 0 deletions.
@@ -0,0 +1,236 @@
title: "Makes it More Convenient for You to Proxy Dubbo Services in Apache APISIX"
linkTitle: "Makes it More Convenient for You to Proxy Dubbo Services in Apache APISIX"
date: 2022-01-18
description: In this article, we introduced how to use Apache APISIX to implement a proxy for Dubbo Service. By introducing the dubbo-proxy plugin, you can build a simpler and more efficient traffic link for the back-end system of Dubbo framework.

## Background

[Apache Dubbo]( is a MicroService development framework open sourced by Alibaba and donated to Apache, which provides two key capabilities of RPC communication and microservice governance. It has not only been validated by Ali's massive traffic in e-commerce scenario, but also been widely implemented in domestic technology companies.

In practical application scenarios, Apache Dubbo is generally used as the implementation framework for RPC calls between back-end systems, and when HTTP interfaces need to be provided to the front-end, the Dubbo Service is packaged as an HTTP interface through a "glue layer" and then delivered to the front-end system.

[Apache APISIX]( is the top open source project of Apache Software Foundation and the most active open source gateway project today. As a dynamic, real-time, high-performance open source API gateway, Apache APISIX provides rich traffic management features such as load balancing, dynamic upstream, grayscale publishing, service meltdown, authentication, observability, and more.

Benefiting from the advantages of Apache Dubbo application scenarios, Apache APISIX is based on the open source project tengine/mod_dubbo module to equip Apache Dubbo services with HTTP gateway capabilities. Dubbo Service can be easily published as an HTTP service via the dubbo-proxy plugin.

![Architecture Diagram](/imgs/blog/apisix-plugin/1.png)

## How to use

### Getting Started: Installation and Use

> Here we recommend using the Apache APISIX version 2.11 image for installation. This version of APISIX-Base has the Dubbo module compiled by default, so you can use the `dubbo-proxy` plugin directly.
In the next steps, we will use the [`dubbo-samples`]( project for a partial demonstration. This project is a demo application implemented using Apache Dubbo, and in this article we use one of the sub-modules as the Dubbo Provider.

Before we get into the action, let's take a brief look at the definition, configuration, and implementation of the Dubbo interface.

#### Interface implementation

public interface DemoService {
* standard samples dubbo infterace demo
* @param context pass http infos
* @return Map<String, Object></> pass to response http
Map<String, Object> apisixDubbo(Map<String, Object> httpRequestContext);

As shown above, the Dubbo interface is defined in a fixed way. The `Map` of method parameters represents the information passed by APISIX to the Dubbo Provider about the HTTP request (e.g. header, body, ...). The `Map` of the method return value indicates how the Dubbo Provider passes some information to APISIX about the HTTP response to be returned.

After the interface information, the DemoService can be published via XML configuration.

<!-- service implementation, as same as regular local bean -->
<bean id="demoService" class="org.apache.dubbo.samples.provider.DemoServiceImpl"/>

<!-- declare the service interface to be exported -->
<dubbo:service interface="org.apache.dubbo.samples.apisix.DemoService" ref="demoService"/>

After the above configuration, the Consumer can access the `apisixDubbo` method through `org.apache.dubbo.samples.apisix.DemoService` The specific interface implementation is as follows.

public class DemoServiceImpl implements DemoService {
public Map<String, Object> apisixDubbo(Map<String, Object> httpRequestContext) {
for (Map.Entry<String, Object> entry : httpRequestContext.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
Map<String, Object> ret = new HashMap<String, Object>();
ret.put("body", "dubbo success\n"); // http response body
ret.put("status", "200"); // http response status
ret.put("test", "123"); // http response header
return ret;

In the above code, `DemoServiceImpl` prints the received `httpRequestContext` and describes the HTTP response to the Dubbo request by returning a Map object with the specified Key.

#### Operation steps

1. Start [`dubbo-samples`](
2. Enable the `dubbo-proxy` plugin in the `config.yaml` file.

# Add this in config.yaml
- ... # plugin you need
- dubbo-proxy

3. Create an Upstream that points to the Dubbo Provider.

curl -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
"nodes": {
"": 1
"type": "roundrobin"

4. Expose an HTTP route for the DemoService.

curl -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
"host": ""
"uris": [
"plugins": {
"dubbo-proxy": {
"service_name": "org.apache.dubbo.samples.apisix.DemoService",
"service_version": "0.0.0",
"method": "apisixDubbo"
"upstream_id": 1

5. Use the curl command to request Apache APISIX and view the returned results.

curl -H "Host:" -X POST --data '{"name": "hello"}'
< HTTP/1.1 200 OK
< Date: Sun, 26 Dec 2021 11:33:27 GMT
< Content-Type: text/plain; charset=utf-8
< Content-Length: 14
< Connection: keep-alive
< test: 123
< Server: APISIX/2.11.0
dubbo success

The above code returns the `test: 123` Header, and the `dubbo success` string as the body. This is the same as what we expected in the `DemoServiceImpl` code.

6. You can view the logs of the Dubbo Provider.

Key = content-length, Value = 17
Key = host, Value =
Key = content-type, Value = application/x-www-form-urlencoded
Key = body, Value = [B@70754265
Key = accept, Value = */*
Key = user-agent, Value = curl/7.80.0

The Header and Body of the HTTP request are available through the `httpRequestContext`, where the Header is used as a Map element, while the Body has a fixed string "body" as the Key value and a Byte array as the Value.

### Advanced: Complex Scenario Example

As you can see in the simple use case above, we do publish Dubbo Service as an HTTP service via Apache APISIX, but there are obvious limitations in its use. For example, the parameters and return values of the interface must be `Map<String, Object>`.

So, how do you expose the HTTP service through Apache APISIX if there is an interface in your project that is already defined, but does not meet the above restrictions?

#### Operation steps

For the above scenario, we can use the HTTP Request Body to describe the Service and Method to be invoked and the corresponding parameters, and then use the reflection mechanism of Java to realize the invocation of the target method. Finally, the return value is serialized to JSON and written to the HTTP Response Body.

This will further enhance the "HTTP to Dubbo" capability of Apache APISIX and apply it to all existing Dubbo services. For details, see the following.

1. Add a Dubbo Service for existing projects to handle HTTP to Dubbo conversions in a unified way.

public class DubboInvocationParameter {
private String type;
private String value;
public class DubboInvocation {
private String service;
private String method;
private DubboInvocationParameter[] parameters;
public interface HTTP2DubboService {
Map<String, Object> invoke(Map<String, Object> context) throws Exception;
public class HTTP2DubboServiceImpl implements HTTP2DubboService {
private ApplicationContext appContext;
public Map<String, Object> invoke(Map<String, Object> context) throws Exception {
DubboInvocation invocation = JSONObject.parseObject((byte[]) context.get("body"), DubboInvocation.class);
Object[] args = new Object[invocation.getParameters().size()];
for (int i = 0; i < args.length; i++) {
DubboInvocationParameter parameter = invocation.getParameters().get(i);
args[i] = JSONObject.parseObject(parameter.getValue(), Class.forName(parameter.getType()));
Object svc = appContext.getBean(Class.forName(invocation.getService()));
Object result = svc.getClass().getMethod(invocation.getMethod()).invoke(args);
Map<String, Object> httpResponse = new HashMap<>();
httpResponse.put("status", 200);
httpResponse.put("body", JSONObject.toJSONString(result));
return httpResponse;

2. Initiate the relevant call with the following command request.

curl -H "Host:" -X POST --data '
"service": "org.apache.dubbo.samples.apisix.DemoService",
"method": "createUser",
"parameters": [
"type": "org.apache.dubbo.samples.apisix.User",
"value": "{'name': 'hello'}"

## Summary

In this article, we introduced how to use Apache APISIX to implement a proxy for Dubbo Service. By introducing the `dubbo-proxy` plugin, you can build a simpler and more efficient traffic link for the back-end system of Dubbo framework.

We hope that the above steps and use cases will provide you with ideas for using it in relevant scenarios. For more information about the `dubbo-proxy` plugin, please refer to the [official documentation](

0 comments on commit c065ccd

Please sign in to comment.