springcloud(七):微服务网关GateWay

静态配置请求路由

1、依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>nacos-register</artifactId>
        <groupId>com.bear</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>nacos_gateway_server</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--将服务注册到nacos中-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>
</project>

yaml配置:

server:
  port: 8021
spring:
  application:
    name: api-gateway # 指定服务名
  cloud:
    gateway:
      routes:   # gateway动态路由,从nacos中动态获取服务
      - id: product-service    # 唯一性的id
        uri: lb://nacos-provide     # nacos上服务的名称,前面的lb是必须要的
        predicates:
        - Path=/provide/**           # 当端口后面有带'/provide参数的时候,则去nacos中获取上面的服务名,然后跳转到目标服务做请求
    nacos:
      discovery:  # 注册中心
        server-addr: 127.0.0.1:8850

注:uri : uri以 lb: //开头(lb代表从注册中心获取服务),后面接的就是你需要转发到的服务名称。
重要的是 predicates:
- Path=/provide/**
只要匹配上了,就会调转到其他服务,请求其他服务的时候,端口号后面会带上前缀provide

动态配置请求路由

去掉端口号后面的请求前缀
yaml配置:

server:
  port: 8021
spring:
  application:
    name: api-gateway # 指定服务名
  cloud:
    gateway:
      routes:   # gateway动态路由,从nacos中动态获取服务
      - id: product-service
        uri: lb://nacos-provide     # nacos上服务的名称,前面的lb是必须要的
        predicates:
        - Path=/product-service/**           # 当端口后面有带'/provide参数的时候,则去nacos中获取上面的服务名,然后跳转到目标服务做请求
        filters:
        - RewritePath=/product-service/(?<segment>.*), /$\{segment}   # #配置路由过滤器,将当前请求http://127.0.0.1:8021/product-service/provide/provideGet    --》   http://127.0.0.1:8095/provide/provideGet
    nacos:
      discovery:  # 注册中心
        server-addr: 127.0.0.1:8850

注:1、product-service为瞎写的名称,可以自定义
2、加上filters 下面的 - RewritePath,这样就可以在调转其他服务的时候,去掉前缀,而只加真正的请求url

过滤器

一、过滤器的生命周期

Spring Cloud Gateway 的 Filter 的生命周期不像 Zuul 的那么丰富,它只有两个:“pre” 和 “post”。
PRE: 这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择
请求的微服务、记录调试信息等。
POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP
Header、收集统计信息和指标、将响应从微服务发送给客户端等。

二、过滤器类型

Spring Cloud Gateway 的 Filter 从作用范围可分为另外两种GatewayFilter 与 GlobalFilter。
GatewayFilter:应用到单个路由或者一个分组的路由上。
GlobalFilter:应用到所有的路由上。

过滤器有:局部过滤器和全局过滤器。 过滤器类很多,可查找网上的

三、统一鉴权

统一鉴权在网关中做:

当客户端第一次请求服务时,服务端对用户进行信息认证(登录) 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证
以后每次请求,客户端都携带认证的token 服务端对token进行解密,判断是否有效。

看我的博客:springsecurity权限管理

https://editor.csdn.net/md/?articleId=121249463

四、网关限流

令牌桶算法

令牌桶算法是对漏桶算法的一种改进,桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用
的平均速率的同时还允许一定程度的突发调用。在令牌桶算法中,存在一个桶,用来存放固定数量的令
牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令
牌,才有机会继续执行,否则选择选择等待可用的令牌、或者直接拒绝。放令牌这个动作是持续不断的
进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这
时进来的请求就可以直接拿到令牌执行,比如设置qps为100,那么限流器初始化完成一秒后,桶中就
已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时
的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。

SpringCloudGateway官方就提供了基于令牌桶的限流支持。基于其内置的过滤器工厂
RequestRateLimiterGatewayFilterFactory 实现。在过滤器工厂中是通过Redis和lua脚本结合的方
式进行流量控制。

setinel做限流:

package com.bear.configuration;

import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayFlowRule;
import com.alibaba.csp.sentinel.adapter.gateway.common.rule.GatewayRuleManager;
import com.alibaba.csp.sentinel.adapter.gateway.sc.SentinelGatewayFilter;
import com.alibaba.csp.sentinel.adapter.gateway.sc.exception.SentinelGatewayBlockExceptionHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.result.view.ViewResolver;

import javax.annotation.PostConstruct;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author LiuShanshan
 * @version V1.0
 * @Description
 */
@Configuration
public class GatewayConfiguration {
    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfiguration(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    /*** 配置限流的异常处理器:SentinelGatewayBlockExceptionHandler */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {
        return new SentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    /*** 配置限流过滤器 */
    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }

    /*** 配置初始化的限流参数 */
    @PostConstruct
    public void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<GatewayFlowRule>();
        rules.add( new GatewayFlowRule("nacos-consumer-sentinel") //资源名称
                 .setCount(1) // 限流阈值
                 .setIntervalSec(1) // 统计时间窗口,单位是秒,默认是 1 秒
                 );
                GatewayRuleManager.loadRules(rules);
    }


}

yaml配置

server:
  port: 8021
spring:
  application:
    name: api-gateway # 指定服务名
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
  cloud:
    gateway:
      routes:   # 1、gateway动态路由,从nacos中动态获取服务
      - id: product-service
        uri: lb://nacos-provide     # nacos上服务的名称,前面的lb是必须要的
        predicates:
        - Path=/product-service/**           # 当端口后面有带'/provide参数的时候,则去nacos中获取上面的服务名,然后跳转到目标服务做请求
        filters:
        - RewritePath=/product-service/(?<segment>.*), /$\{segment}   # #配置路由过滤器,将当前请求http://127.0.0.1:8021/product-service/provide/provideGet    --》   http://127.0.0.1:8095/provide/provideGet
        # 2、下面配置的是限流过滤器,令牌木桶总容量为3,每1秒产生1个
#        - name:  RequestRateLimiter    # 配置 RequestRateLimiter的限流过滤器
#        args:
#          # 使用SpEL从容器中获取对象
#          key-resolver: '#{@pathKeyResolver}'
#          # 令牌桶每秒填充平均速率
#          redis-rate-limiter.replenishRate: 1
#          # 令牌桶的总容量
#          redis-rate-limiter.burstCapacity: 3
    nacos:
      discovery:  # 注册中心
        server-addr: 127.0.0.1:8850
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值