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="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><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="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"><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: 8001
spring: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 #自定义数据源# 配置eureka
eureka: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.springframework.cloud.netflix.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 com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.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;@Service
public 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="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"><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-80
eureka: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: 5000
logging: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.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
//使用openFeign,激活并开启,feign集成了robbin同时集成了hystrix,自动默认轮询的负载均衡规则
@EnableFeignClients
@EnableEurekaClient
public 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秒,所以报错java.net.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.springframework.stereotype.Component;import java.util.List;/*** Feign 客户端的降级处理类(feign自动集成hystrix,但是默认关闭,需要在yml中开启)* 1. 定义类 实现 Feign 客户端接口* 2. 使用@Component注解将该类的Bean加入SpringIOC容器* 默认异常降级,默认等待超时1秒,默认异常占比百分之50,默认的半开时间5秒,默认10秒20次失败请求*/
@Component
public 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的日志配置类*/
@Configuration
public 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="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"><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.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {public static void main(String[] args) {SpringApplication.run(GatewayMain9527.class,args);}
}
自定义网关过滤器MyGatewayFilter(全局过滤器)
对请求进行功能的增强(认证、设置凭证信息等)
- 局部过滤器:只对配置的路由进行生效
- org.springframework.cloud.gateway.filter.factory.过滤器名称GatewayFilterFactory
- 全局过滤器:所有请求都生效
- GlobalFilter
- Ordered指定过滤器执行的顺序,越小越先执行)
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.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;import java.util.Date;/*
自定义gateway路由全局过滤器,只需要编码,不需要进行任何配置implements GlobalFilter, Ordered需要实现这两个接口*/
@Component
@Slf4j
public 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;}
}
SpringCloud微服务架构之,Hystrix 熔断器,Gateway 网关相关推荐
- Github三天点击破亿,四天助力金九银十,精通SpringCloud微服务架构,成就大厂梦
又逢"金九银十",年轻的毕业生们满怀希望与忐忑,去寻找.竞争一个工作机会.已经在职的开发同学,也想通过社会招聘或者内推的时机争取到更好的待遇.更大的平台. 然而,面试人群众多,技术 ...
- 黑马4天从浅入深精通SpringCloud 微服务架构(完整资料)
目录:/001 黑马4天从浅入深精通SpringCloud 微服务架构(完整资料) ┣━━day1 ┃ ┣━━01-课程介绍.mp4 ┃ ┣━━02-系 ...
- 《SpringCloud微服务架构》学习笔记
一.SpringCloud概述 说到SpringCloud,相信大家都不陌生,它主要是用来管理微服务的,说直白有点,它就是基于SpringBoot实现的一套微服务治理工具包,它并不是一个框架,而是一系 ...
- SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用
什么是SpringCloud 微服务架构 • "微服务"一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到 http://mar ...
- Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战
Java生鲜电商平台-SpringCloud微服务架构高并发参数优化实战 一.写在前面 在Java生鲜电商平台平台中相信不少朋友都在自己公司使用Spring Cloud框架来构建微服务架构,毕竟现在这 ...
- SpringCloud微服务架构学习(二)常见的微服务架构
SpringCloud微服务架构学习(二)常见的微服务架构 1.Dubbo 阿里开源微服务框架 官网地址:http://dubbo.apache.org/en-us/ 简介: Dubbo是阿里巴巴SO ...
- SpringCloud微服务架构实战:微服务治理
微服务治理 Spring Cloud 工具套件为微服务治理提供了全面的技术支持.这些治理工具主要包括服务的注册与发现.负载均衡管理.动态路由.服务降级和故障转移.链路跟踪.服务监控等.微服务治理的主要 ...
- SpringCloud微服务架构使用心得
不积跬步,无以至千里:不积小流,无以成江海 前言 最近通过使用SpringCloud微服务架构,记录一些心得. 由于spring cloud是基于spring boot构建的,所以在引入springc ...
- SpringCloud 微服务架构,适合接私活(附源码)
欢迎关注方志朋的博客,回复"666"获面试宝典 今天给大家推荐一个牛逼的接私活项目,SpringCloud微服务架构项目! 一个由商业级项目升级优化而来的微服务架构,采用Sprin ...
最新文章
- 产品经理跪求程序员修改需求
- HDU1899 Sum the K-th's(树状数组)
- JavaScript复制内容到剪贴板
- html背景无法载入gif图像,background-image:url(XXXX.gif)为何不显示背景图片_html/css_WEB-ITnose...
- 传统节日海报PSD分层模板|年货礼品,传递年味温度
- git分支拉项目_Git 拉取 GitLab 分支上的项目
- 编程中常见的安全算法
- android 主题是什么,什么是Android中的AppCompat主题?
- 音乐计算机锦鲤抄,锦鲤抄 (feat. 银临)
- [Codeforces 894E] Ralph and Mushrooms
- 全球及中国空气净化器市场销售模式与营销策略前景咨询报告2022版
- 360手机刷机·LSPosed安装和使用教程
- pcntl_fork导致Mysql have gone away问题解决
- C语言入门(初识C语言)
- 网络:TCP的三次握手
- 数据结构—线性表(第三章)—基本知识点总结
- 【web项目】前端生日礼物--主页面篇
- unity code-动作系统Animator
- 深度剖析陈晓和贝恩之阴谋
- 一个机器学习算法工程师的基本素质~
热门文章
- 日志配置logback
- 20130320java基础学习笔记-dos命令及java临时环境变量配置
- 自己使用window.open和window.showModalDialog在父子窗口传值的实践简单总结
- 关于“SEO五条金律”的解说
- Objective-C设计模式(MVC)的实现,以及协议与委托的运用
- 在eclipse上Checkstyle的安装和使用
- 从github克隆内容到本地时权限问题
- 【转载】/etc/passwd /etc/shadow 详解
- Java线程:新特征-有返回值的线程(转)
- The Tao to Excellent