微服务网关-Gateway
前言
近期做的项目,每次新增一个接口都需要提jira
工单在公司的网关平台上申请接口权限。
那么什么是网关?我们为什么要使用网关呢……一些列问题在我脑海里出现。
正文
网关的简介
网关是系统的唯一对外的入口,介于客户端和服务器端之间的中间层,处理非业务功能 提供路由请求、鉴权、监控、缓存、限流等功能。
微服务使用网关的意义
不同的微服务一般会有不同的网络地址,而客户端可能需要调用多个服务接口才能完成一个业务需求,若让客户端直接与各个微服务通信,会有以下问题:
- 客户端会多次请求不同微服务,增加了客户端复杂性
- 存在跨域请求,处理相对复杂
- 认证复杂,每个服务都需要独立认证
- 难以重构,多个服务可能将会合并成一个或拆分成多个
微服务网关介于服务端与客户端的中间层,所有外部服务请求都会先经过微服务网关客户只能跟微服务网关进行交互,无需调用特定微服务接口,使得开发得到简化
微服务使用的网关主要有两种Zuul
和Gateway
,这里简单做一下对比:
- 从性能方面比较,两种产品在流量小的场景下性能表现差不多;
- 并发高的场景下
Gateway
性能要好很多。从开发方面比较,Zuul1
编程模型简单,易于扩展; Gateway
编程模型稍难,代码阅读难度要比Zuul高不少,扩展也稍复杂一些。
某种意义上GateWay
被作为Zuul
的取代品。
所以这里我们注重来讲一下Spring Cloud Gateway
该项目提供了一个用于在Spring MVC之上构建API网关的库。Spring Cloud Gateway
旨在提供一种简单而有效的方法来路由到API,并为它们提供跨领域的关注点,例如:安全性,监视/指标和弹性。
Spring Cloud Gateway
可以实现以下功能:
- 建立在
Spring Framework 5
,Project Reactor
和Spring Boot 2.0
之上 - 能够匹配任何请求属性上的路由。谓词和过滤器特定于路由
Hystrix
断路器集成Spring Cloud DiscoveryClient
集成- 易于编写的谓词和过滤器
- 请求速率限制,即限流
- 路径改写
Spring Cloud Gateway 快速入门
Nacos搭建可参考我的博客:Nacos服务治理中心和配置中心
项目结构
spring-gateway-demo
- spring-gateway-route: 项目的网关模块
- spring-gatewat-user: 项目的用户测试模块
spring-gateway-route
注入依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
application.properties
server.port=9000
spring.application.name=spring-gateway-route
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#配置路由关系
#表明gateway开启服务注册和发现的功能,并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务。
spring.cloud.gateway.discovery.locator.enabled=true
#是将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了),比以/service-hi/的请求路径被路由转发到服务名为service-hi的服务上。
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
spring.cloud.gateway.routes[0].id=spring-gateway-user
spring.cloud.gateway.routes[0].uri=lb://spring-gateway-user
spring.cloud.gateway.routes[0].predicates[0]=Path=/user/**
spring-gatewat-user
注入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
</dependencies>
application.properties
server.port=8080
spring.application.name=spring-gateway-user
spring.main.allow-bean-definition-overriding=true
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
测试
分别启动两个项目,Nacos管理台中可见
测试接口
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping ("/hello")
public String hello(String input){
return "Hello World"+input;
}
}
访问测试接口
- gateway会将请求转发到指定的服务器上
- localhost:9000/user/hello?input=溪源的奇思妙想