微服务中网关的作用
- 统一入口:为全部微服务提供一个唯一的入口,网关起到外部和内部隔离的作用,保障了后台服务的安全性
- 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求
- 动态路由:动态的将请求路由到不同的后端集群中
- 减少客户端与服务端的耦合:服务可以独立发展,通过网关层来做映射
gateway 与 zuul
gateway 是 springcloud 微服务平台的一个子项目,属于 spring 开源社区,依赖名叫:spring-cloud-starter-gateway 。官网:https://spring.io/projects/spring-cloud-gatewayzuul 是 netflix 公司的开源项目,springcloud 在 netflix 项目中也已经集成了 zuul ,依赖名叫:spring-cloud-starter-netflix-zuul 。官网:https://github.com/Netflix/zuulspringcloud gateway 基于 spring 5、projec treactor、springboot 2 ,使用非阻塞式的 API ,内置限流过滤器,支持长连接(比如 websockets ),在高并发和后端服务响应慢的场景下比 zuul 1 的表现要好zuul 基于 servlet2.x 构建,使用阻塞的 API ,没有内置限流过滤器,不支持长连接
springcloud gateway 简介
springcloud gateway 是 springcloud 的一个全新项目,该项目是基于 spring 5.0,springboot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式springcloud gateway 作为 springcloud 生态系统中的网关,目标是替代 netflix zuul ,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流
相关概念
Route (路由):这是网关的基本构建块。它由一个 ID ,一个目标 URI ,一组断言和一组过滤器定义。如果断言为真,则路由匹配Predicate (断言):这是一个 Java 8 的 Predicate 。输入类型是一个 ServerWebExchange 。我们可以使用它来匹配来自 Http 请求的任何内容,例如 headers 或参数Filter (过滤器):这是 org.springframework.cloud.gateway.filter.GatewayFilter 的实例,我们可以使用它修改请求和响应
工作流程
客户端向 SpringCloud Gateway 发出请求。如果 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler 。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。 过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre )或之后(post )执行业务逻辑
特征
- 基于
Spring 5,Project Reactor 和 SpringBoot 2.0 - 动态路由
Predicates 和 Filters 作用于特定路由- 集成
Hystrix - 集成
SpringCloud 注册中心 - 易于编写的
Predicates 和 Filters - 限流
- 路径重写
快速上手
继续依赖 上一篇 文章的项目结构,再新建服务网关项目如下
Maven 依赖
eureka-client-gateway 服务网关添加依赖如下
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
application.properties 配置文件
eureka-client-gateway 服务网关的配置文件
server.port=9000
spring.application.name=eureka-client-gateway
spring.cloud.gateway.routes[0].id=eureka-client-gateway
spring.cloud.gateway.routes[0].uri=http://localhost:8080
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
id :我们自定义的路由 ID ,保持唯一uri :目标,要路由的服务地址。在这里路由的是 eureka-client-producer 提供方地址predicates :路由条件,Predicate 接受一个输入参数,返回一个布尔值结果filters :过滤规则,本示例暂时没用/user/** :以 user 开头的接口 url ,后面 * 是通配符
上面这段配置的意思是:配置了一个 id 为 eureka-client-gateway 的路由规则,当访问地址 http://localhost:9000/user/** 时会自动转发路由到地址 http://localhost:8080/user/**
启动类
eureka-client-gateway 服务网关的启动类
@Slf4j
@SpringBootApplication
public class AppGateway {
public static void main(String[] args) {
SpringApplication.run(AppGateway.class, args);
log.info("------AppGateway Running------");
}
}
eureka-client-producer 的 controller
它的端口是 8080
@Slf4j
@Controller
@RequestMapping(path = "/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(path = "/selectUserById")
@ResponseBody
public ResultVo selectUserById(Integer id) {
return userService.selectOne(id);
}
}
测试
分别启动项目 eureka-client-gateway ,eureka-client-producer (不需要启动 eureka 服务端以及 config 服务端),访问接口 http://localhost:9000/user/selectUserById?id=1 ,如下
说明 gateway 服务网关已经路由成功。在看看接口 http://localhost:8080/user/selectUserById?id=1 ,也就是被路由转发的原服务地址的返回结果如下
gateway 网关路由的配置方式
- 在配置文件
properties 或 yml 中配置(如上) - 通过
@Bean 自定义 RouteLocator ,在启动主类 Application 中配置(如下)
@SpringBootApplication
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("path_route", r -> r.path("/about")
.uri("http://ityouknow.com"))
.build();
}
}
|