开发者

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

开发者 https://www.devze.com 2025-10-21 10:26 出处:网络 作者: hello_zzw
目录简介同时发布http、dubbo协议发布方式一发布方式二使用REST风格使用网关转http协议为dubbo协议总结简介
目录
  • 简介
  • 同时发布http、dubbo协议
    • 发布方式一
    • 发布方式二
    • 使用REST风格
  • 使用网关转http协议为dubbo协议
    • 总结

      简介

      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 {javascript
          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 "wordpython" 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 php"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" -http://www.devze.com-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, Ujavascriptser 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协议

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号