Higress提供了从HTTP协议到Dubbo协议进行转换的功能,用户通过配置协议转换,可以将一个Dubbo服务以HTTP接口暴露出来,从而用HTTP请求实现对Dubbo接口的调用。本文将通过一个示例来介绍如何用Higress配置HTTP到Dubbo的协议转换。

前提条件

  1. Higress目前支持的Dubbo框架的版本为2.x。若您使用Dubbo3.0,要求使用dubbo协议(目前暂不支持Triple协议。Triple协议底层基于gRPC,可以直接代理,无需做协议转化)。

部署Dubbo服务

您可以选用Naocs或者Zookeeper任意一种作为注册中心,部署一个Dubbo服务。具体可以参考以下文档:

https://cn.dubbo.apache.org/zh-cn/overview/what/ecosystem/registry/nacos/

https://cn.dubbo.apache.org/zh-cn/overview/what/ecosystem/registry/zookeeper/

假设我们现在已经部署了如下一个Dubbo服务,其服务名为com.alibaba.nacos.example.dubbo.service.DemoService,并指定了该服务的version为“1.0.0”,group为“dev”,下面我们将介绍如何为该服务配置协议转换。

  1. package com.alibaba.nacos.example.dubbo.service;
  2. public interface DemoService {
  3. String sayName(String name);
  4. }

通过Ingress转发请求到Dubbo服务

Higress可以通过McpBridge来对接Nacos或者Zookeeper作为服务来源。这里我们以Nacos为例,假设Naocs的ip地址为192.xxx.xx.32,我们可以在K8s集群中apply以下资源来配置McpBridge

  1. apiVersion: networking.higress.io/v1
  2. kind: McpBridge
  3. metadata:
  4. name: default
  5. namespace: higress-system
  6. spec:
  7. registries:
  8. - domain: 192.xxx.xx.32
  9. nacosGroups:
  10. - DEFAULT_GROUP
  11. name: nacos-service-resource
  12. port: 8848
  13. type: nacos2

通过McpBridge,我们可以直接从Nacos中发现Dubbo服务,并为其创建路由。

接下来我们创建如下Ingress,从而创建一条指向Dubbo服务的HTTP路由:

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. annotations:
  5. higress.io/destination: providers:com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev.DEFAULT-GROUP.public.nacos
  6. higress.io/rpc-destination-name: httproute-http2rpc-demo
  7. name: httproute-http2rpc-demo-ingress
  8. namespace: higress-system
  9. spec:
  10. ingressClassName: higress
  11. rules:
  12. - http:
  13. paths:
  14. - backend:
  15. resource:
  16. apiGroup: networking.higress.io
  17. kind: McpBridge
  18. name: default
  19. path: /dubbo
  20. pathType: Prefix

这样,path前缀为/dubbo的请求就会被路由到我们刚刚创建的Dubbo服务上。

通过Higress自定义的CRD-Http2Rpc配置HTTP到Dubbo的协议转换规则

经过上述步骤,我们已经通过Ingress将path前缀为/dubbo的请求路由到我们的Dubbo服务上。但光是这样是无法正常通信的,因为Dubbo服务使用的是定制的Dubbo协议,无法天然与HTTP协议进行兼容。因此接下来我们还要配置具体的HTTP到Dubbo的协议转换规则,从而实现用HTTP请求来调用Dubbo服务。

  1. apiVersion: networking.higress.io/v1
  2. kind: Http2Rpc
  3. metadata:
  4. name: httproute-http2rpc-demo
  5. namespace: higress-system
  6. spec:
  7. dubbo:
  8. service: com.alibaba.nacos.example.dubbo.service.DemoService
  9. version: 1.0.0
  10. group: dev
  11. methods:
  12. - serviceMethod: sayName
  13. headersAttach: “*”
  14. httpMethods:
  15. - GET
  16. httpPath: “/dubbo/hello
  17. params:
  18. - paramKey: p
  19. paramSource: QUERY
  20. paramType: java.lang.String

在以上Http2Rpc中,我们配置了将path为/dubbo/hello的HTTP请求转发到Dubbo服务com.alibaba.nacos.example.dubbo.service.DemoService:1.0.0:dev 中,并调用其sayName方法,而该方法的参数则通过HTTP url中的的query参数p来指定。

请求验证

通过以上配置,我们就可以执行以下curl命令来调用这个dubbo服务了:

  1. $curl localhost/dubbo/hello?p=abc
  2. {“result”:”Service [name :demoService , port : 20880] sayName(\”abc\”) : Hello,abc”}

将整个请求body作为方法参数

Http2Rpc支持将整个请求body序列化为Dubbo方法的入参,如下所示:

  1. apiVersion: networking.higress.io/v1
  2. kind: Http2Rpc
  3. metadata:
  4. name: httproute-http2rpc-demo
  5. namespace: higress-system
  6. spec:
  7. dubbo:
  8. service: com.alibaba.nacos.example.dubbo.service.DemoService
  9. version: 1.0.0
  10. group: dev
  11. methods:
  12. - serviceMethod: sayName
  13. headersAttach: “*”
  14. httpMethods:
  15. - POST
  16. httpPath: “/dubbo/hello
  17. paramFromEntireBody:
  18. paramType: java.lang.String

通过paramFromEntireBody字段,即可将整个请求body序列化为Dubbo方法的入参。参数的类型通过paramFromEntireBody.paramType字段来指定。该场景适用于Dubbo方法只有一个参数的情况,如果同时指定了paramFromEntireBody和params,params字段的内容将被忽略。

通过以上配置,我们可以执行以下命令来调用dubbo服务,注意请求的body必须符合json格式:

  1. $curl localhost/dubbo/hello -X POST -d ‘“abc”‘
  2. {“result”:”Service [name :demoService , port : 20880] sayName(\”abc\”) : Hello,abc”}

配置参考

Http2Rpc的相关配置项参考HTTP转Dubbo配置说明