SpringCloud从入门到精通(七)

Gateway


Gateway-概述

  • 网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
  • 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求。
  • 存在的问题
1. 客户端多次请求不同的微服务,增加客户端的复杂性
2. 认证复杂,每个服务都要进行认证
3.http 请求不同服务次数增加,性能不高
  • 网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能
  • 无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发
  • 在目前的网关解决方案里,有Nginx+ LuaNetflix Zuul Spring Cloud Gateway等等


Gateway-快速入门

1.创建 api-gateway-server 模块
2. 引入依赖: starter-gateway
<dependencies>
  <!--引入gateway 网关-->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
  </dependency>
  <!-- eureka-client -->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  </dependency>
</dependencies>
3. 编写启动类
@SpringBootApplication
@EnableEurekaClient
public class ApiGatewayApp {
  public static void main(String[] args) {
    SpringApplication.run(ApiGatewayApp.class,args);
  }
}
4. 编写配置文件
application.yml
server:
  port: 80

spring:
  application:
    name: api-gateway-server
cloud:
# 网关配置
  gateway:
    # 路由配置:转发规则
    routes: #集合。
    # id: 唯一标识。默认是一个UUID
    # uri: 转发路径
    # predicates: 条件,用于请求网关路径的匹配规则
    - id: gateway-provider
      uri: http://localhost:8001/
      predicates:
      - Path=/goods/**

5.测试发现我们不用直接访问8001的业务端口,而是通过访问80的gateway服务就可以实现请求分发

上面我们写的application.yml 中的 uri 是写死的,这属于静态路由

Gateway-实现动态路由

启动类添加 @EnableEurekaClient (新版本不加也可以)
@SpringBootApplication
@EnableEurekaClient
public class ApiGatewayApp {
  public static void main(String[] args) {
    SpringApplication.run(ApiGatewayApp.class,args);
  }
}
application.yml 中修改 uri 属性: uri: lb:// 服务名称
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/**

Gateway-微服务名称配置

application.yml 中配置微服务名称配置
想要实现动态路由的前提就是我们的微服务和gateway服务都已经被注册的注册中心去,微服务开启了客户端被发现的功能。
# 微服务名称配置
discovery:
  locator:
    enabled: true # 设置为true 请求路径前可以添加微服务名称
    lower-case-service-id: true # 允许为小写

Gateway-过滤器

过滤器 - 概述
Gateway 支持过滤器功能,对请求或响应进行拦截,完成一些通用操作。
Gateway 提供两种过滤器方式: “pre” “post”
        pre 过滤器:在转发之前执行,可以做参数校验、权限校验、流量监控、日志输出、协议转换等。
        post 过滤器:在响应之前执行,可以做响应内容、响应头的修改,日志的输出,流量监控等。
Gateway 还提供了两种类型过滤器
        GatewayFilter:局部过滤器,针对单个路由
        GlobalFilter :全局过滤器,针对所有路由

局部过滤器
GatewayFilter 局部过滤器,是针对单个路由的过滤器。 在Spring Cloud Gateway 组件中提供了大量内置的局部过滤器,对请求和响应做过滤操作。
遵循约定大于配置的思想,只需要在配置文件配置局部过滤器名称,并为其指定对应的值,就可以让其生效。
测试配置
api-gateway-server application.yml
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
gateway-provider 模块中 GoodsController 中的 findOne 添加 username 参数
public Goods findOne(@PathVariable("id") int id,String username){
  System.out.println(username);
  //如果id == 1 ,则出现异常,id != 1 则正常访问
  if(id == 1){
    //1.造个异常
    int i = 3/0;
  }
  /*try {
    //2. 休眠2秒
    Thread.sleep(2000);
  } catch (InterruptedException e) {
    e.printStackTrace();
  }*/
  Goods goods = goodsService.findOne(id);
  goods.setTitle(goods.getTitle() + ":" + port);//将端口号,设置到了 商品标题上
  return goods;
}
全局过滤器
GlobalFilter 全局过滤器,不需要在配置文件中配置,系统初始化时加载,并作用在每个路由上。 Spring Cloud Gateway 核心的功能也是通过内置的全局过滤器来完成。
自定义全局过滤器步骤:
1. 定义类实现 GlobalFilter Ordered 接口
2. 复写方法
3. 完成逻辑处理

代码实现

MyFilter
@Component
public class MyFilter implements GlobalFilter, Ordered {
  @Override
  public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChainchain) {
    System.out.println("自定义全局过滤器执行了~~~");
    return chain.filter(exchange);//放行
  }
  /**
  * 过滤器排序
  * @return 数值越小 越先执行
  */
  @Override
  public int getOrder() {
    return 0;
  }
}

通过feign调用spring cloud gateway代理的服务

 工程结构

api-gateway-server 80 端口
eureka-server-gateway 8761 端口
gateway-consumer 9000 端口
gateway-provider 8001 端口

配置 consumer 通过 gateway 调用 provider
修改feign接口上FeignClient注解的value值为api-gateway-server的应用名称
@FeignClient(value = "api-gateway-server",fallback =
GoodsFeignClientFallback.class)
public interface GoodsFeignClient {
  @GetMapping("/goods/findOne/{id}")
  public Goods findGoodsById(@PathVariable("id") int id);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值