目录
- 简介
- 同时发布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)。
精彩评论