1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > SpringCloud微服务架构之 Hystrix 熔断器 Gateway 网关

SpringCloud微服务架构之 Hystrix 熔断器 Gateway 网关

时间:2023-08-11 18:53:48

相关推荐

SpringCloud微服务架构之 Hystrix 熔断器 Gateway 网关

Hystrix 概述

Hystix 是 Netflix 开源的一个延迟和容错库,用于隔离访问远程服务、第三方库,防止出现级联失败(雪崩)。

pom依耐

<!-- hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency>

• 雪崩:一个服务失败,导致整条链路的服务都失败的情形。

• Hystix 主要功能

隔离:用于隔离不同调用链之间相互不受影响降级:封装友好的错误提示并返回熔断:当请求错误率较高时,自动降级熔断限流:合理分配每个调用的并发请求数量

隔离

1. 线程池隔离

将多个请求线程按照每个服务的配置,分发到不同的微服务去调用,这样就解决的,线程一窝蜂的同一微服务中,影响的雪崩

2. 信号量隔离

降级

异常,超时

在A调用C的时候,C服务发生了异常,或者执行时间过长,为了避免请求回不友好的错误信息或者线程不一直等待,我们提供一个友好的方法,该方法往往返回一个失败请求的响应结果集,如:服务器繁忙等等,使得请求响应能够快速获得,而且异常后是友好的提示,超时后能快速的返回响应,不占用线程.防止服务雪崩.

这个降级不但可以在服务提供方编写一个降级方法,也可以在服务消费方编写.

熔断

使用服务熔断,首先要导入pom依耐

然后在主启动开启熔断:@EnableCircuitBreaker//开启hystrix的断路器

在服务业务类上书写:

注意的是:不编写那些超时,请求次数,hystrix都会有默认的值,都默认支持熔断

//======服务熔断,providerCircuitBreakerMethod异常或者超时调用的方法@HystrixCommand(fallbackMethod = "providerCircuitBreakerMethod",commandProperties = {@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//是否开启断路器//sleepWindowInMilliseconds请求量阈值 默认失败次数20次@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数//监控时间,默认5000毫秒 就是打开状态与半开状态之间的休眠时间@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"),//时间窗口日期//误差阈值百分比errorThresholdPercentage 失败率默认百分之50@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),//失败率60%达到多少跳闸(进行服务熔断)})public Result providerCircuitBreaker(@PathVariable("id") Integer id){//制作异常,然后调用这个方法就会去调用配置的降级方法if (id==0){//id==0.就异常int i = 1/0;}return new Result(true,"providerCircuitBreaker调用成功");}//熔断友好提示方法@Overridepublic Result providerCircuitBreakerMethod(Integer id){return new Result(false,"服务器繁忙,请稍候再试~~~熔断方法");}

限流

服务限流:(flowLimit)

就好比秒杀商品等高并发操作,禁止一窝蜂的请求过来拥挤,大家排队,一秒钟处理N个,有序的进行

测试Hystrix的代码

搭建一个父工程

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>study-springcloud</artifactId><version>1.0-SNAPSHOT</version><modules><module>fs-server-eureka-7001</module><module>fs-provider-hystrix-8001</module><module>fs-consumer-hystrix-80</module></modules><!-- 作为父工程--><packaging>pom</packaging><dependencyManagement><dependencies><!--spring boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.2.RELEASE</version><type>pom</type><!-- import 导入父工程的配置--><scope>import</scope></dependency><!--spring cloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR6</version><type>pom</type><!-- import 导入父工程的配置--><scope>import</scope></dependency><!-- spring-cloud-alibaba-dependencies 2.2.1.RELEASE --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.1.RELEASE</version><type>pom</type><scope>import</scope></dependency><!-- eureka-server --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.2.4.RELEASE</version></dependency><!-- eureka-client --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.4.RELEASE</version></dependency><!-- 整合MyBatis--><!-- mysql --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.20</version></dependency><!--MyBatisPlus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency><!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies></dependencyManagement><dependencies></dependencies></project>

fs-server-eureka-7001(省略,请查阅上一偏博客,服务治理)

fs-provider-hystrix-8001 服务提供者

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-provider-hystrix-8001</artifactId><dependencies><!-- hystrix--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId></dependency><!--spring-boot-starter-web spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!--第一种是:如果你的应用不会再需要返回xml的系列化格式,那么直接在pom.xml文件中将jackson-dataformat-xml这外包排除即可(如果其他包也进行了jackson-dataformat-xml的依赖引用也要视情况排除):第二种是:不排除jackson-dataformat-xml包,而是直接在相应接口方法或Controller上明确指定将返回JSON格式的值:@GetMapping(value = "/user-instance", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)--><!-- 排除controller返回的格式为xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!-- mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!-- MyBatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!-- 自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 8001spring:application:name: fs-provider-hystrixdatasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/fs_springclouddriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定义数据源# 配置eurekaeureka:instance:hostname: localhost # 主机名,写的是域名,本机在host文件中映射prefer-ip-address: true # 将当前实例的ip注册到eureka server中.默认是false 注册主机名ip-address: 127.0.0.1 # 修改instance-id显示# # 修改instance-id显示,在eureka中的显示名称# instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port}# lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔# lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务client:register-with-eureka: true # 将提供注册到注册eureka中心fetch-registry: true # 从eureka上抓取已有的注册信息service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注册中心地址# 配置MyBatis-plus日志mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

FsProviderHystrix8001 主启动

注意:@EnableCircuitBreaker//开启hystrix的断路器

package com.fs;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;import org.flix.eureka.EnableEurekaClient;@SpringBootApplication//开启Eureka客户端@EnableEurekaClient@EnableCircuitBreaker//开启hystrix的断路器public class FsProviderHystrix8001 {public static void main(String[] args) {SpringApplication.run(FsProviderHystrix8001.class,args);}}

PaymentServiceImpl 业务接口实现类

主要注解:@HystrixCommand

package com.fs.service.impl;import com.fs.dao.PaymentDao;import com.fs.pojo.Payment;import com.fs.result.Result;import com.fs.service.PaymentService;import flix.hystrix.contrib.javanica.annotation.HystrixCommand;import flix.hystrix.contrib.javanica.annotation.HystrixProperty;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.bind.annotation.PathVariable;import java.util.List;@Servicepublic class PaymentServiceImpl implements PaymentService {//注入dao@Autowiredprivate PaymentDao paymentDao;@Overridepublic List<Payment> findAll() {//使用MyBatis提供的方法return paymentDao.selectList(null);}/*测试消费端配置的服务降级方法*/@Overridepublic Result testConsumer(Integer id) {//制作异常,然后调用这个方法就会去调用配置的降级方法if (id==0){//id==0.就异常int i = 1/0;}return new Result(true,"testConsumer调用成功");}/*降级:1.服务出现异常2.服务调用超时,默认为1秒*/@Override//@HystrixCommand一旦调用服务方法失败并抛出了错误信息后,会自动调用标注好的fallbackMethod()指定降级后调用的方法名称@HystrixCommand(fallbackMethod = "providerFallbackMethod",commandProperties = {//HystrixCommandProperties:这个类中有HystrixCommand注解的所有配置//timeoutInMilliseconds规定这个方法在3秒内没有正常执行,就服务降级,方法异常会立马进行降级,不配置默认1秒@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")//熔断不配置默认是 默认失败次数20次 失败率默认百分之50 默认5000毫秒 就是打开状态与半开状态之间的休眠时间})public Result testFallbackMethod(Integer id){//制作异常,然后调用这个方法就会去调用配置的降级方法if (id==0){//id==0.就异常int i = 1/0;}return new Result(true,"testFallbackMethod调用成功");}//服务对应的降级方法/*1.方法的返回值需要和原方法一样2,方法的参数需要和原方法一样*/@Overridepublic Result providerFallbackMethod(Integer id){return new Result(false,"小二开小差中,请稍候再试~~~服务降级方法");}//======服务熔断,providerCircuitBreakerMethod异常或者超时调用的方法@HystrixCommand(fallbackMethod = "providerCircuitBreakerMethod",commandProperties = {@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),//是否开启断路器//sleepWindowInMilliseconds请求量阈值 默认失败次数20次@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),//请求次数//监控时间,默认5000毫秒 就是打开状态与半开状态之间的休眠时间@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"),//时间窗口日期//误差阈值百分比errorThresholdPercentage 失败率默认百分之50@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"),//失败率60%达到多少跳闸(进行服务熔断)})public Result providerCircuitBreaker(@PathVariable("id") Integer id){//制作异常,然后调用这个方法就会去调用配置的降级方法if (id==0){//id==0.就异常int i = 1/0;}return new Result(true,"providerCircuitBreaker调用成功");}//熔断友好提示方法@Overridepublic Result providerCircuitBreakerMethod(Integer id){return new Result(false,"服务器繁忙,请稍候再试~~~熔断方法");}}

fs-consumer-hystrix-80 使用feign远程调用 服务消费端

pom.xml

== hystrix 因为OpenFeign集成了hystrix,所以不用导入hystrix的依耐==

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><parent><artifactId>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-consumer-hystrix-80</artifactId><dependencies><!-- hystrix 因为OpenFeign集成了hystrix,所以不用导入hystrix的依耐--><!--spring-boot-starter-web spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!-- eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!-- 排除controller返回的格式为xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!-- 自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

主要的是加上:

因为feign默认是不开启hystrix的

# 开启feign对hystrix的支持,因为feign默认是不开启hystrix的feign:hystrix:enabled: true

application.yml

server:port: 80spring:application:name: fs-consumer-hystrix-80eureka:client:register-with-eureka: false # 消费者我目前的用途不需要将消费者注册到注册中心fetch-registry: true # 从注册中心拉取服务registry-fetch-interval-seconds: 30 # 默认30秒定时去注册中心拉取服务service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注册中心地址# 设置feign客户端超时时间(OpenFeign默认支持Ribbon) 不配置,默认1秒,因为feign底层是使用的Ribbon,Ribbon默认超时是1秒ribbon:#指的是建立链接后从服务器读取到可用资源所用的时间,等5秒ReadTimeout: 5000#指的是建立连接所用的时间,适用于网络状态正常的情况下,两端连接所用的时间,等5秒ConnectTimeout: 5000logging:level:# root: debug # 开启springboot的debug的日志信息,不配置springboot默认是info# com.fs: debug # 开启部分springboot的debug的日志信息# feign日志以什么级别监控那个feign组件功能使用的接口,使用debug级别(只能记录debug级别),然后调用服务方法,在控制台就能看到详细debug信息com.fs.springcloud.server.PaymentOpenFeignService: debug# 开启feign对hystrix的支持,因为feign默认是不开启hystrix的feign:hystrix:enabled: true

FsConsumerHystrix80 主启动

package com.fs;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.flix.eureka.EnableEurekaClient;import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication//使用openFeign,激活并开启,feign集成了robbin同时集成了hystrix,自动默认轮询的负载均衡规则@EnableFeignClients@EnableEurekaClientpublic class FsConsumerHystrix80 {public static void main(String[] args) {SpringApplication.run(FsConsumerHystrix80.class,args);}}

PaymentOpenFeignHystrix 定义 OpenFeign的接口

指定服务降级友好方法类:fallback = PaymentHystrixFallbackServiceImpl.class

package com.fs.feign;import com.fs.config.OpenFeignConfig;import com.fs.pojo.Payment;import com.fs.result.Result;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;/*** feign的声明式接口,发起远程调用的,简化restTemplate** 1.定义接口* 2.接口上添加注解@FeignClient(value = "注册中心服务提供者名",configuration=定义的OpenFeign的日志类,fallback定义服务降级方法)* 3.编写调用接口,接口的声明规则和提供方接口保持一致* 4.去controller注入改接口对象,调用接口方法来完成远程调用*/@FeignClient(value = "fs-provider-hystrix",configuration = OpenFeignConfig.class,fallback = PaymentHystrixFallbackServiceImpl.class)public interface PaymentOpenFeignHystrix {//复制服务提供的controller方法,路径记得加上controller类上的路径@RequestMapping("/payment/findAll")Result<List<Payment>> findAll();//测试time超时,由于我们在服务提供方的这个方法制作了sleep2秒,由于feign底层基于Ribbon,//Ribbon默认超时时间为1秒,所以报错.SocketTimeoutException: Read timed out//解决办法在配置文件中配置Ribbon的超时时间@RequestMapping("/payment/testTimeOut/{id}")Result test(@PathVariable("id") Integer id);}

PaymentHystrixFallbackServiceImpl 远程调用异常或者超时的服务降级友好方法类

package com.fs.feign;import com.fs.pojo.Payment;import com.fs.result.Result;import org.ponent;import java.util.List;/*** Feign 客户端的降级处理类(feign自动集成hystrix,但是默认关闭,需要在yml中开启)* 1. 定义类 实现 Feign 客户端接口* 2. 使用@Component注解将该类的Bean加入SpringIOC容器* 默认异常降级,默认等待超时1秒,默认异常占比百分之50,默认的半开时间5秒,默认10秒20次失败请求*/@Componentpublic class PaymentHystrixFallbackServiceImpl implements PaymentOpenFeignHystrix {@Overridepublic Result<List<Payment>> findAll() {return new Result(false,"fs-consumer-hystrix-80-findAll服务降级");}@Overridepublic Result test(Integer id) {return new Result(false,"fs-consumer-hystrix-80-test服务降级");}}

OpenFeignConfig

package com.fs.config;import feign.Logger;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/*OpenFeign的日志配置类*/@Configurationpublic class OpenFeignConfig {@BeanLogger.Level feignLoggerLevel(){//表示开启的是详细的feign日志,FULL表示最为详细的,点进去有4个return Logger.Level.FULL;}//还需要在yml中配置feign日志已什么级别监控那个接口}

PaymentController 消费端controller

package com.fs.controller;import com.fs.feign.PaymentOpenFeignHystrix;import com.fs.pojo.Payment;import com.fs.result.Result;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PathVariable;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController@RequestMapping("/consumer")public class PaymentController {//注入OpenFeign接口@Autowiredprivate PaymentOpenFeignHystrix paymentOpenFeign;@RequestMapping("/payment/findAll")public Result<List<Payment>> findAll(){//调用OpenFeign接口Result<List<Payment>> all = paymentOpenFeign.findAll();return all;}//测试OpenFeign远程调用,服务降级方法@RequestMapping("/payment/testTimeOut/{id}")Result test(@PathVariable("id")Integer id){Result test = paymentOpenFeign.test(id);return test;}}

启动项目测试

先启动eureka注册中心:fs-server-eureka-7001

在启动服务提供端:fs-provider-hystrix-8001

在启动服务消费端:fs-consumer-hystrix-80

首先浏览器输入:http://localhost:7001/

然后测试服务提供方的业务是否能正常访问,我们直接访问被指定降级的业务方法

然后测试服务消费端配置的服务降级接口

Hystrix 熔断监控

Gateway 网关

网关概述

• 网关旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。

• 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求。

• 存在的问题:

• 客户端多次请求不同的微服务,增加客户端的复杂性

• 认证复杂,每个服务都要进行认证

• http请求不同服务次数增加,性能不高

• 网关就是系统的入口,封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、缓存、负载均衡、流量管控、路由转发等

• 在目前的网关解决方案里,有Nginx+ Lua、Netflix Zuul 、Spring Cloud Gateway等等

什么是Gateway

定义:前端统一访问微服务的人口功能: 认证鉴权日志监控缓存负载均衡流量控制 事实: Gateway自动集成Ribbon,且默认开启相关功能

Gateway 网关路由配置

Gateway 网关路由配置 – 静态路由

# 网关配置gateway:discovery:locator:enabled: true #使用情况少,不常用(了解) 开启从注册中心动态创建路由的功能,利用微服务进行路由,请求路径前可以添加微服务名称lower-case-service-id: true #(了解) 允许请求路径的微服务名称为小写routes:- id: payment_routh #payment_routh 路由的id,若不配置,默认是UUID,没有固定规则但要求唯一uri: http://localhost:8001 # 静态路由 这样配置是死的,不好 匹配后提供服务的路由地址

Gateway 网关路由配置 – 动态路由

• 引入eureka-client配置

• 修改uri属性:uri: lb://服务名称

# 网关配置gateway:discovery:locator:enabled: true #使用情况少,不常用(了解) 开启从注册中心动态创建路由的功能,利用微服务进行路由,请求路径前可以添加微服务名称lower-case-service-id: true #(了解) 允许请求路径的微服务名称为小写routes:- id: payment_routh #payment_routh 路由的id,若不配置,默认是UUID,没有固定规则但要求唯一uri: lb://FS-PROVIDER # 动态路由 匹配提供服务的路由地址,达到路由是去服务中心找端口,而不是写死:原理是使用自动集成Ribbon,使用默认配置

Gateway 网关路由配置 – 微服务名称配置

# 网关配置gateway:discovery:locator:enabled: true #使用情况少,不常用(了解) 开启从注册中心动态创建路由的功能,利用微服务进行路由,请求路径前可以添加微服务名称lower-case-service-id: true #(了解) 允许请求路径的微服务名称为小写

Gateway 过滤器

局部过滤器配置

predicates 断言

spring:application:name: fs-gatewaycloud:# 网关配置gateway:discovery:locator:enabled: true #使用情况少,不常用(了解) 开启从注册中心动态创建路由的功能,利用微服务进行路由,请求路径前可以添加微服务名称lower-case-service-id: true #(了解) 允许请求路径的微服务名称为小写# 路由配置:转发规则routes:- id: payment_routh #payment_routh 路由的id,若不配置,默认是UUID,没有固定规则但要求唯一#uri: http://localhost:8001 # 静态路由 这样配置是死的,不好 匹配后提供服务的路由地址uri: lb://FS-PROVIDER # 动态路由 匹配提供服务的路由地址,达到路由是去服务中心找端口,而不是写死:原理是使用自动集成Ribbon,使用默认配置filters:# 下面是官方给定的局部过滤器,我们一般还是使用自定义过滤器# - AddRequestParameter=username,xiaofu # 通过过滤工厂会在匹配的请求头上加上一对请求头参数,名称为username值为xiaofupredicates: # predicates就是为了实现一组匹配规则,让请求过来找到对应的route进行处理- Path=/payment/get/** # 断言,路径相匹配的地址 注意Path要大写# - Cookie=username,xiaofu #携带cookie访问,断言是否有,有就允许访问,这里写死了 使用cmd命令curl携带cookie测试 curl http://localhost:9527/payment/get/2 --cookie "username=xiaofu"# 可以配置多个# - id: payment_routh02 #payment_routh02 路由的id,没有固定规则但要求唯一#uri: http://localhost:8001 #匹配后提供服务的路由地址#predicates:# - Path=/payment/lb/** # 断言,路径相匹配的地址

全局过滤器在下面的案列中

使用Gateway

1.导入依耐

2.编写application.yml配置

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency>

搭建Gateway工程

pom.xml

<?xml version="1.0" encoding="UTF-8"?><project xmlns="/POM/4.0.0"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><parent><artifactId>shangguiguSpringCloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs_gateway_gateway9527</artifactId><dependencies><!-- gateway--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- eureka-client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- 基础配置--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- test--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency></dependencies></project>

application.yml

配置

路由配置 id:自定义服务名称(唯一)uri:请求转发的目的地 静态路由:http://localhost:8080/动态路由:lb://服务名称 predicates:那些请求需要使用该路由配置进行转发 Path=/Result/** 依据请求路径来匹配转发的请求 filter 可以使用官方定义的过滤器,但一般使用我们自己定义的

server:port: 9527spring:application:name: fs-gatewaycloud:# 网关配置gateway:discovery:locator:enabled: true #使用情况少,不常用(了解) 开启从注册中心动态创建路由的功能,利用微服务进行路由,请求路径前可以添加微服务名称lower-case-service-id: true #(了解) 允许请求路径的微服务名称为小写# 路由配置:转发规则routes:- id: payment_routh #payment_routh 路由的id,若不配置,默认是UUID,没有固定规则但要求唯一#uri: http://localhost:8001 # 静态路由 这样配置是死的,不好 匹配后提供服务的路由地址uri: lb://FS-PROVIDER # 动态路由 匹配提供服务的路由地址,达到路由是去服务中心找端口,而不是写死:原理是使用自动集成Ribbon,使用默认配置filters:# 下面是官方给定的局部过滤器,我们一般还是使用自定义过滤器# - AddRequestParameter=username,xiaofu # 通过过滤工厂会在匹配的请求头上加上一对请求头参数,名称为username值为xiaofupredicates: # predicates就是为了实现一组匹配规则,让请求过来找到对应的route进行处理- Path=/payment/get/** # 断言,路径相匹配的地址 注意Path要大写# - Cookie=username,xiaofu #携带cookie访问,断言是否有,有就允许访问,这里写死了 使用cmd命令curl携带cookie测试 curl http://localhost:9527/payment/get/2 --cookie "username=xiaofu"# 可以配置多个# - id: payment_routh02 #payment_routh02 路由的id,没有固定规则但要求唯一#uri: http://localhost:8001 #匹配后提供服务的路由地址#predicates:# - Path=/payment/lb/** # 断言,路径相匹配的地址eureka:instance:hostname: fs-gateway-service#服务提供者provider,注册进eureka服务列表内client:service-url:register-with-eureka: true # 注册到服务中心fetch-register: true # 从注册中心获取注册的服务信息defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注册中心地址

主启动

package com.fs.springcloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.flix.eureka.EnableEurekaClient;@SpringBootApplication@EnableEurekaClientpublic class GatewayMain9527 {public static void main(String[] args) {SpringApplication.run(GatewayMain9527.class,args);}}

自定义网关过滤器MyGatewayFilter(全局过滤器)

对请求进行功能的增强(认证、设置凭证信息等)

局部过滤器:只对配置的路由进行生效 org.springframework.cloud.gateway.filter.factory.过滤器名称GatewayFilterFactory 全局过滤器:所有请求都生效 GlobalFilterOrdered指定过滤器执行的顺序,越小越先执行)

package com.fs.springcloud.filter;import lombok.extern.slf4j.Slf4j;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.ponent;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Date;/*自定义gateway路由全局过滤器,只需要编码,不需要进行任何配置implements GlobalFilter, Ordered需要实现这两个接口*/@Component@Slf4jpublic class MyGatewayFilter implements GlobalFilter, Ordered {//过滤方法//测试http://localhost:9527/payment/get/2?username=xiaofu@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("~~~~~进到了MyGatewayFilter自定义过滤器:"+new Date().getTime());//获取请求参数中有没有usernameString username = exchange.getRequest().getQueryParams().getFirst("username");//没有就非法if (username== null){log.info("~~~用户名为null,非法用户~~~~");//没有传递用户名,就返回个状态码不能接受的状态码exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);return exchange.getResponse().setComplete();}//放行,向下继续执行return chain.filter(exchange);}/*** 过滤器排序* @return 数值越低,越先加载*/@Overridepublic int getOrder() {//加载过滤器顺序,数值越低,越先加载return 0;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。