JAVAEE细细看 框架32 - SpringCloud 微服务(八) 网关 - Gateway

Gateway-概述
在这里插入图片描述

Spring Cloud Gateway是Spring官网基于Spring 5.0、 Spring Boot 2.0、Project Reactor等技术开发的网关服
务。
Spring Cloud Gateway基于Filter链提供网关基本功能:安全、监控/埋点、限流等。
Spring Cloud Gateway为微服务架构提供简单、有效且统一的API路由管理方式。
Spring Cloud Gateway是替代Netflix Zuul的一套解决方案。

Spring Cloud Gateway组件的核心是一系列的过滤器,通过这些过滤器可以将客户端发送的请求转发(路由)到对应的微服务。
Spring Cloud Gateway是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,从而加强安全保护。
Spring Cloud Gateway本身也是一个微服务需要注册到Eureka服务注册中心。

网关的核心功能是:过滤和路由

1. Gateway-快速入门

在这里插入图片描述

  1. 搭建网关模块 api-gateway-server

  2. 引入依赖:starter-gateway

    <!--引入gateway 网关-->
    <dependency>
    	<groupId>org.springframework.cloud</groupId>
    	<artifactId>spring-cloud-starter-gateway</artifactId>
    </dependency>
    
  3. 编写启动类

    package com.ittest.gateway;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    
    @SpringBootApplication
    @EnableEurekaClient
    public class ApiGatewayApp {
        public static void main(String[] args) {
            SpringApplication.run(ApiGatewayApp.class,args);
        }
    }
    
  4. 编写配置文件

    server:
      port: 80
    spring:
      application:
        name: api-gateway-server
      cloud:
        # 网关配置
        gateway:
          # 路由配置:转发规则
          routes: #集合。
          # id: 唯一标识。默认是一个UUID
          # uri: 转发路径
          # predicates: 条件,用于请求网关路径的匹配规则
          # filters:配置局部过滤器的
          - id: gateway-provider
            # 静态路由
            uri: http://localhost:8001/
            # 动态路由
            # uri: lb://GATEWAY-PROVIDER
            predicates:
            - Path=/goods/**
            filters:
            - AddRequestParameter=username,zhangsan
          - id: gateway-consumer
            uri: http://localhost:9000
            # uri: lb://GATEWAY-CONSUMER
            predicates:
            - Path=/order/**
            # 微服务名称配置
          discovery:
            locator:
              enabled: true # 设置为true 请求路径前可以添加微服务名称
              lower-case-service-id: true # 允许为小写
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:8761/eureka
    
  5. 启动测试

    启动访问 http://localhost/goods/findOne/2

2.Gateway-静态路由

静态路由

# 静态路由
        uri: http://localhost:8001/
server:
  port: 80
spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # 静态路由
        uri: http://localhost:8001/
        # 动态路由
        # uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**
        filters:
        - AddRequestParameter=username,zhangsan

      - id: gateway-consumer
        uri: http://localhost:9000
        # uri: lb://GATEWAY-CONSUMER
        predicates:
        - Path=/order/**
        # 微服务名称配置
      discovery:
        locator:
          enabled: true # 设置为true 请求路径前可以添加微服务名称
          lower-case-service-id: true # 允许为小写
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
3. Gateway-动态路由

GATEWAY-PROVIDER 是eureka中的服务名

# 动态路由
        uri: lb://GATEWAY-PROVIDER
4. Gateway-微服务名称配置

微服务一旦多了,可以配置微服务名称以示区分

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      //中间配置省略...
      
      # 微服务名称配置    此配置是数据spring.cloud.gateway下的
      discovery:
        locator:
          enabled: true # 设置为true 请求路径前可以添加微服务名称
          lower-case-service-id: true # 允许为小写

访问 http://localhost/gateway-provider/goods/findOne/2 测试

扩展

此处也可以采用 去除前缀来实现该效果

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # 静态路由
        # uri: http://localhost:8001/
        # 动态路由
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/gateway-pro/goods/**
        filters:
        - AddRequestParameter=username,zhangsan
        - StripPrefix=1
5. Gateway-过滤器-概述

在这里插入图片描述

6. Gateway-过滤器-局部过滤器

局部过滤器,是针对单个路由的过滤器

spring cloud 内置了大量局部过滤器

遵循约定大于配置思想,只要在配置文件简单配置,就可以生效

spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # 静态路由
        # uri: http://localhost:8001/
        # 动态路由
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**
        # - Path=/gateway-pro/goods/**
        filters:
        - AddRequestParameter=username,zhangsan
        
        

扩展

1、AddRequestHeader 用法

spring:
  application:
    name: api-gateway-server
  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
		filters:
        - AddRequestParameter=username,zhangsan
        - AddRequestHeader=myheader, myheadervalue

在gateway-provider的GoodsController findOne方法和降级方法参数上加HttpServletRequest

public Goods findOne(@PathVariable("id") int id, String username, HttpServletRequest request){
    System.out.println("-"+username);
	System.out.println("---"+request.getHeader("myheader"));
、、、
}

public Goods findOne_fallback(int id,String username, HttpServletRequest request){
、、、
}

2、自定义局部过滤器

需求:在网关中针对gateway-provider服务的请求 校验请求中有没有token参数

①新建局部过滤器类MyAuthorizeGatewayFilterFactory

package com.ittest.gateway.filter;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

@Component
public class MyAuthorizeGatewayFilterFactory extends AbstractGatewayFilterFactory<MyAuthorizeGatewayFilterFactory.Config> {

    private static final Log logger = LogFactory.getLog(MyAuthorizeGatewayFilterFactory.class);
    private static final String AUTHORIZE_TOKEN = "token";

    public MyAuthorizeGatewayFilterFactory() {
        super(Config.class);
        logger.info("......load MyAuthorizeGatewayFilterFactory....");
    }

    @Override //这个值决定了Config中配置的属性,配置的参数都会被封装到该属性当中
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("enabled");
    }

    @Override
    public GatewayFilter apply(MyAuthorizeGatewayFilterFactory.Config config) {
        logger.info("......进入了 MyAuthorizeGatewayFilterFactory....");
        return (exchange, chain) -> {
            logger.info("......配置文件中的配置...."+ config.isEnabled());

            if (!config.isEnabled()) {
                logger.info("......由于配置文件中没有开启 不校验token 继续往下走....");
                return chain.filter(exchange);
            }
            ServerHttpRequest request = exchange.getRequest();
            HttpHeaders headers = request.getHeaders();
            String token = headers.getFirst(AUTHORIZE_TOKEN);
            if (token == null) {
                token = request.getQueryParams().getFirst(AUTHORIZE_TOKEN);
            }
            ServerHttpResponse response = exchange.getResponse();
            if (StringUtils.isEmpty(token)) {
                System.out.println("Authorize过滤器   url中     token值为空,请登录");
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                return response.setComplete();
            }
            System.out.println("Authorize过滤器   url中       携带了token,此次请求放行,token是"+token);
            return chain.filter(exchange);
        };
    }

    public static class Config {
        // 控制是否开启认证
        private boolean enabled;

        public Config() {}

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }
    }
}

②在网关的gateway-provider路由配置中指定 该过滤器

  • MyAuthorize=true
spring:
  application:
    name: api-gateway-server

  cloud:
    # 网关配置
    gateway:
      # 路由配置:转发规则
      routes: #集合。
      # id: 唯一标识。默认是一个UUID
      # uri: 转发路径
      # predicates: 条件,用于请求网关路径的匹配规则
      # filters:配置局部过滤器的

      - id: gateway-provider
        # 静态路由
        # uri: http://localhost:8001/
        # 动态路由
        uri: lb://GATEWAY-PROVIDER
        predicates:
        - Path=/goods/**
        # - Path=/gateway-pro/goods/**    # 配和StripPrefix使用
        filters:
        - AddRequestParameter=username,zhangsan
        - AddRequestHeader=myheader, myheadervalue
        - MyAuthorize=true

③使用postman测试

携带token 请求头,值任意写 访问 localhost:80/goods/findOne/2

##19-Gateway-过滤器-全局过滤器 6:9

在这里插入图片描述

扩展

1、使用全局过滤器校验请求头 有没有token

2、使用全局过滤器统计时长

3、zuul的使用

①导入zuul依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>

②配置

server:
  port: 81
spring:
  application:
    name: api-zuul-server

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka

zuul:
  routes:
    api-provider: #路由名称,名称任意,保持所有路由名称唯一
      path: /goods/**
      service-id: GATEWAY-PROVIDER #指定服务id,从Eureka中找到服务的ip和端口
      #url: http://localhost:8001/ #也可指定url
      #strip‐prefix: true #true:代理转发时去掉前缀,false:代理转发时不去掉前缀
    api-consumer:
      path: /order/**
      #service-id: service-order #服务id
      url: http://localhost:8002/ #也可指定url

③引导类加@EnableZuulProxy注解

package com.ittest.zuul;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class, args);
    }
}

④访问 http://localhost:81/api-goods/goods/findOne/2 测试 默认会去掉api-goods前缀

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值