SpringCloud—— 微服务网关GateWay

目录

1、GateWay网关概述

1.1、什么是GateWay?

1.2、为什么要使用微服务网关?

1.3、Zuul与GateWay网关的区别?

2、快速入门

2.1、创建项目

2.2、配置yml文件

2.3、controller层

2.4、启动类

2.5、启动整体项目

2.6、配置全局过滤器


1、GateWay网关概述

1.1、什么是GateWay?

SpringCloud Gateway是Spring Cloud 的一个全新项目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。

SpringCloud Gateway 作为Spring Cloud 生态系统中的网关,目标是替代Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上 最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

1.2、为什么要使用微服务网关?

不管是之前学习的的Zuul网关,还是今天所学阿里推出的GateWay网关,学习它们的原因是为了什么呢?

微服务网关是整个微服务api接口的入口,可以实现过滤Api接口。

作用:就是可以实现用户的验证登陆、解决跨域、日志拦截、权限控制、限流熔断、负载均衡、黑名单和白名单机制等。 微服务中的架构模式采用前后分离,前端调用接口地址都能够被抓包分析到。

1.3、Zuul与GateWay网关的区别?

之前已经学习过Zuul网关了,为什么还要学习GateWay网关呢?

Zuul网关属于NetFix公司开源框架,属于第一代微服务网关

GateWay属于SpringCloud自己研发的网关框架,属于第二代微服务网关

相比来说GateWay 比Zuul网关的性能要好很多。

主要区别: Zuul网关底层基于Servlet实现,阻塞式api,不支持长连接,依赖SpringBoot-Web. SpringCloudGateWay基于Spring5构建,能够实现响应式非阻塞式api,支持长连接,能够更好的支持Spring体系产品,依赖SpringBoot-WebFux。

2、快速入门

2.1、创建项目

创建一个项目,名字随意

创建用户项目,用来查询用户

创建eureka模块

2.2、配置yml文件

gateway网关模块yml文件

server:
  port: 9857

spring:
  application:
    name: gateway-service

  cloud:
    gateway:
      discovery:
        locator:
          ##允许通过注册中心获取地址调用
          enabled: true
      #路由策略
      routes:
        #根据我们的服务名称查找地址实现调用
        - id: user-api
          uri: lb://user-service
          #匹配规则
          predicates:
            - Path=/user/**
#这里使用了eureka服务注册中心,如果想用其他的随意
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

用户模块的yml文件 

server:
  port: 8081
spring:
  application:
    name: user-service
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/ssm_crud?useSSL=false&useUnicode=true&characterEncoding=utf-8
    username: root
    password: 
mybatis:
  type-aliases-package: cn.itssl.pojo
  mapper-locations: classpath:mappers/*.xml
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka
  instance:
    # 更倾向使用ip地址,而不是host名
    prefer-ip-address: true
    # 续约间隔,默认30秒
    lease-renewal-interval-in-seconds: 5
    # 服务失效时间,默认90秒  服务失效时间是要比续约间隔时间大的
    lease-expiration-duration-in-seconds: 10

eureka模块yml文件

server:
  port: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka
    fetch-registry: false
    register-with-eureka: false
  server:
    enable-self-preservation: false  # 关闭自我保护机制 失效服务会被删除
    eviction-interval-timer-in-ms: 10000  # 剔除失效服务的时间间隔

2.3、controller层

在user-service模块,创建controller层,并实现相关业务

@RestController
@RequestMapping("/user")
public class UserController {
    @Value("${server.port}")
    private String port;
    @Autowired
    private UserService userService;

    @RequestMapping("/{id}")
    public User queryById(@PathVariable String id) {
        System.out.println("端口号为:"+port+"的user-service服务被调用了");
        //查询用户业务,自行完成
        return userService.getUserById(id);
    }
}

2.4、启动类

gateway-service模块启动类

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

eureka模块启动类 

@SpringBootApplication
@EnableEurekaServer  //开启服务端Eureka
public class EurekaServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class, args);
    }
}

用户模块启动类 

@SpringBootApplication
@MapperScan("cn.itssl.mapper")
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

2.5、启动整体项目

备注:userService2是user-service的一个复制模块,功能一模一样,只是yml文件中spring.name不同而已。形成了一个user集群

连续请求接口localhost:9857/user/2

可以看到请求成功,原本只能通过localhost:8081/user/2,现在在外面又加上一层屏障,把真实的业务请求地址隐藏了,防止了不法分子对真实业务地址进行攻击。

可以看到user集群两个都被访问了,达到了网关的负载均衡的功能。

2.6、配置全局过滤器

在gateway模块中创建一个filter包,创建MyLogGateWayFilter类,实现两个接口,分别是GlobalFiler全局过滤器,以及Ordered类。

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("进入了过滤器拦截");
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
            log.info("非法请求,进行拦截....");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        log.info("符合请求要求,放行!");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

 重新启动项目,必须在后面带有uname参数才能获取到数据,不带uname参数直接拒绝请求。

猜你喜欢

转载自blog.csdn.net/select_myname/article/details/128872549