当前位置:   article > 正文

关于SpringCloud的知识点总结(基础版)

关于SpringCloud的知识点总结(基础版)

Eureka

1. 注册中心

注册中心与生产者,消费者之间的原理图:

  • Eureka:就是服务注册中心(可以是一个集群),对外暴露自己的地址

  • 提供者:启动后向Eureka注册自己信息(地址,提供什么服务)

  • 消费者:向Eureka订阅服务,Eureka会将对应服务的所有提供者地址列表发送给消费者,并且定期更新

  • 心跳(续约):提供者定期通过http方式向Eureka刷新自己的状态

2. 服务端:
2.1 依赖:
  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.0.6.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <properties>
  8. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  9. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  10. <java.version>1.8</java.version>
  11. <spring-cloud.version>Finchley.SR2</spring-cloud.version>
  12. </properties>
  13. <!-- SpringCloud依赖管理 -->
  14. <dependencyManagement>
  15. <dependencies>
  16. <dependency>
  17. <groupId>org.springframework.cloud</groupId>
  18. <artifactId>spring-cloud-dependencies</artifactId>
  19. <version>${spring-cloud.version}</version>
  20. <type>pom</type>
  21. <scope>import</scope>
  22. </dependency>
  23. </dependencies>
  24. </dependencyManagement>
  25. <dependencies>
  26. <dependency>
  27. <groupId>org.springframework.cloud</groupId>
  28. <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
  29. </dependency>
  30. </dependencies>
2.2配置文件:
  1. server:
  2. port: 10087 # 端口
  3. spring:
  4. application:
  5. name: eureka-server # 应用名称,会在Eureka中显示
  6. eureka:
  7. client:
  8. service-url: # EurekaServer的地址,现在是自己的地址,如果是集群,需要加上其它Server的地址。
  9. defaultZone: http://127.0.0.1:${server.port}/eureka
  10. # 不注册自己
  11. # register-with-eureka: false
  12. # 不拉取服务
  13. # fetch-registry: false

(1)eureka.client.registerWithEureka :表示是否将自己注册到Eureka Server,默认为true。由于当前这个应用就是Eureka Server,故而设为false。

(2)eureka.client.fetchRegistry :表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,故而设为false。  

2.3 修改引导类,在类上添加@EnableEurekaServer注解:

  1. @SpringBootApplication
  2. @EnableEurekaServer // 声明当前springboot应用是一个eureka服务中心
  3. public class YhEurekaApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(YhEurekaApplication.class, args);
  6. }
  7. }

3.注册到Eureka:

概念:注册服务,就是在服务上添加Eureka的客户端依赖,客户端代码会自动把服务注册到EurekaServer中。

其中还有一个重要的知识点,暂时先不讲:RestTemplate

流程:

  1. 在pom.xml中,添加springcloud的相关依赖。

  2. 在application.yml中,添加springcloud的相关依赖。

  3. 在引导类上添加注解,把服务注入到eureka注册中心。

3.1 依赖 
  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.0.6.RELEASE</version>
  5. <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
  7. <properties>
  8. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  9. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  10. <java.version>1.8</java.version>
  11. </properties>
  12. <dependencyManagement>
  13. <dependencies>
  14. <dependency>
  15. <groupId>org.springframework.cloud</groupId>
  16. <artifactId>spring-cloud-dependencies</artifactId>
  17. <version>Finchley.SR1</version>
  18. <type>pom</type>
  19. <scope>import</scope>
  20. </dependency>
  21. </dependencies>
  22. </dependencyManagement>
  23. <dependencies>
  24. <dependency>
  25. <groupId>org.springframework.boot</groupId>
  26. <artifactId>spring-boot-starter-jdbc</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.springframework.boot</groupId>
  30. <artifactId>spring-boot-starter-web</artifactId>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.mybatis.spring.boot</groupId>
  34. <artifactId>mybatis-spring-boot-starter</artifactId>
  35. <version>1.3.2</version>
  36. </dependency>
  37. <-- 上面是springboot的基本依赖 -->
  38. <dependency>
  39. <groupId>org.springframework.cloud</groupId>
  40. <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
  41. </dependency>
  42. </dependencies>
3.2 配置文件
  1. server:
  2. port: 8081
  3. spring:
  4. datasource:
  5. url: jdbc:mysql://localhost:3306/lxw
  6. username: root
  7. password: root
  8. driverClassName: com.mysql.jdbc.Driver
  9. application:
  10. name: service-provider # 应用名称,注册到eureka后的服务名称
  11. mybatis:
  12. type-aliases-package: cn.yh.service.pojo
  13. eureka:
  14. client:
  15. service-url: # EurekaServer地址
  16. defaultZone: http://127.0.0.1:10087/eureka
3.3 修改引导类

通过添加@EnableDiscoveryClient来开启Eureka客户端功能,@EnableDiscoveryClient该注解是netflix公司提供的,后期推荐使用springcloud提供的注解@EnableDiscoveryClient,功能相同。

  1. @SpringBootApplication
  2. @EnableDiscoveryClient
  3. public class YhServiceProviderApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(YhServiceApplication.class, args);
  6. }
  7. }

4. 基本架构

Eureka架构中的三个核心角色:

  • 服务注册中心

    Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的yh-eureka。

  • 服务提供者

    提供服务的应用,可以是SpringBoot应用,也可以是其它任意技术实现,只要对外提供的是Rest风格服务即可。本例中就是我们实现的yh-service-provider。

  • 服务消费者

    消费应用从注册中心获取服务列表,从而得知每个服务方的信息,知道去哪里调用服务方。本例中就是我们实现的yh-service-consumer。

5. 高可用的Eureka Server

        Eureka Server即服务的注册中心,在刚才的案例中,我们只有一个EurekaServer,事实上EurekaServer也可以是一个集群,形成高可用的Eureka中心。

5.1 服务同步

        多个Eureka Server之间也会互相注册为服务,当服务提供者注册到Eureka Server集群中的某个节点时,该节点会把服务的信息同步给集群中的每个节点,从而实现数据同步。因此,无论客户端访问到Eureka Server集群中的任意一个节点,都可以获取到完整的服务列表信息。

5.2 动手搭建高可用的EurekaServer

        操作流程:

                1. 启动第一个eurekaServer,我们修改原来的EurekaServer配置中的端口号,

                2. 复制一个启动器,然后在启动服务,就会有两个端口的客户端(都是生产者/消费者)

5.3客户端注册服务到集群

        因为EurekaServer不止一个,因此注册服务的时候,service-url参数需要变化:

  1. eureka:
  2. client:
  3. service-url: # EurekaServer地址,多个地址以','隔开
  4. defaultZone: http://127.0.0.1:10086/eureka,http://127.0.0.1:10087/eureka
5.3 服务提供者

        服务提供者要向EurekaServer注册服务,并且完成服务续约等工作。

5.3.1 服务注册

        服务提供者在启动时,会检测配置属性中的:eureka.client.register-with-eureka=true参数是否正确,事实上默认就是true。如果值确实为true,则会向EurekaServer发起一个Rest请求,并携带自己的元数据信息,Eureka Server会把这些信息保存到一个双层Map结构中。

Map<serviceId,Map<服务实例名,实例对象instance>>

  • 第一层Map的Key就是服务id,一般是配置中的spring.application.name属性

  • 第二层Map的key是服务的实例id。一般host+ serviceId + port,例如:locahost:service-provider:8081

  • 值则是服务的实例对象,也就是说一个服务,可以同时启动多个不同实例,形成集群。

5.3.2 服务续约

        在注册服务完成以后,服务提供者会维持一个心跳(定时向EurekaServer发起Rest请求),告诉EurekaServer:“我还活着”。这个我们称为服务的续约(renew);

        有两个重要参数可以修改服务续约的行为:

  1. eureka:
  2. instance:
  3. lease-expiration-duration-in-seconds: 90
  4. lease-renewal-interval-in-seconds: 30
  • lease-renewal-interval-in-seconds:服务续约(renew)的间隔,默认为30秒

  • lease-expiration-duration-in-seconds:服务失效时间,默认值90秒

也就是说,默认情况下每个30秒服务会向注册中心发送一次心跳,证明自己还活着。如果超过90秒没有发送心跳,EurekaServer就会认为该服务宕机,会从服务列表中移除,这两个值在生产环境不要修改,默认即可。

但是在开发时,这个值有点太长了,经常我们关掉一个服务,会发现Eureka依然认为服务在活着。所以我们在开发阶段可以适当调小。

  1. eureka:
  2. instance:
  3. lease-expiration-duration-in-seconds: 10 # 10秒即过期
  4. lease-renewal-interval-in-seconds: 5 # 5秒一次心跳
5.4 服务消费者

获取服务列表

        当服务消费者启动时,会检测eureka.client.fetch-registry=true参数的值,如果为true,则会拉取Eureka Server服务的列表只读备份,然后缓存在本地。并且每隔30秒会重新获取并更新数据。我们可以通过下面的参数来修改:

  1. eureka:
  2. client:
  3. registry-fetch-interval-seconds: 5 #默认每隔30秒会从注册中心服务列表中重新拉取一次

生产环境中,我们不需要修改这个值。

但是为了开发环境下,能够快速得到服务的最新状态,我们可以将其设置小一点。

6. 失效剔除和自我保护

6.1 服务下线

        当服务进行正常关闭操作时,它会触发一个服务下线的REST请求给Eureka Server,告诉服务注册中心:“我要下线了”。服务中心接受到请求之后,将该服务置为下线状态。

6.2 失效剔除

        有些时候,我们的服务提供方并不一定会正常下线,可能因为内存溢出、网络故障等原因导致服务无法正常工作。Eureka Server需要将这样的服务剔除出服务列表。因此它会开启一个定时任务,每隔60秒对所有失效的服务(超过90秒未响应)进行剔除。

        可以通过eureka.server.eviction-interval-timer-in-ms参数对其进行修改,单位是毫秒,生产环境不要修改。

        这个会对我们开发带来极大的不便,你对服务重启,隔了60秒Eureka才反应过来。开发阶段可以适当调整,比如:10秒

6.3 自我保护

        我们关停一个服务,就会在Eureka面板看到一条警告:

         这是触发了Eureka的自我保护机制。当一个服务未按时进行心跳续约时,Eureka会统计最近15分钟心跳失败的服务实例的比例是否超过了85%。在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。Eureka就会把当前实例的注册信息保护起来,不予剔除。生产环境下这很有效,保证了大多数服务依然可用。

        但是这给我们的开发带来了麻烦, 因此开发阶段我们都会关闭自我保护模式:(yh-eureka)

  1. eureka:
  2. server:
  3. enable-self-preservation: false # 关闭自我保护模式(缺省为打开)
  4. eviction-interval-timer-in-ms: 1000 # 扫描失效服务的间隔时间(缺省为60*1000ms)

负载均衡

1. 概念:

        Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP客户端的行为。为Ribbon配置服务提供者提供地址列表后,Ribbon就可基于某种负载均衡算法,自助地帮助服务消费者去请求。Ribbon默认为我们提供了很多的负载均衡算法,例如轮询,随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。

2. 开启负载均衡

因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖,直接修改代码。

修改yh-service-consumer的引导类,在RestTemplate的配置方法上添加@LoadBalanced注解:

  1. @Bean
  2. @LoadBalanced
  3. public RestTemplate restTemplate() {
  4. return new RestTemplate();
  5. }

3. 修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用:

  1. @Controller
  2. @RequestMapping("consumer/user")
  3. public class UserController {
  4. @Autowired
  5. private RestTemplate restTemplate;
  6. //@Autowired
  7. //private DiscoveryClient discoveryClient; // 注入discoveryClient,通过该客户端获取服务列表
  8. @GetMapping
  9. @ResponseBody
  10. public User queryUserById(@RequestParam("id") Long id){
  11. // 通过client获取服务提供方的服务列表,这里我们只有一个
  12. // ServiceInstance instance = discoveryClient.getInstances("service-provider").get(0);
  13. String baseUrl = "http://service-provider/user/" + id;
  14. User user = this.restTemplate.getForObject(baseUrl, User.class);
  15. return user;
  16. }
  17. }

Hystrix

1. 概念:

1. 原理:

Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队.加速失败判定时间。
用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超时,则会进行降级处理。
服务降级虽然会导致请求失败,但是不会导致阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其它服务没有响应。

2.触发Hystix服务降级的情况:
- 线程池已满
- 请求超时
3. 依赖
  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
  4. </dependency>
4. 注解:

注解:@EnableCircuitBreaker   --->@SpringCloudApplication=@SpringBootApplication+@EnableDiscoveryClient+@EnableCircuitBreaker

5. 操作

1. 实现单个降级方法:@HystixCommond(fallbackMethod = "降级要执行的方法名")注到要降级的方法上,然后编写要降级的方法,参数和返回值要一致,方法名没有要求。
2. 
    2.1 实现多个降级方法:在Controller类上添加@DefaultProperties(defaultFallback = "降级要执行的方法名") // 指定一个类的全局熔断方法
    2.2 接着在要降级的方法上添加 @HystixCommond注解,然后再编写要降级的方法,参数和返回值要一致,方法名没有要求

  1. - @DefaultProperties(defaultFallback = "defaultFallBack"):在类上指明统一的失败降级方法
  2. - @HystrixCommand:在方法上直接使用该注解,使用默认的降级方法。
  3. - defaultFallback:默认降级方法,不用任何参数,以匹配更多方法,但是返回值一定一致

设置超时时间:请求在超过这个时间之后会报错,默认是1秒
我们可以通过`hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds`来设置Hystrix超时时间:

  1. hystrix:
  2. command:
  3. default:
  4. execution:
  5. isolation:
  6. thread:
  7. timeoutInMilliseconds: 6000 # 设置hystrix的超时时间为6000ms

2. 熔断

2.1 概念:

熔断器,也叫断路器,其英文单词为:Circuit Breaker         
熔断是降级下的一个小的模块,当至少访问20次,且有一般的概率出错时,会触发熔断,此时熔断处于断开状态,不论是正确的请求还是错误的请求都无法通过,
默认会休眠5秒,5秒之后,熔断会进入半开状态,此时会关闭一部分请求路径,如果请求正确,那么就可以通过,拿去数据,之后就可以进入关闭状态,所有正确的请求都可以通过。

2.2 熔断状态机3个状态:

可以通过抛异常让熔断进入打开状态
- Closed:关闭状态,所有请求都正常访问。
- Open:打开状态,所有请求都会被降级。Hystix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
- Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,
则会完全关闭断路器,否则继续保持打开,再次进行休眠计时

  1. - requestVolumeThreshold:触发熔断的最小请求次数,默认20
  2. - errorThresholdPercentage:触发熔断的失败请求最小占比,默认50%
  3. - sleepWindowInMilliseconds:休眠时长,默认是5000毫秒

Feign

1. 概念

Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。你不用再自己拼接url,拼接参数等等操作,一切都交给Feign去做。

2. 操作流程

0. 在启动器application类中添加@EnableFeignClients注解
1. 创建一个feign在feign目录下的UserClient接口,接着添加@FeignClient(value = "service-provider")注解,value是生产者的服务名。
2. 定义抽象方法,返回值类型,参数类型与生产者的方法一致,@PathVariable注解也不能省略,方法名可以任意,RequestMapping与生产者的controller的uri一致

  1. @FeignClient(value = "service-provider") // 标注该类是一个feign接口
  2. public interface UserClient {
  3. @GetMapping("user/{id}")
  4. User queryById(@PathVariable("id") Long id);
  5. }

- 首先这是一个接口,Feign会通过动态代理,帮我们生成实现类。这点跟mybatis的mapper很像
- `@FeignClient`,声明这是一个Feign客户端,类似`@Mapper`注解。同时通过`value`属性指定服务名称
- 接口中的定义方法,完全采用SpringMVC的注解,Feign会根据注解帮我们生成URL,并访问获取结果

然后在Controller里面

  1. @Autowired
  2. private UserClient userClient;
  3. userClient.queryUserById(id);

3. 依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-openfeign</artifactId>
  4. </dependency>

Feign默认也有对Hystrix的集成:
只不过,默认情况下是关闭的。我们需要通过下面的参数来开启:(在Yh-service-consumer工程添加配置内容)

  1. feign:
  2. hystrix:
  3. enabled: true # 开启Feign的熔断功能
  4. 这个时候就不可以用@SpringCloudApplication注解了,因为@SpringCloudApplication包含了@EnableCircuitBreaker,这个注解的意思就是开启熔断

首先,我们要定义一个类UserClientFallback,实现刚才编写的UserClient,作为fallback的处理类

  1. @Component
  2. public class UserClientFallback implements UserClient {
  3. @Override
  4. public User queryById(Long id) {
  5. User user = new User();
  6. user.setUserName("服务器繁忙,请稍后再试!");
  7. return user;
  8. }
  9. }

然后在UserFeignClient中,指定刚才编写的实现类

  1. @FeignClient(value = "service-provider", fallback = UserClientFallback.class) // 标注该类是一个feign接口
  2. public interface UserClient {
  3. @GetMapping("user/{id}")
  4. User queryUserById(@PathVariable("id") Long id);
  5. }

Zuul网关

1. 概念:

        Zuul是Netflix开源的微服务网关,他可以和Eureka,Ribbon,Hystrix等组件配合使用。Zuul的核心是一系列的过滤器。

这些过滤器可以完成一下功能:

  • 身份认证与安全:识别每个资源的验证要求,并拒绝那些与要求不符的请求。
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
  • 动态路由:动态地将请求路由到不同的后端集群。
  • 压力测试:逐渐增加指向集群的流量,以了解性能。
  • 负载分配:为每一种负载类型分配对应容量,并启用超出限定值的请求。
  • 静态相应处理:在边缘位置直接建立部分响应,从而避免其转发到内部集群。
  • 多区域弹性:跨越AWS Region进行请求路由,旨在实现ELB(ElasticSearch Load Balanceing) 使用多样化,以及让系统的边缘更贴近系统的使用者。

2. 依赖

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
  4. </dependency>

3. 配置文件

  1. server:
  2. port: 10010 #服务端口
  3. spring:
  4. application:
  5. name: api-gateway #指定服务名

4. 添加注解

给启动类添加@EnableZuulProxy注解,表示开启网关功能

5. 配置路由规则:

  1. 第一种方式:
  2. zuul:
  3. routes:
  4. service-provider: # 这里是路由id,随意写
  5. path: /service-provider/** # 这里是映射路径
  6. url: http://127.0.0.1:8081 # 映射路径对应的实际url地址
  7. 第二种方式
  8. zuul:
  9. routes:
  10. service-provider: # 这里是路由id,随意写
  11. path: /service-provider/**
  12. url: http://127.0.0.1:8081
  13. service-id: service-provider #指定服务名称
  14. 第三种方式:推荐使用
  15. zuul:
  16. routes:
  17. service-provider: /service-provider/**
  18. service-consumer: /service-consumer/**
  19. prefix: /api
  20. 第四种方式:
  21. 不配置,即默认配置,默认情况,每个微服务的服务名,即是访问映射地址

6. 过滤器

        Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。而这个动作我们往往是通过Zuul提供的过滤器来实现的     

6.1 ZuulFilter抽象类

ZuulFilter是过滤器的顶级父类。在这里我们看一下其中定义的4个最重要的方法:

  1. public abstract ZuulFilter implements IZuulFilter{
  2. abstract public String filterType();
  3. abstract public int filterOrder();
  4. boolean shouldFilter();// 来自IZuulFilter
  5. Object run() throws ZuulException;// IZuulFilter
  6. }

    

  • shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行。

  • run:过滤器的具体业务逻辑。

  • filterType:返回字符串,代表过滤器的类型。包含以下4种:

    • pre:请求在被路由之前执行

    • route:在路由请求时调用

    • post:在route和errror过滤器之后调用

    • error:处理请求时发生错误调用

  • filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

6.2 过滤器执行生命周期

6.2.1 正常流程

  • 请求到达首先会经过pre类型过滤器,而后到达route类型,进行路由,请求就到达真正的服务提供者,执行请求,返回结果后,会到达post过滤器。而后返回响应。

6.2.2 异常流程

  • 整个过程中,pre或者route过滤器出现异常,都会直接进入error过滤器,在error处理完毕后,会将请求交给POST过滤器,最后返回给用户。

  • 如果是error过滤器自己出现异常,最终也会进入POST过滤器,将最终结果返回给请求客户端。

  • 如果是POST过滤器出现异常,会跳转到error过滤器,但是与pre和route不同的是,请求不会再到达POST过滤器了。

6.3 使用场景
  • 请求鉴权:一般放在pre类型,如果发现没有访问权限,直接就拦截了

  • 异常处理:一般会在error类型和post类型过滤器中结合来处理。

  • 服务调用时长统计:pre和post结合使用。

6.4 自定义过滤器
6.4.1 定义过滤器类

        定义过滤器类,继承ZuulFilter抽象类,并重写抽象方法。

  1. @Component
  2. public class LoginFilter extends ZuulFilter {
  3. /**
  4. * 过滤器类型,前置过滤器
  5. * @return
  6. */
  7. @Override
  8. public String filterType() {
  9. return "pre";
  10. }
  11. /**
  12. * 过滤器的执行顺序
  13. * @return
  14. */
  15. @Override
  16. public int filterOrder() {
  17. return 1;
  18. }
  19. /**
  20. * 该过滤器是否生效
  21. * @return
  22. */
  23. @Override
  24. public boolean shouldFilter() {
  25. return true;
  26. }
  27. /**
  28. * 登陆校验逻辑
  29. * @return
  30. * @throws ZuulException
  31. */
  32. @Override
  33. public Object run() throws ZuulException {
  34. // 获取zuul提供的上下文对象
  35. RequestContext context = RequestContext.getCurrentContext();
  36. // 从上下文对象中获取请求对象
  37. HttpServletRequest request = context.getRequest();
  38. // 获取token信息
  39. String token = request.getParameter("access-token");
  40. // 判断
  41. if (StringUtils.isBlank(token)) {
  42. // 过滤该请求,不对其进行路由
  43. context.setSendZuulResponse(false);
  44. // 设置响应状态码,401
  45. context.setResponseStatusCode(HttpStatus.SC_UNAUTHORIZED);
  46. // 设置响应信息
  47. context.setResponseBody("{\"status\":\"401\", \"text\":\"request error!\"}");
  48. }
  49. // 校验通过,把登陆信息放入上下文信息,继续向后执行
  50. context.set("token", token);
  51. return null;
  52. }
  53. }

7. 负载均衡和熔断

        Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。但是所有的超时策略都是走的默认值,比如熔断超时时间只有1S,很容易就触发了。因此建议我们手动进行配置:

  1. hystrix:
  2. command:
  3. default:
  4. execution:
  5. isolation:
  6. thread:
  7. timeoutInMilliseconds: 2000 # 设置hystrix的超时时间为6000ms

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/86360
推荐阅读
相关标签
  

闽ICP备14008679号