dubbo http流量接入dubbo后端服务方式

 更新时间:2025年10月21日 08:36:51   作者:hello_zzw  
Dubbo协议基于TCP,适用于后端高效RPC通信,但对前端不友好,可通过多协议发布或网关协议转换支持HTTP接入,主流网关如Higress、APISIX可实现协议转换和自动服务发现

简介

dubbo协议是基于TCP的二进制私有协议,更适合作为后端微服务间的高效RPC通信协议,也导致dubbo协议对于前端流量接入不是很友好。在dubo框架中,有两种方式可以解决这个问题:

  • 多协议发布【推荐】,为dubbo协议服务暴露rest风格的http协议访问方式。
  • 通过网关实现 http->dubbo协议转换,这种方式需要将http协议转换为后端服务能识别的dubbo协议,要求网关必须支持dubbo协议。

同时发布http、dubbo协议

dubbo框架支持为同一个服务发布多个协议,并且支持客户端通过同一个端口以不同的协议访问服务。

发布方式一

dubbo协议的基础上增加tri协议

dubbo:
  protocol:
    name: dubbo
    port: 20080
    ext-protocol: tri
public interface DemoService01 {
    String buyApple(Apple apple);
    String sayHello(String name);
}

public class Apple implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String name;
    
    public Apple(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Apple{" +
                "name='" + name + '\'' +
                '}';
    }
}

访问

curl --header "Content-Type:application/json"  --data '{"name":"apple"}' http://localhost:20880/com.doudou.rpc.api.DemoService01/buyApple 

curl --header "Content-Type:text/html"  --data "name" http://localhost:20880/com.doudou.rpc.api.DemoService01/sayHello 

发布方式二

只使用tri协议

dubbo:
  protocol:
    name: tri
    port: 50053

访问

curl --header "Content-Type:application/json"  --data '{"name":"apple"}' http://localhost:50053/com.doudou.rpc.api.DemoService01/buyApple 

curl --header "Content-Type:text/html"  --data "name" http://localhost:50053/com.doudou.rpc.api.DemoService01/sayHello 

使用REST风格

引入javax.ws.rs-api

<dependency>
  <groupId>javax.ws.rs</groupId>
  <artifactId>javax.ws.rs-api</artifactId>
  <version>2.1.1</version>
</dependency>

在使用方法上添加路径注解

import com.alibaba.fastjson2.JSON;
import com.doudou.demo.api.DemoService;
import com.doudou.demo.po.User;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;


@Path("/demo")
@DubboService
public class DemoServiceImpl implements DemoService {
    private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class);

    /**
     * curl --header "Content-Type:text/html"  --data "word" http://localhost:50051/demo/hello
     * curl --header "Content-Type:text/html"  --data "word" http://localhost:50051/com.doudou.demo.api.DemoService/sayHello
     */
    @Path("/hello")
    @POST
    @Override
    public String sayHello(String name) {
        logger.info("name:{}", name);
        return "hello " + name;
    }

    /**
     * curl -X POST --header "Content-Type:text/html" http://localhost:50051/demo/hello2/world
     */
    @Path("/hello2/{name}")
    @POST
    @Override
    public String sayHello2(@PathParam("name") String name) {
        logger.info("name 2:{}", name);
        return "hello 2 " + name;
    }

    /**
     * curl -X POST --header "Content-Type:application/json" "http://localhost:50051/demo/hello3?name=doudou"
     */
    @Path("/hello3")
    @POST
    @Override
    public String sayHello3(@QueryParam("name") String name) {
        logger.info("name 3:{}", name);
        return "hello 3 " + name;
    }

    /**
     * curl -X POST "http://localhost:50051/demo/hello4" --header "Content-Type: application/x-www-form-urlencoded"  -d "name=admin"
     * curl -X POST "http://localhost:50051/com.doudou.demo.api.DemoService/sayHello4" --header "Content-Type: application/x-www-form-urlencoded"  -d "name=admin1"
     *
     * @FormParam 用于接收表单数据‌(application/x-www-form-urlencoded 或 multipart/form-data):
     */
    @Path("/hello4")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)  // 必须指定表单类型
    @Override
    public String sayHello4(@FormParam("name") String name) {
        logger.info("name 4:{}", name);
        return "hello 4 " + name;
    }

    /**
     * curl -X POST --header "Content-Type:application/json" -H "name: world" http://localhost:50051/demo/hello5
     * curl -X POST --header "Content-Type:application/json" -H "name: world" http://localhost:50051/com.doudou.demo.api.DemoService/sayHello5
     */
    @Path("/hello5")
    @POST
    @Override
    public String sayHello5(@HeaderParam("name") String name) {
        logger.info("name 5:{}", name);
        return "hello 5 " + name;
    }

    /**
     * curl -X POST --header "Content-Type:application/json" -H "cookie:name=world" http://localhost:50051/demo/hello6
     * curl -X POST --header "Content-Type:application/json" -H "cookie:name=world" http://localhost:50051/com.doudou.demo.api.DemoService/sayHello6
     */
    @Path("/hello6")
    @POST
    @Override
    public String sayHello6(@CookieParam("name") String name) {
        logger.info("name 6:{}", name);
        return "hello 6 " + name;
    }

    /**
     *  curl -X POST --header "Content-Type:application/json" --data '{"id":1,"name":"world"}'  http://localhost:50051/com.doudou.demo.api.DemoService/sayHello7
     *  curl -X POST --header "Content-Type:application/json" --data '{user:{"id":1,"name":"world"}, user2:{"id":2,"name":"world2"}}'  http://localhost:50051/com.doudou.demo.api.DemoService/sayHello7
     *
     *  {"id":1,"name":"world"}
     */
    @Path("/hello7")
    @POST
    @Override
    public String sayHello7(User user, User user2) {
        logger.info("user:{}", JSON.toJSONString(user));
        logger.info("user2:{}", JSON.toJSONString(user2));
        return JSON.toJSONString(user);
    }
}

使用网关转http协议为dubbo协议

网关需要实现的关键点:

  • 协议转换,支持http到dubbo协议的转换,包括参数映射。
  • 自动地址发现,支持Nacos、Zookeeper、Kubernetes等主流注册中心,动态感知后端dubbo实例变化。
  • 结合dubbo协议的路由,如在发起 dubbo 协议调用时,支持按照特定规则地址筛选、传递附加参数到 dubbo 后端服务。

支持的开源网关

  • Higress
  • Apache APISIX
  • Apache Shenyu

参考HTTP网关接入->dubbo协议

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java并发中的ABA问题学习与解决方案

    Java并发中的ABA问题学习与解决方案

    这篇文章主要介绍了Java并发中的ABA问题学习与解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • SpringBoot整合Pulsar的实现示例

    SpringBoot整合Pulsar的实现示例

    本文主要介绍了SpringBoot整合Pulsar的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • IDEA如何实现显示类的所有方法

    IDEA如何实现显示类的所有方法

    这篇文章主要介绍了IDEA如何显示类的所有方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • Java实现特定范围的完数输出算法示例

    Java实现特定范围的完数输出算法示例

    这篇文章主要介绍了Java实现特定范围的完数输出算法,简单说明了完数的概念、计算原理并结合实例形式分析了java针对给定范围内的完数输出操作实现技巧,需要的朋友可以参考下
    2017-12-12
  • java枚举转list通用类过程

    java枚举转list通用类过程

    文章介绍了如何将Java枚举类型转换为List<Map<String, Object>>的通用类,该类可以实现枚举到列表的转换,并且示例了使用方法
    2025-03-03
  • 关于Jackson的JSON工具类封装 JsonUtils用法

    关于Jackson的JSON工具类封装 JsonUtils用法

    这篇文章主要介绍了关于Jackson的JSON工具类封装 JsonUtils用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    如何在Spring Boot应用中优雅的使用Date和LocalDateTime的教程详解

    这篇文章主要介绍了如何在Spring Boot应用中优雅的使用Date和LocalDateTime,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • java多线程关键字final和static详解

    java多线程关键字final和static详解

    这篇文章主要介绍了java多线程关键字final和static详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • SpringMVC整合SSM实现异常处理器详解

    SpringMVC整合SSM实现异常处理器详解

    SpringMVC是一种基于Java,实现了Web MVC设计模式,请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将Web层进行职责解耦。基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发,SpringMVC也是要简化我们日常Web开发
    2022-10-10
  • Java 如何读取Excel格式xls、xlsx数据工具类

    Java 如何读取Excel格式xls、xlsx数据工具类

    这篇文章主要介绍了Java 如何读取Excel格式xls、xlsx数据工具类的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论