微服务网关Gateway

gateway快速⼊⻔

下面,我们就演示下⽹关的基本路由功能。基本步骤如下:

  1. 创建SpringBoot⼯程gateway,引⼊⽹关依赖 2

  2. 编写基础配置和路由规则

  3. 启动⽹关服务进⾏测试

1)创建gateway服务,引⼊依赖

创建服务: 创建⼀个 api-gateway 的模块,导⼊相关依赖

XML 复制代码
<!-⽹关-->
 <dependency>
 	<groupId>org.springframework.cloud</groupId>
 	<artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>
 <!--nacos服务发现依赖(gateway⾼级使⽤需要)-->
 <dependency>
 	<groupId>com.alibaba.cloud</groupId>
 	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
 </dependency>
2)编写基础配置和路由规则

创建application.yml⽂件,内容如下:

XML 复制代码
##############################
基本版本
#####################################
 ##
 server:
  port: 7000
 spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes: # 路由数组[路由 就是指定当请求满⾜什么条件的时候转到哪个微服务]       
      	- id: product_route # 当前路由的标识, 要求唯⼀
          uri: http://localhost:8081/ # 请求要转发到的地址
          order: 1 # 路由的优先级,数字越⼩级别越⾼
          predicates: # 断⾔(就是路由转发要满⾜的条件)
            - Path=/product-serv/** # 当请求路径满⾜Path指定的规则时,才进⾏路由转发
          
          filters: # 过滤器,请求在传递过程中可以通过过滤器对其进⾏⼀定的修改
            - StripPrefix=1 # 转发之前去掉1层路径


localhost:8081/product/19
 localhost:7000/product-serv/product/19
##############################⾼级版本#####################################
##
#启动类添加注解@EnableDiscoveryClient,项⽬添加坐标
server:
  port: 7000
 spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes:
        - id: product_route
          uri: lb://service-product # lb指的是从nacos中按照名称获取微服务,并遵循负载均 衡策略
          order: 1
          predicates:
            - Path=/product-serv/**
          filters:
            - StripPrefix=1
            - AddRequestHeader=msg,abc

我们将符合Path 规则的⼀切请求,都代理到 uri参数指定的地址。

3)重启测试

总结: ⽹关搭建步骤: 1.创建项⽬,引⼊nacos服务发现和gateway依赖 2.配置application.yml,包括服务基本信息、nacos地址、路由

路由配置包括:

1.路由id:路由的唯⼀标示 2.路由⽬标(uri):路由的⽬标地址,http代表固定地址,lb代表根据服务名负载均衡 3.路由断⾔(predicates):判断路由的规则, 4.路由过滤器(filters):对请求或响应做处理

1.3 断⾔⼯⼚

我们在配置⽂件中写的断⾔规则只是字符串,这些字符串会被Predicate Factory读取并处理,转 变为路由判断的条件 例如Path=/user/**是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理 的,像这样的断⾔⼯⼚在SpringCloudGateway还有⼗⼏个:

演示:

  • After=2037-01-20T17:42:47.789-07:00[America/Denver]

GatewayFilter是⽹关中提供的⼀种过滤器,可以对进⼊⽹关的请求和微服务返回的响应做处理:

1.4.1 路由过滤器的种类

Spring提供了31种不同的路由过滤器⼯⼚

1.4.2 请求头过滤器

下⾯我们以AddRequestHeader 为例来讲解。

只需要修改gateway服务的application.yml⽂件,添加路由过滤即可:

XML 复制代码
 server:
  port: 7000
 spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes:
        - id: product_route
          uri: lb://service-product
          order: 1
          predicates:
            - Path=/product-serv/**
		  filters: # 默认过滤器,会对所有的路由请求都⽣效
          - AddRequestHeader=msg,wake up! # 添加请求头
1.4.3 默认过滤器

如果要对所有的路由都⽣效,则可以将过滤器⼯⼚写到default下。格式如下:

XML 复制代码
server:
  port: 7000
 spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
      routes:
        - id: product_route
          uri: lb://service-product
          order: 1
          predicates:
            - Path=/product-serv/**
      default-filters: # 默认过滤器,会对所有的路由请求都⽣效
  		- AddRequestHeader=msg,wake up! # 添加请求头
1.4.4 全局过滤器

上⼀节学习的过滤器,⽹关提供了31种,但每⼀种过滤器的作⽤都是固定的。如果我们希望拦截请 求,做⾃⼰的业务逻辑则没办法实现。 全局过滤器作⽤ 全局过滤器的作⽤也是处理⼀切进⼊⽹关的请求和微服务响应,与GatewayFilter的作⽤⼀样。区 别在于GatewayFilter通过配置定义,处理逻辑是固定的;⽽GlobalFilter的逻辑需要⾃⼰写代码实 现。

定义⽅式是实现GlobalFilter接⼝

java 复制代码
 public interface GlobalFilter {
 /**
  *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下⼀个过滤器处理
  *@param exchange 请求上下⽂,⾥⾯可以获取Request、Response等信息
  * @param chain ⽤来把请求委托给下⼀个过滤器
  * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
  */
   Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain
);
}

在filter中编写⾃定义逻辑,可以实现下列功能:

  • 登录状态判断

  • 权限校验

  • 请求限流等

⾃定义全局过滤器

需求:定义全局过滤器,拦截请求,判断请求的参数是否满⾜下⾯条件:

  • 参数中是否有authorization,

  • authorization参数值是否为admin

如果同时满⾜则放⾏,否则拦截

实现:在gateway中定义⼀个过滤器:

java 复制代码
 @Order(-1)
 @Component
 public class AuthorizeFilter implements GlobalFilter {
    @Override
 	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
 		// 1.获取请求参数
		MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();   
		// 2.获取authorization参数
		String auth = params.getFirst("authorization");
		// 3.校验
		if ("admin".equals(auth)) {
 			// 放⾏
			return chain.filter(exchange);
		}
 		// 4.拦截
		// 4.1.禁⽌访问
 		exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
		// 4.2.结束处理
		return exchange.getResponse().setComplete();
	}
 }

 //发送请求测试
//http://localhost:7000/product-serv/product/6?authorization=admin
1.4.5 过滤器执⾏顺序

请求进⼊⽹关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter 请求路由后,会将当前路由过滤器和DefaultFilter、GlobalFilter,合并到⼀个过滤器链(集合) 中,排序后依次执⾏每个过滤器:

排序的规则是什么呢?

  • 每⼀个过滤器都必须指定⼀个int类型的order值,order值越⼩,优先级越⾼,执⾏顺序越靠前。

  • GlobalFilter通过实现Ordered接⼝,或者添加@Order注解来指定order值,由我们⾃⼰指定

  • 路由过滤器和defaultFilter的order由Spring指定,默认是按照声明顺序从1递增。

  • 当过滤器的order值⼀样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执⾏。

1.5 浏览器同源策略

1995年,同源政策由 Netscape 公司引⼊浏览器。⽬前,所有浏览器都实⾏这个政策。 最初,它的含义是指,A⽹⻚设置的 Cookie,B⽹⻚不能打开,除⾮这两个⽹⻚"同源"。所谓"同源"指的 是"三个相同"。

  • 协议相同

  • 域名相同

  • 端⼝相同

举例:

http://www.example.com/dir/page.html⽹址

  • 协议是http://

  • 域名是<www.example.com>

  • 端⼝是80(默认端⼝可以省略)

它的同源情况如下

同源⽬的

同源政策的⽬的,是为了保证⽤户信息的安全,防⽌恶意的⽹站窃取数据。 设想这样⼀种情况:A⽹站是⼀家银⾏,⽤户登录以后,⼜去浏览其他⽹站。如果其他⽹站可以读取A⽹ 站的 Cookie,会发⽣什么? 很显然,如果 Cookie 包含隐私(⽐如存款总额),这些信息就会泄漏。更可怕的是,Cookie 往往⽤来 保存⽤户的登录状态,如果⽤户没有退出登录,其他⽹站就可以冒充⽤户,为所欲为。因为浏览器同时 还规定,提交表单不受同源政策的限制。 由此可⻅,"同源政策"是必需的,否则 Cookie 可以共享,互联⽹就毫⽆安全可⾔了。

1.6 跨域问题解决⽅案

跨域:域名不⼀致就是跨域,主要包括:

跨域问题:浏览器禁⽌请求的发起者与服务端发⽣跨域ajax请求,请求被浏览器拦截的问题

CORS

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求 的根本解决⽅法。相⽐JSONP只能发GET请求,CORS允许任何类型的请求。

在gateway服务的application.yml⽂件中,添加下⾯的配置:

java 复制代码
spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理        
      	add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题        				corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些⽹站的跨域请求
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求⽅式              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息            
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期
相关推荐
用户83071968408219 小时前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解20 小时前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解20 小时前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记1 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者2 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840822 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解2 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端
初次攀爬者3 天前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺3 天前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart3 天前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot