赞
踩
引自百度百科
API网关,软件术语,两个相互独立的局域网之间通过路由器进行通信,中间的路由被称之为网关。
任何一个应用系统如果需要被其他系统调用,就需要暴露 API,这些 API 代表着一个一个的功能点。
如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关
API 网关是一个搭建在客户端和微服务之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。
API 网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。
对于服务数量众多、复杂度较高、规模比较大的系统来说,使用 API 网关具有以下好处:
常见的 API 网关实现方案主要有以下 5 种:
Spring Cloud Gateway 是 Spring Cloud 团队基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的高性能 API 网关组件。
Spring Cloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty
Spring Cloud GateWay 最主要的功能就是路由转发,而在定义转发规则时主要涉及了以下三个核心概念
1、Route(路由)
2、Predicate(断言)
3、Filter(过滤)
核心概念 | 描述 |
---|---|
Route(路由) | 网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成。 |
Predicate(断言) | 路由转发的判断条件,我们可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。 |
Filter(过滤器) | 过滤器,我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理。 |
注:其中 Route 和 Predicate 必须同时声明
1、客户端将请求发送到 Spring Cloud Gateway 上
2、Spring Cloud Gateway 通过 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送给 Gateway Web Handler。
3、Gateway Web Handler 通过指定的过滤器链(Filter Chain),将请求转发到实际的服务节点中,执行业务逻辑返回响应结果。
4、过滤器之间用虚线分开是因为过滤器可能会在转发请求之前(pre)或之后(post)执行业务逻辑。
5、过滤器(Filter)可以在请求被转发到服务端前,对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等。
6、过滤器可以在响应返回客户端之前,对响应进行拦截和再处理,例如修改响应内容或响应头、日志输出、流量监控等。
7、响应原路返回给客户端
1、新建一个springboot Module(springcloud-7-service-eureka-gateway)
2、添加 spring-cloud-starter-gateway;spring-cloud-starter-netflix-eureka-client等 依赖
注:
在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
spring-cloud-starter-gateway 使用的Netty服务器,而 spring-boot-starter-web 使用 的Tomcat服务器;Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
- <dependencies>
-
- <!--spring-cloud-starter-netflix-eureka-client-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
-
- <!-- Spring cloud gateway 网关依赖
- 特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
- Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
- -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
- </dependencies>
- <!--继承统一的父项目-->
- <parent>
- <groupId>com.company</groupId>
- <artifactId>springcloud-demo</artifactId>
- <version>1.0.0</version>
- </parent>
-
- <groupId>com.company</groupId>
- <artifactId>springcloud-7-service-eureka-gateway</artifactId>
- <version>1.0.0</version>
-
- <name>springcloud-7-service-eureka-gateway</name>
- <description>Demo project for Spring Boot</description>
-
- <properties>
- <java.version>1.8</java.version>
- </properties>
-
- <dependencies>
-
- <!--spring-cloud-starter-netflix-eureka-client-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
-
- <!-- Spring cloud gateway 网关依赖
- 特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
- Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
- -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-gateway</artifactId>
- </dependency>
- </dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
3、application.properties配置文件
server.port=81 #eureka注册中心首页的Application这一栏 spring.application.name=springcloud-7-service-eureka-gateway #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活” eureka.instance.lease-renewal-interval-in-seconds=2 #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出 eureka.instance.lease-expiration-duration-in-seconds=10 #告诉服务端,服务实例以IP作为链接,不是取机器名 eureka.instance.prefer-ip-address=false #注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gateway eureka.instance.instance-id=${spring.application.name}:${server.port} #注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka eureka.client.service-url.defaultZone=http://localhost:8761/eureka #网关路由配置 #开启网关,默认开启 spring.cloud.gateway.enabled=true #节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象) #路由 id,没有固定规则,但唯一 spring.cloud.gateway.routes[0].id=login-service-route #匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符 spring.cloud.gateway.routes[0].uri=http://localhost:9001 #以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上 #断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写 #也可以全局匹配,如 /service/** spring.cloud.gateway.routes[0].predicates[0]=Path=/doLogin #只能是 GET 请求时,才能访问 spring.cloud.gateway.routes[0].predicates[0]=Method=GET
application.yml写法
server: port: 81 #eureka注册中心首页的Application这一栏 spring: application: name: springcloud-7-service-eureka-gateway #网关路由配置 cloud: gateway: #开启网关,默认开启 enabled: true #节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象) routes: #路由 id,没有固定规则,但唯一 - id: login-service-route #匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符 uri: http://localhost:9001 #以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上 predicates: #断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写 #也可以全局匹配,如 /service/** - Path=/doLogin #只能是 GET,POST 请求时,才能访问 - Method=GET,POST eureka: instance: #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活” lease-renewal-interval-in-seconds: 2 #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出 lease-expiration-duration-in-seconds: 10 #告诉服务端,服务实例以IP作为链接,不是取机器名 prefer-ip-address: false #注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gateway instance-id: ${spring.application.name}:${server.port} #注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka client: service-url: defaultZone: http://localhost:8761/eureka
注:
(1)Gateway 网关建议 使用 yml 文件格式配置,以properties配置比较繁琐,一般公司项目也建议采取 yml格式
(2)不管 application.properties 还是 application.yml 写法,都要注意 断言 predicates 处的 Path=/doLogin 和 Method=GET,POST写法,不然报如下错误
- ***************************
- APPLICATION FAILED TO START
- ***************************
-
- Description:
-
- Binding to target [Bindable@4a6facb0 type = java.util.List<org.springframework.cloud.gateway.handler.predicate.PredicateDefinition>, value = 'provided', annotations = array<Annotation>[@javax.validation.constraints.NotEmpty(message={javax.validation.constraints.NotEmpty.message}, groups=[], payload=[]), @javax.validation.Valid()]] failed:
-
- Property: spring.cloud.gateway.routes[0].predicates[0].path
- Value: /doLogin
- Origin: class path resource [application.yml]:23:21
- Reason: The elements [spring.cloud.gateway.routes[0].predicates[0].path,spring.cloud.gateway.routes[0].predicates[1].method] were left unbound.
- Property: spring.cloud.gateway.routes[0].predicates[1].method
- Value: GET,POST
- Origin: class path resource [application.yml]:25:23
- Reason: The elements [spring.cloud.gateway.routes[0].predicates[0].path,spring.cloud.gateway.routes[0].predicates[1].method] were left unbound.
4、在 Spring Boot 的启动类中,添加 @EnableEurekaClient 注解开启 Eureka 客户端功能(Gateway网关也是eureka的客户端)
- @EnableEurekaClient //Gateway网关也是eureka的客户端
- @SpringBootApplication
- public class EurekaGateway7Application {
- public static void main(String[] args) {
- SpringApplication.run(EurekaGateway7Application.class, args);
- }
- }
5、创建一个服务提供者 springcloud-7-service-eureka-gateway-login
依赖
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <!--spring-cloud-starter-netflix-eureka-client-->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- </dependencies>
application.properties
- server.port=9001
-
- #设置应用名称,对应Eureka控制台下 DS Replicas 的 Application(集群部署服务提供者,Application一致,对应多个eureka.instance.instance-id)
- spring.application.name=springcloud-7-service-eureka-gateway-login
-
- #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
- eureka.instance.lease-renewal-interval-in-seconds=5
- #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
- eureka.instance.lease-expiration-duration-in-seconds=10
- #告诉服务端,服务实例以IP作为链接,不是取机器名
- eureka.instance.prefer-ip-address=false
-
- #注册服务实例ID,,服务ID必须唯一
- eureka.instance.instance-id=springcloud-7-service-eureka-gateway-login
- #注册中心的链接地址 http://localhost:8761/eureka
- eureka.client.service-url.defaultZone=http://localhost:8761/eureka
controller测试类
- @RestController
- public class LoginController {
- @GetMapping("/doLogin")
- public String doLogin(String name, String pwd) {
- System.out.println(name);
- System.out.println(pwd);
- // token
- String token = UUID.randomUUID().toString();
- return token;
- }
- }
6、分别启动本地 eureka,gateway,login-service ,输入访问 http://localhost:81/doLogin
注:
这里启动 Gateway网关模块,会明显的在控制台下方看到输出:
Netty started on port(s):81
服务者自己的端口 9001 访问 自然无问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。