企业级网关设计

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://www.mzph.cn/news/869357.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何在 PostgreSQL 中确保数据的异地备份安全性?

文章目录 一、备份策略1. 全量备份与增量备份相结合2. 定义合理的备份周期3. 选择合适的备份时间 二、加密备份数据1. 使用 PostgreSQL 的内置加密功能2. 使用第三方加密工具 三、安全的传输方式1. SSH 隧道2. SFTP3. VPN 连接 四、异地存储的安全性1. 云存储服务2. 内部存储设…

人话学Python-基础篇-字符串

一&#xff1a;字符串的定义 在Python中使用引号来定义。不论是单引号还是双引号。 str1 Hello World str2 "Hello World" 二&#xff1a;字符串的访问 如果我们要取出字符串中单独的字符&#xff0c;需要使用方括号来表示取得的位置。如果要取出字符串的子串&…

原创作品—数据可视化大屏

设计数据可视化大屏时&#xff0c;用户体验方面需注重以下几点&#xff1a;首先&#xff0c;确保大屏信息层次分明&#xff0c;主要数据突出显示&#xff0c;次要信息适当弱化&#xff0c;帮助用户快速捕捉关键信息。其次&#xff0c;设计应直观易懂&#xff0c;避免复杂难懂的…

前端javascript中的排序算法之冒泡排序

冒泡排序&#xff08;Bubble Sort&#xff09;基本思想&#xff1a; 经过多次迭代&#xff0c;通过相邻元素之间的比较与交换&#xff0c;使值较小的元素逐步从后面移到前面&#xff0c;值较大的元素从前面移到后面。 大数据往上冒泡&#xff0c;小数据往下沉&#xff0c;也就是…

大语言模型垂直化训练技术与应用

在人工智能领域&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已经成为推动技术进步的关键力量&#xff0c;垂直化训练技术逐渐成为研究的热点&#xff0c;它使得大模型能够更精准地服务于特定行业和应用场景。本文结合达观数据的分享&#xff0c…

tomcat 项目迁移,无法将项目作为服务service启动

背景 测试服务器需要迁移到正式服务器上&#xff0c;为了方便省事&#xff0c;将测试服务器上的一些文件直接复制到正式服务器 问题 使用startup启动项目之后&#xff0c;可以直接使用使用tomcat9w启动&#xff0c;或者作为服务service启动的时候&#xff0c;显示无法访问到资源…

AGE Cypher 查询格式

使用 ag_catalog 中的名为 cypher 的函数构建 Cypher 查询&#xff0c;该函数返回 Postgres 的记录集合。 Cypher() Cypher() 函数执行作为参数传递的 Cypher 查询。 语法&#xff1a;cypher(graph_name, query_string, parameters) 返回&#xff1a; A SETOF records 参…

自动驾驶事故频发,安全痛点在哪里?

大数据产业创新服务媒体 ——聚焦数据 改变商业 近日&#xff0c;武汉城市留言板上出现了多条关于萝卜快跑的投诉&#xff0c;多名市民反映萝卜快跑出现无故停在马路中间、高架上占最左道低速行驶、转弯卡着不动等情况&#xff0c;导致早晚高峰时段出现拥堵。萝卜快跑是百度 A…

YOLOv5、v7、v8如何修改检测框文字颜色和大小

YOLOv5和YOLOv8默认的标签文字颜色为白色&#xff0c;但是在亮度较大的图片中文字不明显&#xff0c;就需要对标签文字的颜色进行修改 一、YOLOv5 打开X:\Anaconda\envs\your-env\Lib\site-packages\ultralytics\utils\plotting.py X代表你的anaconda安装的盘&#xff0c;yo…

随笔(一)

1.即时通信软件原理&#xff08;发展&#xff09; 即时通信软件实现原理_即时通讯原理-CSDN博客 笔记&#xff1a; 2.泛洪算法&#xff1a; 算法介绍 | 泛洪算法&#xff08;Flood fill Algorithm&#xff09;-CSDN博客 漫水填充算法实现最常见有四邻域像素填充法&#xf…

最全windows提权总结(建议收藏)

当以低权用户进去一个陌生的windows机器后&#xff0c;无论是提权还是后续做什么&#xff0c;第一步肯定要尽可能的搜集信息。知己知彼&#xff0c;才百战不殆。 常规信息搜集 systeminfo 查询系统信息hostname 主机名net user 查看用户信息netstat -ano|find "3389&quo…

论文 | Chain-of-Thought Prompting Elicits Reasoningin Large Language Models 思维链

这篇论文研究了如何通过生成一系列中间推理步骤&#xff08;即思维链&#xff09;来显著提高大型语言模型进行复杂推理的能力。论文展示了一种简单的方法&#xff0c;称为思维链提示&#xff0c;通过在提示中提供几个思维链示例来自然地激发这种推理能力。 主要发现&#xff1…

SDIO CMD 数据部分 CRC 计算规则

使用的在线 crc 计算工具网址&#xff1a;http://www.ip33.com/crc.html CMD CRC7 计算 如下图为使用逻辑分析仪获取的SDIO读写SD卡时&#xff0c;CMD16指令发送的格式&#xff0c;通过逻辑分析仪总线分析&#xff0c;可以看到&#xff0c;该部分的CRC7校验值得0x05,大多数情况…

MySQL之基本查询(上)-表的增删查改

目录 Create(创建) 案例建表 插入 单行数据 指定列插入 单行数据 全列插入 多行数据 全列插入 插入是否更新 插入时更新 替换 Retrieve(读取) 建表插入 select列 全列查询 指定列查询 查询字段为表达式 为查询结果指定别名 结果去重 where条件 比较运算符 逻辑运…

昇腾APN最佳伙伴—英码科技AI算力计算产品亮相WAIC 2024

2024年7月4日-7日&#xff0c; “以共商促共享&#xff0c;以善治促善智”为主题的2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;WAIC&#xff09;在上海世博展览中心隆重举行。国务院总理李强出席开幕式并致辞。来自50多个国家和地区的1300位全球领军人物、展…

分享:Motionity-开源的Web端动画编辑器

Motionity是一个免费且开源的Web端动画编辑器&#xff0c;它结合了After Effects和Canva的优点&#xff0c;为用户提供了强大的动画编辑功能。支持视频剪切、图像搜索过滤、文本动画库、图层蒙版等功能。 一、项目背景与特点 开源项目&#xff1a;Motionity是一个开源项目&…

utf8mb4和utf8的不同、若依框架,代码生成器,gitee,前端vue的下载、修复和启动(寻求大佬帮助若依框架三、2.3)

2024.7.9 一、数据库的排序和统一问题。utf8mb4和utf8的不同1.1 发现问题1.2 解决问题-在idea中用sql生成器&#xff0c;生成sql语句&#xff0c;然后在里面修改1.3 utf8和utf8mb4的区别 二、若依前后端框架。代码生成器&#xff08;还没研究懂&#xff0c;但有三个方案&#x…

重塑智慧生活想象 Yeelight易来举行2024年战略及新品发布会圆满成功

7月9日&#xff0c;智能照明品牌Yeelight易来在广州举行“光为境和无界”——2024年Yeelight易来战略&新品发布会&#xff0c;此次发布会不仅展示了易来在新的一年中取得的显著业绩增长&#xff0c;还发布了多款引领行业潮流的智能新品。同时&#xff0c;发布会还邀请了权威…

如何学好C++?

首先&#xff0c;对于零基础的想学习C的同学&#xff0c;我想要你们先明白一件事&#xff1a;C是一门极为复杂且难以掌握的编程语言。因此推荐在学习C之前可以先去学习C语言&#xff0c;在拥有了一定的知识储备和编程能力后再学习C会更加的高效和相对轻松。 下面推荐从三个方面…

gitee及git的简单使用、下载教(保姆级教程)

前言&#xff1a; GitHub&#xff0c;一个由外国研发的代码开源网站&#xff0c;我们可以通过它获得别人优秀的项目源码&#xff0c;也可以在上面上传自己的劳动成果。但是&#xff0c;我们很难访问外网。于是&#xff0c;我们将目光转向国内一个类似的网站---码云&#xff08…