OpenFeign和Gateway
OpenFeign和Gateway
- 一.OpenFeign介绍
- 二.快速上手
- 1.引入依赖
- 2.开启openfeign的功能
- 3.编写客户端
- 4.修改远程调用代码
- 5.测试
 
- 三.OpenFeign参数传递
- 1.传递单个参数
- 2.多个参数、传递对象和传递JSON字符串
- 3.最佳方式写代码
- 继承的方式
- 抽取的方式
 
 
- 四.部署OpenFeign
- 五.统一服务入口-Gateway
- 1.网关
- 2.常见网关实现
 
- 六.快速上手
- 七.Gateway
- 1.Predicate
- 2.Route Predicate Factories
- 3.Gateway Filter Factories(网关过滤器工厂)
- GatewayFilter
- GlobalFilter
- 过滤器执行顺序
- ⾃定义过滤器
 
 
- 八.部署Gateway
一.OpenFeign介绍
OpenFeign是⼀个声明式的Web Service 客户端。它让微服务之间的调⽤变得更简单,类似controller
 调⽤service,只需要创建一个接口,然后添加注解即可使⽤OpenFeign。
OpenFeign的前身:
 Feign 是 Netflix 公司开源的一个组件。
- 2013年6月:Netflix发布 Feign的第一个版本 1.0.0
- 2016年7月:Netflix发布Feign的最后一个版本 8.18.0
- 2016年:Netflix 将 Feign 捐献给社区
- 2016年7月:OpenFeign 的首个版本 9.0.0 发布,之后一直持续发布到现在.
可以简单理解为Netflix Feign 是OpenFeign的祖先。或者说OpenFeign 是Netflix Feign的升级版。OpenFeign 是Feign的一个更强大更灵活的实现。
Spring Cloud Feign
 Spring Cloud Feign 是 Spring 对 Feign 的封装,将 Feign 项目集成到 Spring Cloud生态系统中。
 受 Feign 更名影响,Spring Cloud Feign 也有两个 starter
- spring-cloud-starter-feign
- spring-cloud-starter-openfeign
 由于Feign的停更维护,对应的,我们使用的依赖是 spring-cloud-starter-openfeign
OpenFeign 官方文档
 Spring Cloud Feign官方文档
二.快速上手
1.引入依赖
在订单项目中引入openfeign的依赖:
		<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
2.开启openfeign的功能
给订单项目的启动类加上openfeign的注解:
3.编写客户端
在订单服务中写一个api,value代表微服务的名称,path代表Feign客户端的统一前缀
 
4.修改远程调用代码

5.测试

 
 
三.OpenFeign参数传递
1.传递单个参数
ProductController:
 
 ProductAPI:
 在Order项目中写一个FeignController:
 
2.多个参数、传递对象和传递JSON字符串
ProductController:
 
 ProductAPI:
 
 FeignController:
 
3.最佳方式写代码
继承的方式
创建一个公共的包来提取公共代码,创建包的方式和之前相同:

 再将ProductAPI里面写的代码复制到新的ProductAPI项目的包中的,写成接口的形式:
 
此时需要将ProductInfo引入到这个项目中,但是其他的几个微服务项目都有这个类于是,可以将这个代码复制到这个API项目中,其他的微服务项目直接删除原来的ProductInfo这个类,通过API项目打包的形式放入到起到微服务的POM文件中:
-  先进行install,把当前工程打成jar包,放在Maven的本地仓库 
  
-  打包好后对其进行引入后,就会有POM文件自动生成: 
  
  
-  实现接口: 
  
-  订单的微服务中ProductAPI继承接口: 
  
-  使用了ProductInfo和继承了或者实现了ProductInterface都要将ProductInfo的包重新引入,并对方法进行一些修改。 
抽取的方式
-  依旧是先建一个module,并在pom文件中引入对应的依赖:  
-  将Order微服务的ProductAPI接口放到product-api微服务项目中的api包中,删除Order原有的api接口:  
-  对product-api进行打包: 
  
-  启动服务端 
-  抽取调用方:  
-  进行测试即可 
四.部署OpenFeign
对两个服务进行打包,Maven打包默认是从远程仓库下载的,product-api 这个包在本地,有以下解决方案:
- 上传到Maven中央仓库(参考:如何发布Jar包到Maven中央仓库,比较麻烦)[不推荐]
- 搭建Maven私服,上传Jar包到私服 [企业推荐]
- 从本地读取Jar包 [个人学习阶段推荐]
 前两种方法比较复杂,咱们使用第三种方式
- 从product-api的打包成功后的结果里找到本地Maven路径写到Order微服务的POM文件中:
  
  
  
- 上传到云服务器上:
  
- 启动jar包:
  
五.统一服务入口-Gateway
1.网关
API网关(简称网关)也是⼀个服务,通常是后端服务的唯一入口。它的定义类似设计模式中的Facade模式(门面模式,也称外观模式)。它就类似整个微服务架构的门面,所有的外部客户端访问,都需要经过它来进行调度和过滤。

 网关核心功能:
 权限控制: 作为微服务的入口,对用户进行权限校验,如果校验失败则进行拦截
 动态路由: ⼀切请求先经过网关,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务
 负载均衡:当路由的目标服务有多个时,还需要做负载均衡
 限流: 请求流量过高时,按照网关中配置微服务能够接受的流量进行放行,避免服务压力过大
2.常见网关实现
业界常用的网关方式有很多,技术方案也较成熟,其中不乏很多开源产品,比如Nginx,Kong,Zuul,
 Spring Cloud Gateway等。下面介绍两种常见的网关方案。
Zuul
 Zuul 是 Netflix 公司开源的一个API网关组件,是Spring Cloud Netflix 子项目的核心组件之一,它可以
 和 Eureka、Ribbon、Hystrix 等组件配合使用
在Spring Cloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix提供的Zuul(此处指Zuu 1.X).
 然而Netflix在2018年宣布一部分组件进入维护状态,不再进行新特性的开发。这部分组件中就包含Zuul
Spring Cloud Gateway
 Spring Cloud Gateway 是Spring Cloud的⼀个全新的API网关项目,基于Spring + SpringBoot等技术
 开发,目的是为了替换掉Zuul。
旨在为微服务架构提供一种简单而有效的途径来转发请求,并为他们提供横切关注点,比如:安全性,监控/指标和弹性。
在性能方面,根据官方提供的测试报告,Spring Cloud Gateway的RPS(每秒请求数)是Zuul的1.6倍。测
 试报告参考
六.快速上手
- 创建项目和之前相同
- 引入网关的依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.example</groupId><artifactId>spring-cloud-gateway</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>gateway</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency></dependencies></project>
- 写启动类:
  
- 写配置信息:
server:port: 10030 # ⽹关端⼝
spring:application:name: gateway # 服务名称cloud:nacos:discovery:server-addr: 1.95.194.117:8848gateway:routes: # ⽹关路由配置- id: order-service #路由ID, ⾃定义, 唯⼀即可uri: lb://order-service #⽬标服务地址predicates: #路由条件- Path=/order/**,/feign/**- id: product-service #路由ID, ⾃定义, 唯⼀即可uri: lb://product-service #⽬标服务地址predicates: #路由条件- Path=/product/**- 测试
  
七.Gateway
1.Predicate
Predicate是Java 8提供的一个函数式编程接口,它接收一个参数并返回一个布尔值,用于条件过滤,请求参数的校验。
代码:
 直接通过实现接口后,调用方法来使用:
 
 
 直接是在创建对象的时候重写方法来使用:
 使用lambda表达式的使用:
Predicate 的其他方法
- isEqual(Object targetRef):比较两个对象是否相等,参数可以为Null
- and(Predicate other):短路与操作,返回一个组成Predicate
- or(Predicate other):短路或操作,返回一个组成Predicate
- test(T t):传入一个Predicate参数,用来做判断
- negate(): 返回表示此Predicate逻辑否定的Predicate
  
2.Route Predicate Factories
Route Predicate Factories (路由断言工厂,也称为路由谓词工厂,此处谓词表示一个函数),在Spring
 Cloud Gateway中,Predicate提供了路由规则的匹配机制。
我们在配置文件中写的断言规则只是字符串,这些字符串会被Route Predicate Factory读取并处理,转
 变为路由判断的条件。比如前面章节配置的 Path=/product/** ,就是通过Path属性来匹配URL前缀是 /product 的请求。
这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 来实现的。Spring Cloud Gateway默认提供了很多Route Predicate Factory,这些Predicate会分别匹配HTTP请求的不同属性,并且多个Predicate可以通过and逻辑进行组合。

 
 
 更多参考
3.Gateway Filter Factories(网关过滤器工厂)
Predicate决定了请求由哪⼀个路由处理,如果在请求处理前后需要加⼀些逻辑,这就是Filter(过滤器)的
 作用范围了。
Filter分为两种类型:Pre类型和Post类型。
 Pre类型过滤器:路由处理之前执行(请求转发到后端服务之前执行),在Pre 类型过滤器中可以做鉴权,限流等。
Post类型过滤器:请求执行⾏完成后,将结果返回给客户端之前执行。
 
 Spring Cloud Gateway 中内置了很多Filter,用于拦截和链式处理web请求。比如权限校验,访问超时等设定。
 Spring Cloud Gateway从作用范围上,把Filter可分为GatewayFilter 和GlobalFilter。
 GatewayFilter: 应用到单个路由或者一个分组的路由上。
 GlobalFilter: 应用到所有的路由上,也就是对所有的请求生效。
GatewayFilter
GatewayFilter 同 Predicate 类似,都是在配置文件 application.yml 中配置,每个过滤器的逻辑都是固定的。比如 AddRequestParameterGatewayFilterFactory 只需要在配置文件中写AddRequestParameter,就可以为所有的请求添加⼀个参数,我们先通过⼀个例子来演示GatewayFilter如何使用。
快速上手:
- 添加yml配置
  
- order微服务中添加过滤器参数: 
- 通过网管访问后,日志中打印出userName: 
GatewayFilter详细介绍官网
Default Filters
 前面的filter添加在指定路由下,所以只对当前路由生效,若需要对全部路由生效,可以使用spring.cloud.gateway.default-filters 这个属性需要⼀个filter的列表。
yml配置
spring:
cloud:
gateway:
default-filters:
- AddResponseHeader=X-Response-Default-Red, Default-Blue
- PrefixPath=/httpbin
GlobalFilter
lobalFilter是Spring Cloud Gateway中的全局过滤器,它和GatewayFilter的作用是相同的。
 GlobalFilter 会应用到所有的路由请求上,全局过滤器通常用于实现与安全性,性能监控和日志记录等相关的全局功能。
 Spring Cloud Gateway 内置的全局过滤器也有很多,比如:
- Gateway Metrics Filter:网关指标,提供监控指标
- Forward Routing Filter:用于本地forword,请求不转发到下游服务器。
- LoadBalancer Client Filter:针对下游服务,实现负载均衡。
 更多过滤器参考:Global Filters
演示:
- 添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
- 添加yml配置
spring:application:name: gateway # 服务名称cloud:nacos:discovery:server-addr: gateway:metrics:enabled: true
management:endpoints:web:exposure:include: "*"endpoint:health:show-details: alwaysshutdown:enabled: true
- 测试
  
过滤器执行顺序
一个项目中,既有GatewayFilter,又有 GlobalFilter时,执行的先后顺序是什么呢? 请求路由后,网关会把当前项目中的GatewayFilter和GlobalFilter合并到一个过滤器链(集合)中,并进行排序,依次执行过滤器。

 每一个过滤器都必须指定一个int类型的order值,默认值为0,表示该过滤的优先级。order值越小,优先级越高,执行顺序越靠前。
- Filter通过实现Order接口或者添加@Order注解来指定order值。
- Spring Cloud Gateway提供的Filter由Spring指定.用户也可以自定义Filter,由用户指定。
- 当过滤器的order值⼀样时,会按照 defaultFilter > GatewayFilter > GlobalFilter的顺序执行
⾃定义过滤器
Spring Cloud Gateway提供了过滤器的扩展功能,开发者可以根据实际业务来⾃定义过滤器,同样自定
 义过滤器也⽀持GatewayFilter 和 GlobalFilter两种.
自定义GatewayFilter
 自定义GatewayFilter,需要去实现对应的接口 GatewayFilterFactory,Spring Boot 默认帮我们实现的抽象类是 AbstractGatewayFilterFactory,我们可以直接使用。
定义GatewayFilter
- 写一个Custom的Config
  
- 自定义一个CustomGatewayFilterFactory类: 
- 增加一点yml的配置:
  
- 测试:
  
**自定义GlobalFilter **
 GlobalFilter的实现比较简单,它不需要额外的配置,只需要实现GlobalFilter接口,自动会过滤所有的
 Filter.
定义GlobalFilter:
八.部署Gateway
- 打包
  
- 把打好的jar包上传云服务器
- 再通过nohup命令启动jar包
