android系统定制开发SpringCloud - Spring Cloud 之 Gateway网关(十三)

android系统定制开发阅读本文前可先参考

一、网关

android系统定制开发引自百度百科

API,软件术语,android系统定制开发两个相互独立的局域网android系统定制开发之间通过路由器进行通信,android系统定制开发中间的路由被称之为。

android系统定制开发任何一个应用系统如果android系统定制开发需要被其他系统调用,android系统定制开发就需要暴露 ,这些 API 代表着一个一个的功能点。

如果两个系统中间通信,在系统之间加上一个中介者协助 API 的调用,这个中介者就是 API 网关

API 网关是一个搭建在客户端和之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等。

API 网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例。

对于服务数量众多、复杂度较高、规模比较大的系统来说,使用 API 网关具有以下好处:

  • 客户端通过 API 网关与微服务交互时,客户端只需要知道 API 网关地址即可,而不需要维护大量的服务地址,简化了客户端的开发。
  • 客户端直接与 API 网关通信,能够减少客户端与各个服务的交互次数。
  • 客户端与后端的服务耦合度降低。
  • 节省流量,提高性能,提升用户体验。
  • API 网关还提供了安全、流控、过滤、缓存、计费以及监控等 API 管理功能。

常见的 API 网关实现方案主要有以下 5 种:

  • Spring Cloud Gateway
  • Spring Cloud Netflix Zuul
  • Kong
  • Nginx+Lua
  • Traefik

二、Gateway

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 必须同时声明

Spring Cloud Gateway 工作流程

 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、响应原路返回给客户端

三、Gateway应用

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服务器方式不同

  1. <dependencies>
  2. <!--spring-cloud-starter-netflix-eureka-client-->
  3. <dependency>
  4. <groupId>org.springframework.cloud</groupId>
  5. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  6. </dependency>
  7. <!-- Spring cloud gateway 网关依赖
  8. 特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
  9. Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
  10. -->
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <artifactId>spring-cloud-starter-gateway</artifactId>
  14. </dependency>
  15. </dependencies>
  1. <!--继承统一的父项目-->
  2. <parent>
  3. <groupId>com.company</groupId>
  4. <artifactId>springcloud-demo</artifactId>
  5. <version>1.0.0</version>
  6. </parent>
  7. <groupId>com.company</groupId>
  8. <artifactId>springcloud-7-service-eureka-gateway</artifactId>
  9. <version>1.0.0</version>
  10. <name>springcloud-7-service-eureka-gateway</name>
  11. <description>Demo project for Spring Boot</description>
  12. <properties>
  13. <java.version>1.8</java.version>
  14. </properties>
  15. <dependencies>
  16. <!--spring-cloud-starter-netflix-eureka-client-->
  17. <dependency>
  18. <groupId>org.springframework.cloud</groupId>
  19. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  20. </dependency>
  21. <!-- Spring cloud gateway 网关依赖
  22. 特别注意:在 gateway 网关服务中不能引入 spring-boot-starter-web 的依赖,否则会报错
  23. Spring Cloud Gateway使用是基于WebFlux和Netty开发的,和传统的Tomcat服务器方式不同
  24. -->
  25. <dependency>
  26. <groupId>org.springframework.cloud</groupId>
  27. <artifactId>spring-cloud-starter-gateway</artifactId>
  28. </dependency>
  29. </dependencies>
  30. <build>
  31. <plugins>
  32. <plugin>
  33. <groupId>org.springframework.boot</groupId>
  34. <artifactId>spring-boot-maven-plugin</artifactId>
  35. </plugin>
  36. </plugins>
  37. </build>

3、application.properties配置文件

  1. server.port=81
  2. #eureka注册中心首页的Application这一栏
  3. spring.application.name=springcloud-7-service-eureka-gateway
  4. #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
  5. eureka.instance.lease-renewal-interval-in-seconds=2
  6. #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
  7. eureka.instance.lease-expiration-duration-in-seconds=10
  8. #告诉服务端,服务实例以IP作为链接,不是取机器名
  9. eureka.instance.prefer-ip-address=false
  10. #注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gateway
  11. eureka.instance.instance-id=${spring.application.name}:${server.port}
  12. #注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
  13. eureka.client.service-url.defaultZone=http://localhost:8761/eureka
  14. #网关路由配置
  15. #开启网关,默认开启
  16. spring.cloud.gateway.enabled=true
  17. #节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象)
  18. #路由 id,没有固定规则,但唯一
  19. spring.cloud.gateway.routes[0].id=login-service-route
  20. #匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符
  21. spring.cloud.gateway.routes[0].uri=http://localhost:9001
  22. #以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上
  23. #断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写
  24. #也可以全局匹配,如 /service/**
  25. spring.cloud.gateway.routes[0].predicates[0]=Path=/doLogin
  26. #只能是 GET 请求时,才能访问
  27. spring.cloud.gateway.routes[0].predicates[0]=Method=GET

application.yml写法

  1. server:
  2. port: 81
  3. #eureka注册中心首页的Application这一栏
  4. spring:
  5. application:
  6. name: springcloud-7-service-eureka-gateway
  7. #网关路由配置
  8. cloud:
  9. gateway:
  10. #开启网关,默认开启
  11. enabled: true
  12. #节点 routes 是一个List 对象,其中 routes 集合中中又包含多个对象,每个对象有三个属性(一个 索引[0]代表一个对象)
  13. routes:
  14. #路由 id,没有固定规则,但唯一
  15. - id: login-service-route
  16. #匹配后提供服务的路由地址;uri统一资源定位符 url 统一资源标识符
  17. uri: http://localhost:9001
  18. #以下是断言条件,必选全部符合条件;断言是给某一个路由来设定的一种匹配规则 默认不能作用在动态路由上
  19. predicates:
  20. #断言,路径匹配,只要Path匹配上了/doLogin 就往 uri 转发 并且将路径带上 注意:Path 中 P 为大写
  21. #也可以全局匹配,如 /service/**
  22. - Path=/doLogin
  23. #只能是 GET,POST 请求时,才能访问
  24. - Method=GET,POST
  25. eureka:
  26. instance:
  27. #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
  28. lease-renewal-interval-in-seconds: 2
  29. #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
  30. lease-expiration-duration-in-seconds: 10
  31. #告诉服务端,服务实例以IP作为链接,不是取机器名
  32. prefer-ip-address: false
  33. #注册服务实例ID,,服务ID必须唯一 springcloud-7-service-eureka-gateway
  34. instance-id: ${spring.application.name}:${server.port}
  35. #注册中心的链接地址 http://eureka8761:8761/eureka,http://eureka8762:8762/eureka,http://eureka8763:8763/eureka
  36. client:
  37. service-url:
  38. defaultZone: http://localhost:8761/eureka

注:

(1)Gateway 网关建议 使用 yml 文件格式配置,以properties配置比较繁琐,一般公司项目也建议采取 yml格式

(2)不管 application.properties 还是 application.yml 写法,都要注意 断言 predicates 处的 Path=/doLogin 和  Method=GET,POST写法,不然报如下错误

  1. ***************************
  2. APPLICATION FAILED TO START
  3. ***************************
  4. Description:
  5. 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:
  6. Property: spring.cloud.gateway.routes[0].predicates[0].path
  7. Value: /doLogin
  8. Origin: class path resource [application.yml]:23:21
  9. Reason: The elements [spring.cloud.gateway.routes[0].predicates[0].path,spring.cloud.gateway.routes[0].predicates[1].method] were left unbound.
  10. Property: spring.cloud.gateway.routes[0].predicates[1].method
  11. Value: GET,POST
  12. Origin: class path resource [application.yml]:25:23
  13. 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的客户端)

  1. @EnableEurekaClient //Gateway网关也是eureka的客户端
  2. @SpringBootApplication
  3. public class EurekaGateway7Application {
  4. public static void main(String[] args) {
  5. SpringApplication.run(EurekaGateway7Application.class, args);
  6. }
  7. }

5、创建一个服务提供者  springcloud-7-service-eureka-gateway-login

依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. </dependency>
  6. <!--spring-cloud-starter-netflix-eureka-client-->
  7. <dependency>
  8. <groupId>org.springframework.cloud</groupId>
  9. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  10. </dependency>
  11. </dependencies>

application.properties

  1. server.port=9001
  2. #设置应用名称,对应Eureka控制台下 DS Replicas 的 Application(集群部署服务提供者,Application一致,对应多个eureka.instance.instance-id)
  3. spring.application.name=springcloud-7-service-eureka-gateway-login
  4. #每间隔5s,向Eureka服务注册中心发送一次心跳,证明服务是否依然“存活”
  5. eureka.instance.lease-renewal-interval-in-seconds=5
  6. #告诉服务端,如果10s之内没有发送心跳,就代表故障,将本服务踢出
  7. eureka.instance.lease-expiration-duration-in-seconds=10
  8. #告诉服务端,服务实例以IP作为链接,不是取机器名
  9. eureka.instance.prefer-ip-address=false
  10. #注册服务实例ID,,服务ID必须唯一
  11. eureka.instance.instance-id=springcloud-7-service-eureka-gateway-login
  12. #注册中心的链接地址 http://localhost:8761/eureka
  13. eureka.client.service-url.defaultZone=http://localhost:8761/eureka

 controller测试类

  1. @RestController
  2. public class LoginController {
  3. @GetMapping("/doLogin")
  4. public String doLogin(String name, String pwd) {
  5. System.out.println(name);
  6. System.out.println(pwd);
  7. // token
  8. String token = UUID.randomUUID().toString();
  9. return token;
  10. }
  11. }

6、分别启动本地 eureka,gateway,login-service ,输入访问 

注:

这里启动 Gateway网关模块,会明显的在控制台下方看到输出:

 Netty started on port(s):81

服务者自己的端口 9001 访问 自然无问题 

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发