目录
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参数直接拒绝请求。