JAVA微服务_网关

news2024/12/24 10:13:29

服务网关

  • 什么是服务网关/API网关

API Gateway(APIGW / API 网关),顾名思义,是系统对外的唯一入口。API网关封装了系统内部架构,为每个客户端提供定制的API。 近几年来移动应用与企业间互联需求的兴起。从以前单一的Web应用,扩展到多种使用场景,且每种使用场景对后台服务的要求都不尽相同。 这不仅增加了后台服务的响应量,还增加了后台服务的复杂性。随着微服务架构概念的提出,API网关成为了微服务架构的一个标配组件。

  • 为什么要使用网关

微服务的应用可能部署在不同机房,不同地区,不同域名下。此时客户端(浏览器/手机/软件工具)想 要请求对应的服务,都需要知道机器的具体 IP 或者域名 URL,当微服务实例众多时,这是非常难以记忆的,对 于客户端来说也太复杂难以维护。此时就有了网关,客户端相关的请求直接发送到网关,由网关根据请求标识 解析判断出具体的微服务地址,再把请求转发到微服务实例。这其中的记忆功能就全部交由网关来操作了。

负载均衡、路由、限流、协议适配、服务降级、熔断、重试、鉴权、计量计费

各种网关方案

Nginx + Lua

没有熔断、重试等功能

Kong

对Nginx+Lua再次封装

SpringCloud Gateway

Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

WebFlux(异步非阻塞IO)

Zuul

1.0版本单线程,后来跳票,已经出了GateWay

  • 那还需要nginx不?是不是需要动静分离之类的?加了nginx的话,熔断之类的还能用不?
  • 熔断应该可以用,毕竟自己断了就行;重试应该也可以,对于nginx来说就是还没response,实际上是在重试

SpringCloud Gateway

添加依赖

注:gateway中不能添加springMVC的依赖,因为用的是WebFlux模型

spring:
	cloud:
		gateway:
			route:
				- id: #路由对象唯一标识(随便写,唯一就行)
				  uri: #地址
				  predicates:	# 断言,配置规则
				  	- Path=/path1,/path2/**	# 将该Path的访问转发到url(通过网关访问服务的路径)
				  	- After=2021-02-23T14:20:00.000+08:00[Asia/Shanghai] # 还有Before和Between(前后两个时间 )
				  	- Cookie=loginname, ruoyi
				  	- Header=X-Request-Id, \d+ #\d+值匹配正则表达式,其他项设置也可用
				  filters:				    
				    -AddRequestParameter=key, value #给当前路由对象所有请求加入添加参数(直接用形参接收的那个)
				    -AddRequestHeader=key, value	#****加入请求头信息(HttpServletRequest接收,getHeader())
				    -PrefixPath=/mypath	#最终转发路径为:uri+该前缀+path

访问规则:path后面保留,前面网关的网址替换为uri地址

负载均衡

之前写死uri的方式,没法负载均衡

spring:
	cloud:
		gateway:
			route:
				- id: #路由对象唯一标识(随便写,唯一就行)
				  uri: lb://服务id #地址
				  predicates:	# 断言,配置规则
				  	- Path=/path1,/path2/**	# 将该Path的访问转发到url(通过网关访问服务的路径)

lb: LoadBalance

类似ribbon,根据服务id去服务中心拉取该服务的列表,然后进行负载均衡

原理解析

看官网的流程图,

gateway = 断言(前置filter)+过滤(后置filter)

前置后置指转发前后(这是一种比喻的说法,其实前置不像是filter,而像是predicate,满足条件才通过)

来回都要走一次

断言和过滤都有很多工厂类

似乎是抽象工厂模式,顶层接口RoutePredicateFactory下有抽象工厂类,然后又工厂类

断言 Route Predicate Factories

官网有11个

常用的就是配置文件中predicate下的那些

过滤 GatewayFilter Factories

官网有31个

注意过滤器不止过滤的功能,而是类似切面做各种操作(如添加请求头信息)

自定义Filter

自定义的Filter选择合适的接口实现

官网关于全局过滤器的例子。注意全局过滤器不需要在配置文件里配置到某一服务上了,因为全局有效;

@Bean
public GlobalFilter customFilter() {
    return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);		//放行
    }
	
    //过滤器顺序,按自然数顺序,-1为在所有fliter之前
    @Override
    public int getOrder() {
        return -1;
    }
}

也可以直接在类上加@Component注解(ruoyi的做法)

非全局的filter要进行配置,将自定义filter的类名写上

      routes:
        # 认证中心
        - id: ruoyi-auth
          uri: lb://ruoyi-auth
          predicates:
            - Path=/auth/**
          filters:
            # 验证码处理
            - CacheRequestFilter
            - ValidateCodeFilter
            - StripPrefix=1

Gateway 网关层的白名单实现原理是在过滤器内判断请求地址是否符合白名单,如果通过则跳过当前过滤器。

ServerWebExchange封装了request和response,可以通过get方法拿到

但gateway采用的是webFlux模型,返回的是ServerHttpRequest类的对象

整个Filter类似Servlet的Filter处理流程(doFilter方法)

注意放行后的代码也会被执行,因为gateway组件下响应返回时又要经过Fliter

限流

常见的限流算法有:计数器算法,漏桶(Leaky Bucket)算法,令牌桶(Token Bucket)算法。

Spring Cloud Gateway官方提供了RequestRateLimiterGatewayFilterFactory过滤器工厂,使用RedisLua脚本实现了令牌桶的方式。

1、添加依赖

<!-- spring data redis reactive 依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

配置fliter

spring:
  cloud:
    gateway:
      routes:
        # 系统模块
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
            - name: RequestRateLimiter
              args:
                redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶总容量
                key-resolver: "#{@pathKeyResolver}" # 使用 SpEL 表达式按名称引用 bean

StripPrefix=1配置,表示网关转发到业务模块时候会自动截取前缀。

编写URI限流规则配置类

package com.ruoyi.gateway.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
 * 限流规则配置类
 */
@Configuration
public class KeyResolverConfiguration
{
    @Bean
    public KeyResolver pathKeyResolver()
    {
        return exchange -> Mono.just(exchange.getRequest().getURI().getPath());
    }
}

多次请求会发现返回HTTP ERROR 429,同时在redis中会操作两个key,表示限流成功。

request_rate_limiter.{xxx}.timestamp
request_rate_limiter.{xxx}.tokens
  • 是依赖包里有lua吗?
  • 似乎在容器里注册KeyResolver就行了
  • name什么意思?随便写还是?看看fliter那里

其他限流规则

参数限流:key-resolver: "#{@parameterKeyResolver}"

@Bean
public KeyResolver parameterKeyResolver()
{
	return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("userId"));
}

IP限流:key-resolver: "#{@ipKeyResolver}"

@Bean
public KeyResolver ipKeyResolver()
{
	return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}

拓展:

java代码配置路由

reactor的异步非阻塞模型

java代码配置的生效优先级高,原因是先加载配置再加载代码,导致代码覆盖了配置设置的数据

可视化查看路由

http://localhost:8989/actuator/gateway/routes

management:
	endpoints:
		web:
			exposure:
				include: "*"	#开启所有的Web端点暴漏,有些版本要填写数组,应为["*"]

官网例子:

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

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

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

相关文章

数据结构学习记录——图-最短路径问题(无权图单源最短路径算法、有权图单源最短路径算法、多源最短路径算法、Dijkstra(迪杰斯特拉)算法、Floyd算法)

目录 问题分类 无权图单源最短路径算法 思路 伪代码 时间复杂度 代码实现&#xff08;C语言&#xff09; 有权图单源最短路径算法 Dijkstra&#xff08;迪杰斯特拉&#xff09;算法 伪代码 时间复杂度 代码实现&#xff08;C语言&#xff09; 多源最短路径算法 …

《Apollo 智能驾驶进阶课程》四、感知

1. 感知概貌 2. 传感器和标定 激光雷达&#xff1a;主动式&#xff0c;发射功率限制 Camera: 被动式&#xff0c;受到光照影响大 Radar : 多普勒效率 相对速度 超声波: 感知距离有限&#xff0c;倒车时使用。 … 最后设备还在研发过程中。 PnP问题&#xff0c;解决标定。 IC…

chatgpt赋能python:Python实现字符串匹配的SEO优化

Python实现字符串匹配的SEO优化 在现代网络中&#xff0c;SEO&#xff08;搜索引擎优化&#xff09;已成为一项必不可少的技能。它涉及到网站的排名、用户的流量和营销策略等方面。关键字匹配是一种常见的SEO技术&#xff0c;它可以帮助你的网站在搜索引擎中排名更高。 本篇文…

Java 实现判定顺序表中是否包含某个元素的方法

一、思路 1.定义一个toFind变量来传入要查找的元素 2.遍历整个顺序表并判定当前下标的元素等不等于toFind 3.如果等于就返回一个true&#xff0c;否则返回false。 二、图解 首先调用以下的方法求出顺序表的长度&#xff0c;再使用 for 循环遍历每一个元素。 // 求顺序表的长…

《嵌入式系统》知识总结9:使用STM32固件库操纵GPIO

STM32固件库&#xff08;函数库&#xff09; “STM32 标准函数库”它是由 ST 公司针对 STM32 提供的函数接口&#xff0c;即 API (Application Program Interface)&#xff0c;开发者可调用这些函数接口来配置 STM32的寄存器&#xff0c;使开发人员得以脱离最底层的寄存器操作&…

《阿里大数据之路》研读笔记(1)

首先先看到OLAP和OLTP的区别&#xff1a; OLTP(Online transaction processing):在线/联机事务处理。典型的OLTP类操作都比较简单&#xff0c;主要是对数据库中的数据进行增删改查&#xff0c;操作主体一般是产品的用户或者是操作人员。 OLAP(Online analytical processing):…

libVLC 抓取视频帧并渲染(QGraphicsView)

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 在《libVLC 抓取视频帧并渲染(QWidget)》介绍完 QWidget 对视频帧的渲染之后,是时候介绍第二种方式了 - QGraphicsView/QGraphicsScene/QGraphicsItem 图形视图框架。 基本步骤:自定义一个 QGraphicsIte…

RK3588平台开发系列讲解(驱动基础篇)等待队列

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、等待队列二、等待队列头三、等待队列项四、添加/删除队列五、等待唤醒六、等待事件沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 内核的等待队列是以双循环链表为基础数据结构,与进程调度机制紧…

KeepChatGPT: chatGPT增强插件,解决报错、保持活跃,让AI更丝滑

KeepChatGPT&#xff1a; chatGPT增强插件&#xff0c;解决报错、保持活跃&#xff0c;让AI更丝滑 这是一个ChatGPT的畅聊与增强插件。开源免费。不仅能解决所有报错不再刷新&#xff0c;还有保持活跃、取消审计、克隆对话、净化首页、展示大屏、展示全屏、言无不尽、拦截跟踪…

周赛348(模拟、反向思维、数位DP)

文章目录 [6462. 最小化字符串长度](https://leetcode.cn/problems/minimize-string-length/)阅读理解 [6424. 半有序排列](https://leetcode.cn/problems/semi-ordered-permutation/)模拟 [6472. 查询后矩阵的和](https://leetcode.cn/problems/sum-of-matrix-after-queries/)…

java并发编程:volatile关键字详解

文章目录 内存可见性禁止重排序什么是重排序?重排序的类型有哪些呢&#xff1f; 内存屏障volatile的用途 在Java中&#xff0c;volatile关键字有特殊的内存语义。volatile主要有以下两个功能&#xff1a; 保证变量的内存可见性禁止volatile变量与普通变量重排序 内存可见性 …

RK3588平台开发系列讲解(驱动基础篇)中断下文之 tasklet

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、中断下文之 tasklet二、tasklet相关函数介绍三、tasklet使用示例四、中断视频介绍沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 介绍中断下文之 tasklet 的基础理论知识。 一、中断下文之 tasklet 中断…

C C++ 的内存管理(C++)

目录 C / C 的内存分布 C / C 程序内存区域划分&#xff1a;​ C语言内存管理 C中动态内存管理方式&#xff1a; C内存管理 C内存管理的方式&#xff1a; new / delete 操作内置类型 new 和 delete 操作自定义类型 new 和 delete 与 malloc 和 free 的区别&#xff1a; operato…

基于Springboot的漫画之家系统设计实现

&#x1f49e;文末获取源码联系&#x1f649; &#x1f447;&#x1f3fb; 精选专栏推荐收藏订阅&#x1f447;&#x1f3fb; &#x1f380;Java项目精选实战案例《600套》&#x1f618; https://blog.csdn.net/rucoding/category_12319634.html 文章目录 1、演示视频2、课题背…

QSS盒子模型入门指南:了解和应用基础知识

目录 1. QSS盒子模型的组成部分2. QSS盒子模型的属性3. QSS盒子模型的布局4. QSS盒子模型的调试工具结论 #概述 QSS&#xff08;Qt Style Sheets&#xff09;是一种用于美化和定制化Qt应用程序的样式表语言。了解和掌握QSS盒子模型的基本概念对于创建漂亮的用户界面布局至关重要…

javascript基础二十七:说说 JavaScript 数字精度丢失的问题,解决方案?

一、场景复现 一个经典的面试题 0.1 0.2 0.3 // false 为什么是false呢? 先看下面这个比喻 比如一个数 130.33333333… 这是一个除不尽的运算&#xff0c;3会一直无限循环&#xff0c;数学可以表示&#xff0c;但是计算机要存储&#xff0c;方便下次再使用&#xff0c;但…

IMX6ULL裸机篇之I2C实验-硬件原理图

一. I2C 实验简介 I2C实验&#xff0c;我们就来学习如何使用 I.MX6U 的 I2C 接口来驱动 AP3216C&#xff0c;读取 AP3216C 的传感器数据。 AP3216C是一个三合一的环境光传感器&#xff0c;ALSPSIRLED&#xff0c;ALS是环境光&#xff0c;PS是接近传感器&#xff0c;IR是红外L…

2023 华为 Datacom-HCIE 真题题库 12/12(完结)--含解析

单项选择题 1.[试题编号&#xff1a;190728] &#xff08;单选题&#xff09;以下哪种工具不能用来匹配BGP路由条目&#xff1f; A、基本ACL B、高级ACL C、IP PREFIX LIST D、Community Filter 答案&#xff1a;B 解析&#xff1a;高级ACL是一种用于过滤IPv4报文的ACL&#…

多层级table联动

elementui 多层级table联动&#xff1a; 引用&#xff1a; https://blog.csdn.net/weixin_44780971/article/details/130054925 https://blog.csdn.net/qq_42581563/article/details/114325920 需要了解的属性&#xff1a; select-all 全选的时候执行select &#xff1a; 选择…

MySQL 连接查询

文章目录 一&#xff0c;等值连接二&#xff0c;表别名三&#xff0c;多表等值连接四&#xff0c;自然连接五&#xff0c;自连接六&#xff0c;非等值内连接七&#xff0c;外连接&#xff08;一&#xff09;左外连接&#xff08;二&#xff09;右外连接&#xff08;三&#xff…