当前位置: 首页 > news >正文

微服务-Gateway

案例搭建

官网地址

在这里插入图片描述
父Pom

<com.alibaba.cloud.version>2.2.8.RELEASE</com.alibaba.cloud.version>
<com.cloud.version>Hoxton.SR12</com.cloud.version>
<com.dubbo.version>2.2.7.RELEASE</com.dubbo.version>
<dependencyManagement><dependencies><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${com.alibaba.cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${com.cloud.version}</version><type>pom</type><scope>import</scope></dependency><!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-dubbo --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId><version>${com.dubbo.version}</version></dependency></dependencies></dependencyManagement>

工程POM

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
server:port: 9005
spring :application:name: gateway-servercloud:nacos:discovery:server-addr: ip:8848gateway:routes:- id: gateway-provideruri: http://127.0.0.1:8088predicates:- Path=/provider/**filters:- StripPrefix=1- id: gateway-consumeruri: http://127.0.0.1:8089predicates:- Path=/consumer/** filters:- StripPrefix=1 #转发之前将路径前面的一个字符串去除 比如/consumer/echo  最终转发到服务是 http://127.0.0.1:8089/echo- id: gateway-lburi: lb://openfeign-provider #负载均衡,填写nacos里面的服务名称predicates:- Path=/lb/**filters:- StripPrefix=1

启动一个普通的服务端和消费端,另外起一个有三台服务的集群,这些节点的搭建比较容易,可以看同目录笔记。
怎么做到负载均衡?怎么探索源码找到负载均衡?
org.springframework.cloud.gateway.filter.LoadBalancerClientFilter

public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {URI url = exchange.getAttribute(GATEWAY_REQUEST_URL_ATTR);String schemePrefix = exchange.getAttribute(GATEWAY_SCHEME_PREFIX_ATTR);if (url == null|| (!"lb".equals(url.getScheme()) && !"lb".equals(schemePrefix))) {return chain.filter(exchange);}// preserve the original urladdOriginalRequestUrl(exchange, url);if (log.isTraceEnabled()) {log.trace("LoadBalancerClientFilter url before: " + url);}// 选择实例final ServiceInstance instance = choose(exchange);if (instance == null) {throw NotFoundException.create(properties.isUse404(),"Unable to find instance for " + url.getHost());}URI uri = exchange.getRequest().getURI();// if the `lb:<scheme>` mechanism was used, use `<scheme>` as the default,// if the loadbalancer doesn't provide one.String overrideScheme = instance.isSecure() ? "https" : "http";if (schemePrefix != null) {overrideScheme = url.getScheme();}// 选择好节点以后重新组织请求URIURI requestUrl = loadBalancer.reconstructURI(new DelegatingServiceInstance(instance, overrideScheme), uri);if (log.isTraceEnabled()) {log.trace("LoadBalancerClientFilter url chosen: " + requestUrl);}exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, requestUrl);return chain.filter(exchange);}

自定义拦截

首先看官方网提供的几种断言,都是比较简单的这里不在演示:
官网地址
源码,这些类提供了这些能力:
在这里插入图片描述
自定义局部
自定义类,这个类可以参考DedupeResponseHeaderGatewayFilterFactory进行定义

@Component
public class CostGatewayFilterFactory extendsAbstractGatewayFilterFactory<CostGatewayFilterFactory.CustomConfig> {public CostGatewayFilterFactory() {super(CustomConfig.class);}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("switchStatus");}@Overridepublic GatewayFilter apply(CostGatewayFilterFactory.CustomConfig config) {return new GatewayFilter() {@Overridepublic Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain) {if (!config.switchStatus.equalsIgnoreCase("on")) {// 如果这个开关是关闭状态return chain.filter(exchange);}long sTime = System.currentTimeMillis();exchange.getAttributes().put("STIME", sTime);return chain.filter(exchange).then(Mono.fromRunnable(() -> {long stime = (long) exchange.getAttributes().get("STIME");long cost = System.currentTimeMillis() - stime;System.out.println("cost is : " + cost + " ms");}));}@Overridepublic String toString() {return filterToStringCreator(CostGatewayFilterFactory.this).append(config.getSwitchStatus(), config.getSwitchStatus()).toString();}};}public static class CustomConfig  {private String switchStatus;public String getSwitchStatus() {return switchStatus;}public void setSwitchStatus(String switchStatus) {this.switchStatus = switchStatus;}}
}

配置

routes:- id: gateway-provideruri: http://127.0.0.1:8088predicates:- Path=/provider/**filters:- StripPrefix=1- Cost=ON # 这个名字取前面GatewayFilterFactory的

自定义全局

@Component
public class GlobalCustomFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 过滤前System.out.println("Before : " + exchange.getRequest().getURI());return chain.filter(exchange).then(Mono.fromRunnable(() -> {long stime = (long) exchange.getAttributes().get("STIME");long cost = System.currentTimeMillis() - stime;System.out.println("End cost time is  : " +  cost);}));}
}

Spring Cloud Gateway 是基于Netty 实现的,而不是Tomcat。我本来想试试mvc的过滤器和gateway的过滤器的优先级,结果怎么配置filter也不生效,原来如此,菜狗终究是菜狗。
可以换为Tomcat

转发重定向原理

  • Gateway 框架体系处理的入口org.springframework.http.server.reactive.ReactorHttpHandlerAdapter
  • 构建网关上下文:org.springframework.web.server.adapter.HttpWebHandlerAdapter
  • 遍历 Mapping 获取真实处理请求的 Handler org.springframework.web.reactive.DispatcherHandler
  • 构建过滤器链:org.springframework.cloud.gateway.handler.FilteringWebHandler
  • 过滤器必经之路:org.springframework.cloud.gateway.handler.FilteringWebHandler.DefaultGatewayFilterChain
  • 负载均衡过滤器:org.springframework.cloud.gateway.filter.LoadBalancerClientFilter
  • 利用 Netty 发送网络请求过滤器:org.springframework.cloud.gateway.filter.NettyRoutingFilter
    在这里插入图片描述
    RouteToRequestUrlFilter 这个过滤器处理了Route的配置,并且将请求的真实地址存放到了
URI mergedUrl = UriComponentsBuilder.fromUri(uri)// .uri(routeUri).scheme(routeUri.getScheme()).host(routeUri.getHost()).port(routeUri.getPort()).build(encoded).toUri();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);

NettyRoutingFilter 进行了真正的转发调用
在这里插入图片描述
这个经典的图必须贴上:
在这里插入图片描述

相关文章:

微服务-Gateway

案例搭建 官网地址 父Pom <com.alibaba.cloud.version>2.2.8.RELEASE</com.alibaba.cloud.version> <com.cloud.version>Hoxton.SR12</com.cloud.version> <com.dubbo.version>2.2.7.RELEASE</com.dubbo.version> <dependencyManagem…...

【用队列实现栈】【用栈实现队列】Leetcode 232 225

【用队列实现栈】【用栈实现队列】Leetcode 232 225 队列的相关操作栈的相关操作用队列实现栈用栈实现队列 ---------------&#x1f388;&#x1f388;题目链接 用队列实现栈&#x1f388;&#x1f388;------------------- ---------------&#x1f388;&#x1f388;题目链…...

Angular系列教程之观察者模式和RxJS

文章目录 引言RxJS简介RxJS中的设计模式观察者模式迭代器模式 示例代码RxJS 在 Angular 中的应用总结 引言 在Angular开发中&#xff0c;我们经常需要处理异步操作&#xff0c;例如从后端获取数据或与用户的交互。为了更好地管理这些异步操作&#xff0c;Angular中引入了RxJS&…...

展厅设计中搭建的小常识

1、展厅的安全问题 展厅的空间面积大&#xff0c;平时为出现公开展览时人员较少&#xff0c;但遇到开展活动、会展展览时人流量将大大增多&#xff0c;无论是临时的展厅展示还是长期的展示安全问题即使不说都应该是装饰的重中之重&#xff0c;所以在从前期设计规划到后期施工采…...

LeetCode 98. 验证二叉搜索树

98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例…...

自定义shell工具函数之pull_image()

这是一个名为pull_image的Shell脚本函数。让我来解释一下这个函数的功能&#xff1a; function pull_image() {image$1DOCKER_IMAGE_MIRROR$(get_config_or_env DOCKER_IMAGE_MIRROR)if [[ "${DOCKER_IMAGE_MIRROR}" "1" ]]; thenif [[ "$(uname -m…...

2019年认证杯SPSSPRO杯数学建模C题(第二阶段)保险业的数字化变革全过程文档及程序

2019年认证杯SPSSPRO杯数学建模 基于统计建模的车险业数字变革研究 C题 保险业的数字化变革 原题再现&#xff1a; 车险&#xff0c;即机动车辆保险。保险自身是一种分散风险、消化损失的经济补偿制度&#xff0c;车险即为分散机动车辆在行驶过程中可能发作的未知风险和损失…...

【数据结构和算法】反转链表

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 方法一&#xff1a;迭代&#xff08;双指针&#xff09; 2.2 方法二&#xff1a;递归 三、代码 3.…...

What is `GenericFilterBean` does?

GenericFilterBean 是 SpringWeb 框架中提供的一个抽象基类&#xff0c;其对 javax.servlet.Filter接口进行了封装和扩展&#xff0c;它简化了在 Servlet环境下创建自定义过滤器的工作。 GenericFilterBean 主要特点包括&#xff1a; 集成 Spring 容器&#xff1a; 由于它是一…...

突破通胀风险,聚焦现货黄金投资机遇

随着全球经济不断发展和金融市场的波动&#xff0c;通胀风险成为各界关注的焦点。在面对通胀带来的财务压力和资产贬值的威胁时&#xff0c;投资者都在寻找稳定且可靠的避险资产。而现货黄金作为一种值得瞩目的投资工具&#xff0c;正吸引着越来越多投资者的目光。 黄金作为一种…...

Jenkins集成Sonar Qube

下载插件 重启Jenkins 容器 sonarqube 使用令牌 Jenkins 配置 重新构建...

Angular系列教程之zone.js和NgZone

文章目录 什么是zone.jsZone的工作原理Zone的常见用途NgZone&#xff1a;Angular中的zone.js使用NgZone使用NgZone执行代码使用NgZone外部检测 结论 什么是zone.js 在Angular中&#xff0c;zone.js是一个非常重要的库&#xff0c;它为我们提供了一种跟踪和管理异步操作的机制。…...

阿里巴巴的第二代通义千问可能即将发布:Qwen2相关信息已经提交HuggingFace官方的transformers库

本文来自DataLearnerAI官方网站&#xff1a;阿里巴巴的第二代通义千问可能即将发布&#xff1a;Qwen2相关信息已经提交HuggingFace官方的transformers库 | 数据学习者官方网站(Datalearner) 通义千问是阿里巴巴开源的一系列大语言模型。Qwen系列大模型最高参数量720亿&#xf…...

肯尼斯·里科《C和指针》第6章 指针(6)编程的练习:查找字符

1.编写一个函数&#xff0c;它在一个字符串中进行搜索&#xff0c;查找在一个给定字符集合中出现的所有字符。这个函数的原型如下&#xff1a; char *find_char( char const *source, char const *chars ); 它的基本想法是查找source字符串中匹配chars字符串中任何字符的第1个…...

Entity Framework知识点整理

Entity Framework Entity Framework&#xff08;EF&#xff09;是微软提供的一种对象关系映射&#xff08;Object-Relational Mapping&#xff0c;ORM&#xff09;框架&#xff0c;用于在.NET应用程序和关系型数据库之间建立映射关系。它简化了数据访问层的开发&#xff0c;使…...

源码搭建教学:连锁餐饮APP开发实战

连锁餐饮APP&#xff0c;对于很多从事餐饮行业的人来说不会陌生&#xff0c;同样这个项目本身就有着很高的热度。今天&#xff0c;小编将深入为大家讲述一下此系统的前后端开发、数据库设计、用户界面设计等方面&#xff0c;让您深入了解全栈开发的方方面面。 一、项目准备与规…...

使用JavaScript实现一个在线画板

一、引言 随着Web技术的发展&#xff0c;网页上的交互性变得越来越重要。一个在线画板是一个很好的例子&#xff0c;它允许用户在网页上自由创作。在这篇博客中&#xff0c;我们将使用HTML5的Canvas元素和JavaScript来实现一个简单的在线画板 二、HTML结构 首先&#xff0c;…...

微信小程序如何自定义导航栏,怎么确定导航栏及状态栏的高度?导航栏被刘海、信号图标给覆盖了怎么办?

声明&#xff1a;本文为了演示效果&#xff0c;颜色采用的比较显眼&#xff0c;可根据实际情况修改颜色 问题描述 当我们在JSON中将navigationStyle设置成custom后&#xff0c;当前页面的顶部导航栏就需要我们制作了&#xff0c;但出现了一下几个问题&#xff1a; 导航栏的高…...

Spring Boot “How-to“ 指南中文文档-上

本文为官方文档直译版本。原文链接 篇幅较长&#xff0c;遂分两篇 Spring Boot "How-to" 指南中文文档-上 引言Spring Boot Application创建自己的FailureAnalyzer&#xff08;故障分析器&#xff09;自动配置故障诊断启动前自定义环境或应用程序上下文构建 Applicat…...

快速了解spring boot中的@idempotent注解

目的&#xff1a;一定时间内&#xff0c;同样的请求(业务参数相同)访问同一个接口&#xff0c;则只能成功一次&#xff0c;其余被拒绝 幂等实现原理就是利用AOP面向切面编程&#xff0c;在执行业务逻辑之前插入一个方法&#xff0c;生成一个token&#xff0c;存入redis并插入到…...

XCTF-web-easyupload

试了试php&#xff0c;php7&#xff0c;pht&#xff0c;phtml等&#xff0c;都没有用 尝试.user.ini 抓包修改将.user.ini修改为jpg图片 在上传一个123.jpg 用蚁剑连接&#xff0c;得到flag...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...