微服务-Gateway

news2024/9/21 14:43:42

案例搭建

官网地址

在这里插入图片描述
父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-server
  cloud:
    nacos:
      discovery:
        server-addr: 111.229.199.181:8848
    gateway:
      routes:
        - id: gateway-provider
          uri: http://127.0.0.1:8088
          predicates:
            - Path=/provider/**
          filters:
            - StripPrefix=1
        - id: gateway-consumer
          uri: http://127.0.0.1:8089
          predicates:
            - Path=/consumer/** 
          filters:
            - StripPrefix=1 #转发之前将路径前面的一个字符串去除 比如/consumer/echo  最终转发到服务是 http://127.0.0.1:8089/echo
        - id: gateway-lb
          uri: 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 url
		addOriginalRequestUrl(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();
		}
		// 选择好节点以后重新组织请求URI
		URI 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 extends
        AbstractGatewayFilterFactory<CostGatewayFilterFactory.CustomConfig> {
    public CostGatewayFilterFactory() {
        super(CustomConfig.class);
    }
    @Override
    public List<String> shortcutFieldOrder() {
       return Arrays.asList("switchStatus");
    }
    @Override
    public GatewayFilter apply(CostGatewayFilterFactory.CustomConfig config) {
        return new GatewayFilter() {

            @Override
            public 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");
                        }));
            }
            @Override
            public 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-provider
    uri: http://127.0.0.1:8088
    predicates:
      - Path=/provider/**
    filters:
      - StripPrefix=1
      - Cost=ON # 这个名字取前面GatewayFilterFactory的

自定义全局

@Component
public class GlobalCustomFilter implements GlobalFilter {
    @Override
    public 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 进行了真正的转发调用
在这里插入图片描述
这个经典的图必须贴上:
在这里插入图片描述

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

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

相关文章

Python基础-05(输出输入、if、if else和elif)

文章目录 前言一、输出&#xff08;print()&#xff09;和输入&#xff08;input()&#xff09;二、if、if else、elif1.if2.if else3.关于输入input的默认值4.elif 前言 今天复习一些非常基础的内容&#xff0c;以及if、if else和elif语句 一、输出&#xff08;print()&…

【vue/uniapp】pdf.js 在一些型号的手机上不显示

引入&#xff1a; uniapp 项目通过 pdf.js 来在线浏览 pdf 链接&#xff0c;在微信小程序中都显示正常&#xff0c;但是通过 app 跳转小程序&#xff0c;在苹果、小米显示正常&#xff0c;但是华为和 oppo 就不显示&#xff0c;可以通过降 pdf.js 的版本来解决这个问题。 解决&…

1.3 力扣二叉树中等题

题目一&#xff1a; 669. 修剪二叉搜索树 给你二叉搜索树的根节点 root &#xff0c;同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[low, high]中。修剪树 不应该 改变保留在树中的元素的相对结构 (即&#xff0c;如果没有被移除&…

python flask图书管理系统带文档

python flask图书管理系统带文档。功能&#xff1a;登录&#xff0c;图书的增删改查&#xff0c;读者管理&#xff0c;借阅记录&#xff0c;有文档。 技术&#xff1a;python3,flask,mysql,html。 包含源码数据库文件文档。 源码下载地址&#xff1a; https://download.csd…

Calibre PEX Hspice Netlist提取步骤(数模芯片提取spice netlist流程)

在数模混合芯片中&#xff0c;通常模拟需要数字模块通过calibre工具来提取Hspice netlist用于功耗仿真。注意这里的spice netlist和做Calibre的spice netlist是不太一样的。 另外在做calibre pex时需要确保当前的design LVS已经pass。否则功耗仿真可能会不准。 Calibre LVS常…

Z-score 因子的深入思考

最新&#xff08;2024 年 1 月&#xff09;出版的 SC 技术分析&#xff08;Techical Analysis of Stock & Commodities&#xff09;的第 4 条文章给到了 Z-score&#xff0c;原文标题为《Z-score: How to use it in Trading》。今天的笔记&#xff0c;就借此机会&#xff0…

在日常工作中如何保障服务器的安全?

服务器在日常工作中具有重要的作用。它是网络的核心组成部分&#xff0c;承担着提供信息和服务的任务。 1.服务器为各种应用提供数据存储和处理服务&#xff0c;支持电子邮件、网页浏览、文件下载等服务&#xff0c;为用户提供高效、安全、可靠的网络访问。 2.服务器承载着各…

uni-app中实现元素拖动

uni-app中实现元素拖动 1、代码示例 <template><movable-area class"music-layout"><movable-view class"img-layout" :x"x" :y"y" direction"all"><img :src"musicDetail.bgUrl" :class&…

Linux mcd命令教程:如何在MS-DOS文件系统中切换工作目录(附实例教程和注意事项)

Linux mcd命令介绍 mcd是mtools工具的指令&#xff0c;它用于在MS-DOS文件系统中切换工作目录。如果不加任何参数&#xff0c;它将显示当前所在的磁盘和工作目录。 Linux mcd命令适用的Linux版本 mcd命令在所有主流的Linux发行版中都可以使用&#xff0c;包括但不限于Ubuntu…

Canvas保姆级教程----深入解析HTML5 Canvas工作原理和常用方法

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

01、Kafka ------ 下载、安装 ZooKeeper 和 Kafka

目录 Kafka是什么&#xff1f;安装 ZooKeeper下载安装启动 zookeeper 服务器端启动 zookeeper 的命令行客户端工具 安装 Kafka下载安装启动 Kafka 服务器 Kafka是什么&#xff1f; RabbitMQ的性能比ActiveMQ的性能有显著提升。 Kafka的性能比RabbitMQ的性能又有显著提升。 K…

ngrok-内网穿透

一、访问官网下载相关的内容 Download (ngrok.com) linux或者windows可供选择&#xff0c;主要在于你的项目跑在什么地方 选择下载 二、获取Authtoken 点击右上角登录&#xff0c;没有号用谷歌账号登录即可跳转 三、在Windows进行内网穿透 下载打开 打开 运行在命令行中&am…

【42页动态规划学习笔记分享】动态规划核心原理详解及27道LeetCode相关经典题目汇总

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…

【Spring】19 AOP介绍及实例详解

文章目录 1. 定义1&#xff09;什么意思呢&#xff1f;2&#xff09;如何解决呢&#xff1f; 2. 基本概念1&#xff09;切面&#xff08;Aspect&#xff09;2&#xff09;切点&#xff08;Pointcut&#xff09;3&#xff09;通知&#xff08;Advice&#xff09;4&#xff09;连…

【python入门】day17:模块化编程、math库常见函数

什么叫模块 模块的导入 导入所有&#xff1a;import 模块名称 导入指定&#xff1a;from 模块名称 import 函数/变量/类 python的math库 什么是math库 Python的math库是Python的内建库之一&#xff0c;它提供了许多数学函数&#xff0c;包括三角函数、对数函数、幂函数等&a…

迅为RK3588开发板使用 FFMpeg 进行推流

Debian/Ubuntu 系统使用以下命令安装 FFMpeg &#xff0c;如下图所示&#xff1a; apt-get install ffmpeg 使用 ifconfig 查看开发板 ip 为 192.168.1.245 如下图所示&#xff1a; 使用 FFMpeg 推流一个 mp4 视频进行测试&#xff0c;作者将测试视频 test.mp4 放在了根目录下…

linuxnodejs 20.* 安装问题,version `GLIBCXX_3.4.26‘

背景 今天服务器被重置拉&#xff0c;nodejs 环境不存在&#xff0c;特意安装下nodejs&#xff0c;一访问官网&#xff0c;妈呀&#xff0c;居然到20版本拉&#xff01;就尝试安装下最新版本&#xff01; 过程 $ cd /opt $ curl -OL https://nodejs.org/dist/v20.10.0/node-v2…

c++语言基础18-开房门

题目描述 假设你手里有一串钥匙&#xff0c;这串钥匙上每把钥匙都有一个编号&#xff0c;对应着一个房门的编号。现给你一个房门编号&#xff0c;你需要判断是否能够打开该房门。 输入描述 测试数据共有多组。 第一行为一个整数 s&#xff0c;表示共有多少组测试数据。 每组第一…

Spring高手之路-Spring中Bean的五大作用域

目录 Singleton&#xff08;单例&#xff09;&#xff1a;默认的作用域 Prototype&#xff08;原型&#xff09; Request&#xff08;请求&#xff09; Session&#xff08;会话&#xff09; Global Session&#xff08;全局会话&#xff09; 五大作用域范围对比 作用域…

[C#]基于deskew算法实现图像文本倾斜校正

【算法介绍】 让我们开始讨论Deskeweing算法的一般概念。我们的主要目标是将旋转的图像分成文本块&#xff0c;并确定它们的角度。为了让您详细了解我将使用的方法&#xff1a; 照常-将图像转换为灰度。应用轻微的模糊以减少图像中的噪点。现在&#xff0c;我们的目标是找到带…