dubbo-gateway 高性能dubbo网关
dubbo-gateway
dubbo-gateway 提供了http协议到dubbo协议的转换,但【并非】使用dubbo的【泛化】调用(泛化调用性能比普通调用有10-20%的损耗,通过普通异步的调用方式与基于webflux系列的响应式网关整合提高系统的吞吐量,普通调用需要依赖api jar包,需要对接口定义进行改造,除此之外不需要做任何其它改造.另外也支持基于servlet类的应用或网关进行整合
泛化缺点
- 泛化过程数据流会经过了三次转换, 会产生大量的临时对象, 有很大的内存要求。使用反射方式对于旨在榨干服务器性能以获取高吞吐量的系统来说, 难以达到性能最佳
- 同时服务端也会对泛化请求多一重 Map <-> POJO 的来回转换的过程。整体上,与普通的Dubbo调用相比有10-20%的损耗
- 泛化调用在网关或服务消费者阶段无法校验参数类型的有效性,数据要到服务提供者反序列化时才能校验出参数类型的有效性
开源地址
相关注解
@GateWayDubbo
标识这个接口需要自动进行协议转换
/**
* 服务id,可以和dubbo普通调用的配置属性关联.
*/
@AliasFor("id")
String value() default "";
/**
* 服务id,可以和dubbo普通调用的配置属性关联.
* 例如:
com.atommiddleware.cloud.config.dubboRefer.<userService>.version=1.1.0
com.atommiddleware.cloud.config.dubboRefer.<userService>.group=userSystem
以上相当于会调用版本号为1.1.0并且groupw为userSystem的dubbo服务,与@DubboReference的参数对齐,具体支持哪些参数详见配置类DubboReferenceConfigProperties
*/
@AliasFor("value")
String id() default "";
@PathMapping
标记这个接口方法需要进行协议自动转换
/**
* 路径表达式
*/
@AliasFor("path")
String value() default "";
/**
* 路径表达式
*/
@AliasFor("value")
String path() default "";
/**
* 提交方法,GET或POST
*/
RequestMethod requestMethod() default RequestMethod.POST;
public enum RequestMethod {
GET, POST
}
@FromBody
表示参数对象来源于消息体
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
@FromHeader
表示参数对象来源于消息头
/**
* 消息头名称
*/
@AliasFor(annotation = ParamAttribute.class)
String value() default "";
/**
* 消息头名称
*/
@AliasFor(annotation = ParamAttribute.class)
String name() default "";
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
@FromCookie
表示参数对象来源于cookie
/**
* cookie名称
*/
@AliasFor(annotation = ParamAttribute.class)
String value() default "";
/**
* cookie名称
*/
@AliasFor(annotation = ParamAttribute.class)
String name() default "";
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
@FromPath
表示参数对象来源于path,支持path表达式
/**
* path占位符名称
*/
@AliasFor(annotation = ParamAttribute.class)
String value() default "";
/**
* path占位符名称
*/
@AliasFor(annotation = ParamAttribute.class)
String name() default "";
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
@FromQueryParams
表示参数来源于query部分
/**
* query名称
*/
@AliasFor(annotation = ParamAttribute.class)
String value() default "";
/**
* query名称
*/
@AliasFor(annotation = ParamAttribute.class)
String name() default "";
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
@FromAttribute
表示参数来源于attribute
/**
* attribute 名称
*/
@AliasFor(annotation = ParamAttribute.class)
String value() default "";
/**
* attribute 名称
*/
@AliasFor(annotation = ParamAttribute.class)
String name() default "";
/**
* 是否检查参数
*/
@AliasFor(annotation = ParamAttribute.class)
boolean required() default true;
配置示例
@GateWayDubbo("userService")
public interface UserService {
/**
* 数据来源消息体
*/
@PathMapping("/sample/registerUser")
Result registerUser(@FromBody User user);
/**
* 对象数据源来自header
* @param user 用户信息
* @return 结果
*/
@PathMapping(value="/sample/registerUserFromHeader",requestMethod=RequestMethod.GET)
Result registerUserFromHeader(@FromHeader("user") User user);
/**
* 对象数据源来自cookie
* @param user 用户信息
* @return 结果
*/
@PathMapping(value="/sample/registerUserFromCookie",requestMethod=RequestMethod.GET)
Result registerUserFromCookie(@FromCookie("user") User user);
/**
* 对象数据源来自path
* @param user 用户信息
* @return 结果
*/
@PathMapping(value="/sample/registerUserFromPath/{user}",requestMethod=RequestMethod.GET)
Result registerUserFromPath(@FromPath("user") User user);
/**
* 数据来源queryParam
* @param userId 用户id
* @return 取消注销结果
*/
@PathMapping(value="/sample/unRegisterUser",requestMethod=RequestMethod.GET)
Result unRegisterUser(@FromQueryParams("userId")Long userId);
/**
* 数据来源path
* @param userId
* @return
*/
@PathMapping(value="/sample/getUserInfo/{userId}/{gender}",requestMethod=RequestMethod.GET)
Result getUserInfo(@FromPath("userId") Long userId,@FromPath("gender") Short gender);
/**
* 数据来源header 和cookie
* @param userId 用户id
* @param age 年龄
* @return 返回插叙结果
*/
@PathMapping(value="/sample/getUserInfo/byHeaderAndCookie",requestMethod=RequestMethod.GET)
Result getUserInfo(@FromHeader("userId")Long userId,@FromCookie("age")Integer age);
/**
* 全场景
* @param userId 用户id
* @param age 年龄
* @param gender 性别
* @param user 用户信息
* @return 查询结果
*/
@PathMapping("/sample/getUserUserInfoAll/{userId}")
Result getUserUserInfoAll(@FromPath("userId") Long userId,@FromCookie("age")Integer age,@FromHeader("gender")Long gender,@FromBody User user);
}
使用步骤
第一步:按照示例改造api接口,接口需要引入dubbo-gateway-api jar包
<dependency>
<groupId>com.atommiddleware</groupId>
<artifactId>dubbo-gateway-api</artifactId>
<version>1.0.5</version>
</dependency>
第二步:网关引入改造后的jar包,同时引用以下jar包
` <dependency>
<groupId>com.atommiddleware</groupId>
<artifactId>dubbo-gateway-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>`
第三步:没有了。。就是这么简单
项目说明
- dubbo-gateway-api 是核心的api,相关注解都是在此项目中定义
- dubbo-gateway-core 核心实现,实现dubbo-gateway的相关逻辑都在此项目中
- dubbo-gateway-spring-boot-autoconfigure dubbo-gateway的自动装配
- dubbo-gateway-spring-boot-starter dubbo-gateway的starter
- dubbo-gateway-sample-api 示例服务api定义在此项目中
- dubbo-gateway-sample-provider 基于spring cloud的dubbo 服务提供者示例
- dubbo-gateway-sample 基于webflux(spring cloud gateway、zuul2)的接入dubbo-gateway示例
- dubbo-gateway-sample-web-provider 基于sevlet类型的dubbo服务提供者示例
- dubbo-gateway-sample-web-consumer 基于sevlet类型的项目(包括网关比如zuul-1)接入dubbo-gateway示例
配置中心
按照dubbo的正常接入配置进行配置就好了,以下贴出例子使用的配置在nacos配置中心的配置,其中filters使用了Dubbo作为过滤器
服务提供者配置:
dubbo:
protocol:
name: dubbo
port: 20861
server:
port: 8861
spring:
cloud:
nacos:
discovery:
namespace: dev
server-addr: 127.0.0.1:8848
服务消费者配置:
dubbo:
cloud:
subscribed-services: dubbo-gateway-sample-provider
server:
port: 8862
spring:
cloud:
nacos:
discovery:
namespace: dev
server-addr: 127.0.0.1:8848
gateway:
routes:
- id: myGateway
uri: http://127.0.0.1:8862
predicates:
- Path=/**
filters:
- Dubbo
注意:其中filters下面配的"Dubbo"表示使用的是DubboGatewayFilter去处理,如果不配置则不会生效.
其它说明
基于webflux的网关与基于servlet类的web应用接入整合方式是一样的步骤,例子使用的nacos版本2.0.3,如果需要在cookie,header,url,传递复杂参数【非java基本类型】,需先将参数转为json,然后使用UrlEncode进行编码,js中可以使用encodeURIComponent进行编码
dubbo-gateway 高性能dubbo网关的更多相关文章
- Dubbo想要个网关怎么办?试试整合Spring Cloud Gateway
一.背景 在微服务架构中 API网关 非常重要,网关作为全局流量入口并不单单是一个反向路由,更多的是把各个边缘服务(Web层)的各种共性需求抽取出来放在一个公共的"服务"(网关)中 ...
- 【Dubbo篇】--Dubbo框架的使用
一.前述 Dubbo是一种提供高性能,透明化的RPC框架.是阿里开源的一个框架. 官网地址:http://dubbo.io/ 二.架构 组件解释: Provider: 提供者.发布服务的项目.Regi ...
- Spring Boot 2.x (十五):Dubbo + Zookeeper + 新版Dubbo Admin
Dubbo 简介 Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成. 它提供了三大核心能力: 面向接口的远程 ...
- dubbo系列一:dubbo介绍、dubbo架构、dubbo的官网入门使用demo
一.dubbo介绍 Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的RPC实现服务的输出和输入功能,可以和Spring框架无缝集成.简单地说,dubbo是一个基于Spri ...
- Dubbo学习(六) dubbo 架构图 以及调用过程
一.Dubbo结构图 duubo结构图 我们解释以下这个架构图:Consumer服务消费者,Provider服务提供者.Container服务容器.消费当然是invoke提供者了,invoke这条 ...
- DUBBO初探-搭建DUBBO开发环境
我所理解的DUBBO 相对于传统web开发框架,dubbo更加适合于并行系统开发,分布式,模块化.将server和client都注册到zookeeper注册中心上,然后由最外层客户端发起请求到相应cl ...
- dubbo源码—dubbo自定义spring xml标签
dubbo为了和spring更好的集成,提供了一些xml配置标签,也就是自定义标签 spring自定义标签 spring自定义标签的方式如下: 设计配置属性和JavaBean 编写xsd文件,校验xm ...
- dubbo源码—dubbo简介
dubbo是一个RPC框架,应用方像使用本地service一样使用dubbo service.dubbo体系架构 上图中的角色: 最重要的是consumer.registry和provider con ...
- Dubbo源码-Dubbo是如何随心所欲自定义XML标签的
叨叨 今天考虑了很久要不要写这篇文章. 距离<Dubbo源码>系列的开篇到现在已经快两个月时间了.当时是想着工作上的RPC框架使用存在一些让人头疼的问题,就来看看Dubbo给出了一套什么样 ...
随机推荐
- 【LeetCode】697. Degree of an Array 解题报告
[LeetCode]697. Degree of an Array 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/degree- ...
- 【LeetCode】617. Merge Two Binary Trees 解题报告
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...
- 【LeetCode】797. All Paths From Source to Target 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 回溯法 日期 题目地址:https://leetco ...
- idea使用教程-安装
[1]将安装包进行解压-->选择固态盘符 [2]发送到桌面快捷方式,生成一个快捷方式 [3]打开: 选择主题: 先进入再说,免费试用: 创建一个项目: 选择JDK: 找到jetbrains-ag ...
- Linux磁盘分区与挂载
原理介绍 在Linux世界中,一切皆目录,每一块硬盘分区对应Linux的一个目录,所以我们可以通过管理目录来管理硬盘分区,而将硬盘分区与文件目录关联的操作就成为"挂载"[mount ...
- JavaScript交互式网页设计 • 【第8章 jQuery动画与特效】
全部章节 >>>> 本章目录 8.1 显示隐藏动画效果 8.1.1 show() 方法与hide() 方法 8.1.2 toggle()方法 8.1.3 实践练习 8.2 ...
- Java开发之项目分包
在我们开始准备写一个大点规模的项目时,我们不能随便地从main函数就开始往下写,要有清晰的逻辑思路和各个层面上的数据的传递和交互. 同时在我们写项目时也应该分出不同的包来做不同的事情,比如view包就 ...
- javascript实现base64格式转码与解码
最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码! 然后查了一下, ...
- PHP json_encode() 序列化对象、数组、空对象、空数组
$result = [ "object" => ["a" => 1], "array" => [1,2,3,4,5], & ...
- linux分区(挂载)
主分区: 最多4个扩展分区: 最多一个: 扩展分区+主分区最多4个: 不能存放数据,只能划分逻辑分区逻辑分区: 可格式化.存放数据: 分区编号只能从5开始(1.2.3.4编号为主分区或扩展分区) 所有 ...