企业级网关设计

tips:本文完全来源于卢泽龙!!!

一、Gateway概述

1.1设计目标

在这里插入图片描述

1.2gateway基本功能

中文文档参考:https://cloud.tencent.com/developer/article/1403887?from=15425
在这里插入图片描述

三大核心:
在这里插入图片描述

二、引入依赖和yaml配置

1.1maven依赖(大坑:spring-web和actuaor一定不要引入!)

<!--gateway-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>

1.2BootStrap.yaml配置

spring:application:name: rical-gatewaycloud:nacos:discovery:server-addr: xx.xxx.xx.xx:8848config:server-addr: xx.xxx.xx.xx:8848 #Nacos作为配置中心地址file-extension: yaml #指定yaml格式的配置

1.3动态路由配置rical-gateway-dev.yaml(nacos配置)

spring:cloud:gateway:routes:- id: search-movieInfouri: https://www.maoyan.compredicates:- Path=/films/**- id: self-checkuri: http://localhost:8080predicates:- Path=/demo/selfCheck.jsonrical:gateway:request:qpslimit: 1timeout: 0

三、自定义Filter

3.1、gateWay网关扩展点介绍

在这里插入图片描述

使用到gateway过滤器:
在这里插入图片描述

3.2、全局限流器

通过在nacos平台的rical-gateway-dev.yaml配置qpslimit和timeout这两个参数,实现限制qps和限流后的等待时间。遭到限制时,直接给客户端返回error响应!

@Component
@Slf4j
public class LimitFilter implements GlobalFilter, Ordered
{@Value("${rical.gateway.request.qpslimit}")private Double qpslimit;@Value("${rical.gateway.request.timeout}")private Integer timeout;//创建一个限流器,参数代表每秒生成的令牌数(用户限流频率设置 每秒中限制qpslimit个请求)RateLimiter rateLimiter;/*** 为什么要在bean的初始化方法赋值?* 因为@value注解是在spring的 populateBean 方法中 通过 AutowiredAnnotationBeanPostProcessor后置处理器中赋值*        * 而如果直接在上面赋值他的执行时机是jvm启动时赋值,该步骤会在spring之前就会产生npe异常*/@PostConstructpublic void init(){rateLimiter = RateLimiter.create(qpslimit);}@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpResponse response = exchange.getResponse();ServerHttpRequest request = exchange.getRequest();HttpHeaders header = response.getHeaders();header.add("Content-Type", "application/json; charset=UTF-8");RequestPath path = request.getPath();//设置等待超时时间的方式获取令牌,如果超timeout为0,则代表非阻塞,获取不到立即返回boolean tryAcquire = rateLimiter.tryAcquire(timeout, TimeUnit.SECONDS);log.info("com.wtrue.rical.gateway.filter.LimitFilter.filter , tryAcquire = {}",tryAcquire);if (!tryAcquire) {JSONObject jsonObject = setResultErrorMsg("当前访问用户过多,请稍后重试");DataBuffer buffer = response.bufferFactory().wrap(jsonObject.toJSONString().getBytes());return response.writeWith(Mono.just(buffer));}// 放行return chain.filter(exchange);}private JSONObject setResultErrorMsg(String msg) {JSONObject jsonObject = new JSONObject();jsonObject.put("code", "406");jsonObject.put("message", msg);return jsonObject;}@Overridepublic int getOrder(){return 0;}
}

3.3、全局日志打印器

注意:该日志打印器只打印配置好路由且没有被上面限流器限流的http请求(比如用户随便乱输入个路径进行请求是不会打印日志的)

@Component
@Slf4j
public class LoggerFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1.获取请求信息ServerHttpRequest request = exchange.getRequest();InetSocketAddress address = request.getRemoteAddress();String method = request.getMethodValue();URI uri = request.getURI();HttpHeaders requestHeaders = request.getHeaders();// 获取请求queryMultiValueMap<String, String> map = request.getQueryParams();log.info("LoggerFilter.filter , request come in, please look down: \n{\n\trequest = {} \n\taddress = {} \n\tmethod = {} \n\turi = {} \n\trequestHeaders = {} \n\tmap = {}\n}",request,address,method,uri,requestHeaders,map);// 2.获取响应信息ServerHttpResponse response = exchange.getResponse();HttpStatus statusCode = response.getStatusCode();MultiValueMap<String, ResponseCookie> cookies = response.getCookies();HttpHeaders responseHeaders = response.getHeaders();log.info("LoggerFilter.filter , response is : \n{\n\tstatusCode = {} \n\tcookies = {} \n\tresponseHeaders = {}\n}",statusCode,cookies,responseHeaders);return chain.filter(exchange);}@Overridepublic int getOrder() {return 1;}
}

四、服务测试(类似美团OCTO功能)

1、大体流程图

在这里插入图片描述

2、具体实现方法

2.1gateway的export包提供一个所有业务方都能使用的controller,并通过springBoot自动装配的办法让业务方一引入依赖就能使用
@RestController
@Slf4j
public class SelfCheckController implements BeanFactoryAware {/*** 业务方引入该export包,就会把业务方自己的appname放进去*/@Value("${spring.application.name}")private String appName;private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}@PostMapping("selfCheck.json")public String testInvoke(@RequestBody SelfCheckRequest request) {try {//1.安全检测invokeSafeCheck(request);//2.获取目标beanClass<?> beanClazz = Class.forName(request.getBeanClazzName());Object tartgetBean = getTartgetBean(beanClazz);//3.转化参数类型列表Class[] parameterTyps = transformParameterTypes(request.getParameterTypes());//4.执行Method method = beanClazz.getMethod(request.getMethodName(), parameterTyps);Object returnValue = method.invoke(tartgetBean, request.getParameters());return JSON.toJSONString(returnValue);}catch (Exception e){log.error("errMsg : {}",e.getMessage(),e);return "自检异常:" + e.getMessage();}}/*** 转化参数类型列表* @param parameterTypes* @return*/@SneakyThrowsprivate Class[] transformParameterTypes(String[] parameterTypes) {if (ArrayUtils.isEmpty(parameterTypes)) {return new Class[0];}Class[] classes = new Class[parameterTypes.length];int index = 0;for (String parameterType : parameterTypes) {Class<?> paramClzz = Class.forName(parameterType);classes[index++] = paramClzz;}return classes;}/*** 获取目标bean* @param beanClazz* @return*/private Object getTartgetBean(Class<?> beanClazz) {Object bean = beanFactory.getBean(beanClazz);if (bean ==  null){throw new RuntimeException("本服务没有自检所需要的bean");}return bean;}/*** 执行前的安全检测* @param request*/private void invokeSafeCheck(SelfCheckRequest request) {String targetAppName = request.getAppName();if (!targetAppName.equals(appName)) {throw new RuntimeException("自检错误!本服务不是目标服务,请检查appName是否传递错误~");}}}
2.2 业务方一定要配置这两个参数,后面有大用
server.servlet.context-path=/demo
spring.application.name=demo

2.3 nacos配置路由规则

- id: self-checkuri: http://localhost:8080predicates:- Path=/demo/selfCheck.json

经过这样配置后,用户就能通过网关访问目标服务器的bean方法了,请求案例如下

POST localhost:10001/demo/selfCheck.json
{"appName": "demo","beanClazzName": "com.example.demo.service.ITestService","methodName": "getTestMap","parameterTypes": ["java.lang.String","java.lang.Integer"],"parameters": ["luzelong",999]
}

目标方法的代码如下:

public Map getTestMap(String key, Integer value) {HashMap<String, Integer> map = new HashMap<>();map.put(key,value);log.info("demo!!!!!!");return map;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3224382.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

大话光学原理:2.最短时间原理、“魔法石”与彩虹

一、最短时间原理 1662年左右&#xff0c;费马在一张信纸的边角&#xff0c;用他那著名的潦草笔迹&#xff0c;随意地写下了一行字&#xff1a;“光在两点间选择的路&#xff0c;总是耗时最少的。”这句话&#xff0c;简单而深邃&#xff0c;像是一颗悄然种下的种子&#xff0c…

【C语言】volatile 关键字详解

在C语言中&#xff0c;volatile关键字用于声明一个变量&#xff0c;告知编译器该变量的值可能会被程序之外的某些因素&#xff08;如硬件或其他并发线程&#xff09;改变。因此&#xff0c;编译器在优化代码时不能对这个变量做假设&#xff0c;也不能优化掉对它的读取或写入操作…

【分布式系统】ceph部署(命令+截图巨详细版)

目录 一.存储概述 1.单机存储设备 2.单机存储的问题 3.商业存储 4.分布式存储​编辑 4.1.什么是分布式存储 4.2.分布式存储的类型 二.ceph概述 1.ceph优点 2.ceph架构 3.ceph核心组件 4.OSD存储后端 5.ceph数据存储过程 6.ceph版本发行生命周期 7.ceph集群部署 …

使用pyqt界面化部署

使用pyqt界面化部署 文章目录 前言一、软件介绍总结 前言 pyqtopencv开发的图像识别qt界面 目前共有五个主要界面&#xff1a;软件介绍界面、省份识别、浙产识别、产地识别界面、以及自定义识别页面。 三叶青图像识别研究简概 一、软件介绍 总结 开发这个图像识别的qt界面&a…

插入排序算法(C语言版)

直接插入排序 插入排序&#xff08;insert sort&#xff09;是一种简单的排序算法&#xff0c;它的工作原理与手动整理一副牌的过程非常相似。 具体来说&#xff0c;我们在未排序区间选择一个基准元素&#xff0c;将该元素与其左侧已排序区间的元素逐一比较大小&#xff0c;并…

编写ONLYOFFICE8.1版本推广活动文章

在这个日新月异的数字时代&#xff0c;高效、协同、智能已成为现代办公的关键词。作为全球领先的在线与桌面办公套件解决方案提供商&#xff0c;ONLYOFFICE始终站在技术创新的前沿&#xff0c;致力于为全球用户带来更加便捷、安全、强大的办公体验。今日&#xff0c;我们满怀激…

【实习问题记录】Nodeclub本地部署

问题描述 在按照官方网站给出的教程一步一步操作以后发现出现以下报错&#xff1a; 问题分析 显示连接不上mongodb&#xff0c;分析报错可能是因为版本不匹配导致的&#xff0c;查看安装的mongodb版本发现是7.0.4&#xff0c;与目标版本不匹配&#xff0c;同时查看mongodb官…

基于 sftp 的 NAS (局域网文件存储服务器)

局域网 NAS (文件存储服务器) 的基本功能有: 能够存储文件, 同时能够通过多个设备访问 (上传/下载) 文件. 这些功能通过 sftp 可以实现. sftp 是基于 SSH 的文件传输协议, SSH 全程加密传输, 使用 公钥 认证 (不使用密码/口令), 能够提供很高的安全性. 上文说到, 在 LVM 和 bt…

如何压缩pdf文件大小,怎么压缩pdf文件大小

在数字化时代&#xff0c;pdf文件因其稳定的格式和跨平台兼容性&#xff0c;成为了工作与学习中不可或缺的一部分。然而&#xff0c;随着pdf文件内容的丰富&#xff0c;pdf文件的体积也随之增大&#xff0c;给传输和存储带来了不少挑战。本文将深入探讨如何高效压缩pdf文件大小…

了解PPO算法(Proximal Policy Optimization)

Proximal Policy Optimization (PPO) 是一种强化学习算法&#xff0c;由 OpenAI 提出&#xff0c;旨在解决传统策略梯度方法中策略更新过大的问题。PPO 通过引入限制策略更新范围的机制&#xff0c;在保证收敛性的同时提高了算法的稳定性和效率。 PPO算法原理 PPO 算法的核心…

IDEA如何创建原生maven子模块

文件 -> 新建 -> 新模块 -> Maven ArcheTypeMaven ArcheType界面中的输入框介绍 名称&#xff1a;子模块的名称位置&#xff1a;子模块存放的路径名创建Git仓库&#xff1a;子模块不单独作为一个git仓库&#xff0c;无需勾选JDK&#xff1a;JDK版本号父项&#xff1a;…

策略路由和路由策略的区别详解

先说策略路由也就是 PBR&#xff1a; 它不会影响路由表的生成&#xff0c;设备的路由表是已经存在而且稳定的。 举个例子&#xff1a; 用 TCP/IP 路由技术一书的表述就是&#xff1a;策略路由就是一个复杂的静态路由。 总结&#xff1a;策略路由是一个基于路由表的影响特定数…

微信服务里底部的不常用功能如何优化的数据分析思路

图片.png 昨天下午茶时光&#xff0c;和闺蜜偶然聊起&#xff0c;其实在微信服务底部&#xff0c;有很多被我们忽略遗忘&#xff0c;很少点过用过的功能服务&#xff0c;往往进入服务只为了收付款或进入钱包&#xff0c;用完就走了&#xff0c;很少拉到底部&#xff0c;看到和用…

mirthConnect 常用示例和语法整理

mirthConnect 常用示例和语法整理 1、jolt json常用语法 https://please.blog.csdn.net/article/details/140137463 2、常用方法 2.1 WinningDateUtils 所有的时间工具在WinningDateUtils里面 获取当前时间&#xff1a;var nowStrWinningDateUtils.getStandardNowStr()获取…

Python函数 之 函数基础

print() 在控制台输出 input() 获取控制台输⼊的内容 type() 获取变量的数据类型 len() 获取容器的⻓度 (元素的个数) range() ⽣成⼀个序列[0, n) 以上都是我们学过的函数&#xff0c;函数可以实现⼀个特定的功能。我们将学习⾃⼰如何定义函数, 实现特定的功能。 1.函数是什么…

由于找不到krpt.dll,无法继续执行代码的7种解决方法

krpt.dll 与 Microsoft Office 套件中的 PDF 文档生成和编辑功能有关。它是 Microsoft Office 中的一项关键组件&#xff0c;在 Word、Excel 等应用程序中扮演着重要角色&#xff0c;支持文档转换成 PDF 格式的功能。那么遇到找不到krpt.dll文件或krpt.dll丢失要怎么办&#xf…

鸿蒙语言基础类库:【@ohos.util.ArrayList (线性容器ArrayList)】

线性容器ArrayList 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 …

FunAudioLLM SenseVoice语音转录与CosyVoice语音合成及语音克隆使用案例

参考: https://fun-audio-llm.github.io/ 1、SenseVoice语音转录 在线体验:https://modelscope.cn/studios/iic/CosyVoice-300M 参考:https://github.com/FunAudioLLM/SenseVoice 下载: pip install -U funasr使用: from funasr import AutoModelmodel_dir = "…

连接与隔离:Facebook在全球化背景下的影响力

在当今全球化的背景下&#xff0c;Facebook作为全球最大的社交网络平台&#xff0c;不仅连接了世界各地的人们&#xff0c;还在全球社会、经济和文化中发挥着深远的影响。本文将深入探讨Facebook在全球化进程中的作用&#xff0c;以及其对个体和社会之间连接与隔离的双重影响。…

odoo中的钩子 Hooks

钩子 钩子&#xff08;Hooks&#xff09;是一种在特定时间点或特定事件发生时执行自定义代码的机制。它们允许开发者在不修改核心代码的情况下&#xff0c;为Odoo添加自定义功能或扩展现有功能。以下是关于Odoo钩子的一些关键点和常见用法&#xff1a; 一、钩子的类型 pre_i…