关于后端:从原理到操作让你在-APISIX-中代理-Dubbo-服务更便捷

52次阅读

共计 5595 个字符,预计需要花费 14 分钟才能阅读完成。

背景

Apache Dubbo 是由阿里巴巴开源并捐献给 Apache 的微服务开发框架,它提供了 RPC 通信 微服务治理 两大要害能力。不仅通过了阿里电商场景中海量流量的验证,也在国内的技术公司中被宽泛落地。

在理论利用场景中,Apache Dubbo 个别会作为后端系统间 RPC 调用的实现框架,当须要提供 HTTP 接口给到前端时,会通过一个「胶水层」将 Dubbo Service 包装成 HTTP 接口,再交付到前端零碎。

Apache APISIX 是 Apache 软件基金会的顶级开源我的项目,也是以后最沉闷的开源网关我的项目。作为一个动静、实时、高性能的开源 API 网关,Apache APISIX 提供了负载平衡、动静上游、灰度公布、服务熔断、身份认证、可观测性等丰盛的流量治理性能。

得益于 Apache Dubbo 的利用场景劣势,Apache APISIX 基于开源我的项目 tengine/mod_dubbo 模块为 Apache Dubbo 服务装备了 HTTP 网关能力。通过 dubbo-proxy 插件,能够轻松地将 Dubbo Service 公布为 HTTP 服务。

如何应用

入门篇:装置应用

这里咱们倡议应用 Apache APISIX 2.11 版本镜像进行装置。该版本的 APISIX-Base 中已默认编译了 Dubbo 模块,可间接应用 dubbo-proxy 插件。

在接下来的操作中,咱们将应用dubbo-samples 我的项目进行局部展现。该我的项目是一些应用 Apache Dubbo 实现的 Demo 利用,本文中咱们采纳其中的一个子模块作为 Dubbo Provider。

在进入正式操作前,咱们先简略看下 Dubbo 接口的定义、配置以及相干实现。

接口实现一览

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);

}

如上所示,Dubbo 接口的定义是固定的。即办法参数中 Map 示意 APISIX 传递给 Dubbo Provider 对于 HTTP request 的一些信息(如:header、body…)。而办法返回值的 Map 示意 Dubbo Provider 传递给 APISIX 要如何返回 HTTP response 的一些信息。

接口信息之后可通过 XML 配置形式公布 DemoService。

 <!-- 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"/>

通过上述配置后,Consumer 可通过 org`.apache.dubbo.samples.apisix.DemoService 拜访其中的 apisix`Dubbo 办法。具体接口实现如下:

public class DemoServiceImpl implements DemoService {

    @Override

    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;

    }

}

上述代码中,DemoServiceImpl 会打印接管到的 httpRequestContext,并通过返回蕴含有指定 Key 的 Map 对象去形容该 Dubbo 申请的 HTTP 响应。

操作步骤

  1. 启动 dubbo-samples 我的项目。
  2. config.yaml 文件中进行 dubbo-proxy 插件启用。
# Add this in config.yaml

plugins:

  - ... # plugin you need

  - dubbo-proxy
  1. 创立指向 Dubbo Provider 的 Upstream。
curl http://127.0.0.1:9180/apisix/admin/upstreams/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{"nodes": {"127.0.0.1:20880": 1},

    "type": "roundrobin"

}'
  1. 为 DemoService 裸露一个 HTTP 路由。
curl http://127.0.0.1:9180/apisix/admin/routes/1  -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '{"host":"example.org""uris": ["/demo"],

    "plugins": {

        "dubbo-proxy": {

            "service_name": "org.apache.dubbo.samples.apisix.DemoService",

            "service_version": "0.0.0",

            "method": "apisixDubbo"

        }

    },

    "upstream_id": 1

}'
  1. 应用 curl 命令申请 Apache APISIX,并查看返回后果。
curl http://127.0.0.1:9080/demo  -H "Host: example.org"  -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

上述代码返回中蕴含了test: 123 Header,以及 dubbo success 字符串作为 Body 体。这与咱们在 DemoServiceImpl 编码的预期成果统一。

  1. 查看 Dubbo Provider 的日志。
Key = content-length, Value = 17

Key = host, Value = example.org

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

通过 httpRequestContext 能够拿到 HTTP 申请的 Header 和 Body。其中 Header 会作为 Map 元素,而 Body 中 Key 值是固定的字符串 ”body”,Value 则代表 Byte 数组。

进阶篇:简单场景示例

在上述的简略用例中能够看出,咱们的确通过 Apache APISIX 将 Dubbo Service 公布为一个 HTTP 服务,然而在应用过程中的限度也非常明显。比方:接口的参数和返回值都必须要是 Map<String, Object>

那么,如果我的项目中呈现曾经定义好、但又不合乎上述限度的接口,该如何通过 Apache APISIX 来裸露 HTTP 服务呢?

操作步骤

针对上述场景,咱们能够通过 HTTP Request Body 形容要调用的 Service 和 Method 以及对应参数,再利用 Java 的反射机制实现目标办法的调用。最初将返回值序列化为 JSON,并写入到 HTTP Response Body 中。

这样就能够将 Apache APISIX 的 「HTTP to Dubbo」 能力进一步增强,并利用到所有已存在的 Dubbo Service 中。具体操作可参考下方:

  1. 为已有我的项目减少一个 Dubbo Service 用来对立解决 HTTP to Dubbo 的转化。
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;

}





@Component

public class HTTP2DubboServiceImpl implements HTTP2DubboService {



    @Autowired

    private ApplicationContext appContext;

    

    @Override

    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;

    }



}
  1. 通过如下命令申请来发动相干调用。
curl http://127.0.0.1:9080/demo  -H "Host: example.org"  -X POST --data '{"service":"org.apache.dubbo.samples.apisix.DemoService","method":"createUser","parameters": [

        {

            "type": "org.apache.dubbo.samples.apisix.User",

            "value": "{'name':'hello'}"

        }

    ]

}'

总结

本文为大家介绍了如何借助 Apache APISIX 实现 Dubbo Service 的代理,通过引入 dubbo-proxy 插件便可为 Dubbo 框架的后端系统构建更简略更高效的流量链路。

心愿通过上述操作步骤和用例场景分享,能为大家在相干场景的应用提供借鉴思路。更多对于 dubbo-proxy 插件的介绍与应用可参考官网文档。

对于 Apache APISIX

Apache APISIX 是一个动静、实时、高性能的开源 API 网关,提供负载平衡、动静上游、灰度公布、服务熔断、身份认证、可观测性等丰盛的流量治理性能。

Apache APISIX 能够帮忙企业疾速、平安地解决 API 和微服务流量,包含网关、Kubernetes Ingress 和服务网格等。目前已被普华永道数据安全团队、腾讯蓝军、安全河汉实验室、爱奇艺 SRC 和源堡科技平安团队等业余网络安全机构测试,并给予了高度认可。

Apache APISIX 落地用户(仅局部)

  • Apache APISIX GitHub:https://github.com/apache/apisix
  • Apache APISIX 官网:https://apisix.apache.org/
  • Apache APISIX 文档:https://apisix.apache.org/zh/…

正文完
 0