【Java】Hystrix服务保护框架

Hystrix服务保护框架

isWulongbo发布于 今天 03:03

Hystrix简介

基于Hystrix解决服务雪崩效应原理:

  1. 服务降级:在高并发情况下防止一直等待,而使用降级的方式(返回一个友好提示给客户端,不会去处理请求,调用fallBack本地方法),在tomcat没有线程处理请求的时候,不应该让用户一直等待。目的是为了用户体验。
  2. 服务熔断:目的为了保护服务。在高并发情况下,如果请求达到一定极限(可以自己设置阈值),如果流量超出了设置的阈值,自动开启服务保护功能,使用服务降级方式返回一个友好提示。服务熔断和服务降级一般是一起使用的
  3. 服务隔离:线程池隔离和信号量隔离。每个服务接口有自己独立的线程池,每个线程池互不影响,缺点CPU占用率非常高。不是所有的接口都采用线程隔离,核心关键接口隔离

依赖

springcloud-parent 中引入 pom依赖:

<!--hystrix断路器-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

</dependency>

【Java】Hystrix服务保护框架

springcloud-api-order-service-impl 中开启断路器

####开启hystrix断路器

feign:

hystrix:

enabled: true # 在feign中开启 hystrix

【Java】Hystrix服务保护框架

Feign 调用同一个接口模拟雪崩效应,一个是没加了 @HystrixCommand 注解的,一个是加了 @HystrixCommand 注解的。并创建一个方法,验证开启 @HystrixCommand 注解会 默认开启:

  1. 默认开启服务隔离,以线程池隔离方式
  2. 默认开启服务降级执行方法
  3. 默认开启服务服务熔断机制

package com.baba.api.service.impl;

import com.baba.api.entity.UserEntity;

import com.baba.api.feign.MemberServiceFeign;

import com.baba.api.service.IOrderService;

import com.baba.wlb.base.BaseResponse;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* @Author wulongbo

* @Date 2021/1/22 13:51

* @Version 1.0

*/

@RestController

public class OrderServiceImpl implements IOrderService {

//订单服务集成会员服务接口,用来实现feign 客户端 减少接口重复代码

@Autowired

private MemberServiceFeign memberServiceFeign;

@Override

@RequestMapping("/getOrderByMember")

public String getOrderByMember(String name) {

UserEntity userEntity = memberServiceFeign.getMember(name);

return userEntity == null ? "没有找到用户信息!" : userEntity.toString();

}

// 没有解决服务雪崩效应

@Override

@RequestMapping("/getUserInfoByMember")

public BaseResponse getUserInfoByMember() {

return memberServiceFeign.getUserInfo();

}

// 解决服务雪崩效应

/***

* fallbackMethod 方法作用:服务降级执行。

* @HystrixCommand 默认开启服务隔离,以线程池隔离方式

* 默认开启服务降级执行方法 getUserInfoByMemberHystrixFallbackMethod

* 默认开启服务服务熔断机制

*/

@HystrixCommand(fallbackMethod = "getUserInfoByMemberHystrixFallbackMethod")

@RequestMapping("/getUserInfoByMemberHystrix")

public BaseResponse getUserInfoByMemberHystrix() {

System.out.println("getUserInfoByMemberHystrix-->线程池名称:" + Thread.currentThread().getName());

return memberServiceFeign.getUserInfo();

}

public BaseResponse getUserInfoByMemberHystrixFallbackMethod() {

return new BaseResponse(500, "返回一个友好提示", "服务降级,服务器繁忙,请稍后重试!");

}

// 订单服务接口

@Override

@RequestMapping("/getOrderInfo")

public String getOrderInfo() {

System.out.println("getOrderInfo-->线程池名称:" + Thread.currentThread().getName());

return "订单服务接口调用成功!";

}

// Hystrix有两种方式配置保护服务,通过注解和接口形式

}

IOrderService 接口类:

package com.baba.api.service;

import com.baba.wlb.base.BaseResponse;

import org.springframework.web.bind.annotation.RequestMapping;

/**

* @Author wulongbo

* @Date 2021/1/22 13:46

* @Version 1.0

*/public interface IOrderService {

// 订单服务调用会员服务接口 feign @RequestMapping("/getOrderByMember")

String getOrderByMember(String name);

// 订单服务调用会员服务接口 feign @RequestMapping("/getUserInfoByMember")

BaseResponse getUserInfoByMember();

// 订单服务调用会员服务接口 feign @RequestMapping("/getOrderInfo")

String getOrderInfo();

}

启动测试

测试线程池隔离

依次启动 Eureka Server,Member 和 order 服务:
访问:http://localhost:8200/getUserInfoByMemberHystrix和 http://localhost:8200/getOrderInfo
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
证明 @HystrixCommand 注解会默认开启服务隔离,以线程池隔离方式。

测试服务熔断降级

打开测试工具,Apache JMeter,开200个线程,循环100组,测试20000个并发

访问http://localhost:8200/getUserInfoByMemberHystrix 接口测试
【Java】Hystrix服务保护框架

【Java】Hystrix服务保护框架
可以看到只执行了10次,默认并发请求数为10,说明服务熔断生效,而我们测试普通接口 http://localhost:8200/getOrderInfo
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
可以看到没有做降级处理。

浏览器测试熔断接口

现在我们使用浏览器访问 http://localhost:8200/getUserInfoByMemberHystrix
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
可以发现 Feign 客户端 getUserInfo()接口能访问到,但是走的是服务降级方法,原因是因为浏览器(默认1s,可以配置)在1s内没有拿到请求结果就会走服务降级方法(即响应时间,而非调用接口时间)。

解决方案,因为我们在会员接口设置了休眠时间,而我们 hystrix 是默认开启超时时间的,所以想要我们接口可以正常访问,需要关闭超时配置:

hystrix:

command:

default:

execution:

timeout:

enabled:

false

【Java】Hystrix服务保护框架

重启后再次访问 http://localhost:8200/getUserInfoByMemberHystrix
等待1.5s后,接口能够正常访问!
【Java】Hystrix服务保护框架
注意:这里只是演示效果,正常线上是一定要开始超时时间的

javaspringboot

阅读 45更新于 今天 03:06

本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议


wulongbo

我的专栏

avatar

isWulongbo

在人生的头三十年,你培养习惯,后三十年,习惯铸就你

178 声望

8 粉丝

0 条评论

得票时间

avatar

isWulongbo

在人生的头三十年,你培养习惯,后三十年,习惯铸就你

178 声望

8 粉丝

宣传栏

Hystrix简介

基于Hystrix解决服务雪崩效应原理:

  1. 服务降级:在高并发情况下防止一直等待,而使用降级的方式(返回一个友好提示给客户端,不会去处理请求,调用fallBack本地方法),在tomcat没有线程处理请求的时候,不应该让用户一直等待。目的是为了用户体验。
  2. 服务熔断:目的为了保护服务。在高并发情况下,如果请求达到一定极限(可以自己设置阈值),如果流量超出了设置的阈值,自动开启服务保护功能,使用服务降级方式返回一个友好提示。服务熔断和服务降级一般是一起使用的
  3. 服务隔离:线程池隔离和信号量隔离。每个服务接口有自己独立的线程池,每个线程池互不影响,缺点CPU占用率非常高。不是所有的接口都采用线程隔离,核心关键接口隔离

依赖

springcloud-parent 中引入 pom依赖:

<!--hystrix断路器-->

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>

</dependency>

【Java】Hystrix服务保护框架

springcloud-api-order-service-impl 中开启断路器

####开启hystrix断路器

feign:

hystrix:

enabled: true # 在feign中开启 hystrix

【Java】Hystrix服务保护框架

Feign 调用同一个接口模拟雪崩效应,一个是没加了 @HystrixCommand 注解的,一个是加了 @HystrixCommand 注解的。并创建一个方法,验证开启 @HystrixCommand 注解会 默认开启:

  1. 默认开启服务隔离,以线程池隔离方式
  2. 默认开启服务降级执行方法
  3. 默认开启服务服务熔断机制

package com.baba.api.service.impl;

import com.baba.api.entity.UserEntity;

import com.baba.api.feign.MemberServiceFeign;

import com.baba.api.service.IOrderService;

import com.baba.wlb.base.BaseResponse;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* @Author wulongbo

* @Date 2021/1/22 13:51

* @Version 1.0

*/

@RestController

public class OrderServiceImpl implements IOrderService {

//订单服务集成会员服务接口,用来实现feign 客户端 减少接口重复代码

@Autowired

private MemberServiceFeign memberServiceFeign;

@Override

@RequestMapping("/getOrderByMember")

public String getOrderByMember(String name) {

UserEntity userEntity = memberServiceFeign.getMember(name);

return userEntity == null ? "没有找到用户信息!" : userEntity.toString();

}

// 没有解决服务雪崩效应

@Override

@RequestMapping("/getUserInfoByMember")

public BaseResponse getUserInfoByMember() {

return memberServiceFeign.getUserInfo();

}

// 解决服务雪崩效应

/***

* fallbackMethod 方法作用:服务降级执行。

* @HystrixCommand 默认开启服务隔离,以线程池隔离方式

* 默认开启服务降级执行方法 getUserInfoByMemberHystrixFallbackMethod

* 默认开启服务服务熔断机制

*/

@HystrixCommand(fallbackMethod = "getUserInfoByMemberHystrixFallbackMethod")

@RequestMapping("/getUserInfoByMemberHystrix")

public BaseResponse getUserInfoByMemberHystrix() {

System.out.println("getUserInfoByMemberHystrix-->线程池名称:" + Thread.currentThread().getName());

return memberServiceFeign.getUserInfo();

}

public BaseResponse getUserInfoByMemberHystrixFallbackMethod() {

return new BaseResponse(500, "返回一个友好提示", "服务降级,服务器繁忙,请稍后重试!");

}

// 订单服务接口

@Override

@RequestMapping("/getOrderInfo")

public String getOrderInfo() {

System.out.println("getOrderInfo-->线程池名称:" + Thread.currentThread().getName());

return "订单服务接口调用成功!";

}

// Hystrix有两种方式配置保护服务,通过注解和接口形式

}

IOrderService 接口类:

package com.baba.api.service;

import com.baba.wlb.base.BaseResponse;

import org.springframework.web.bind.annotation.RequestMapping;

/**

* @Author wulongbo

* @Date 2021/1/22 13:46

* @Version 1.0

*/public interface IOrderService {

// 订单服务调用会员服务接口 feign @RequestMapping("/getOrderByMember")

String getOrderByMember(String name);

// 订单服务调用会员服务接口 feign @RequestMapping("/getUserInfoByMember")

BaseResponse getUserInfoByMember();

// 订单服务调用会员服务接口 feign @RequestMapping("/getOrderInfo")

String getOrderInfo();

}

启动测试

测试线程池隔离

依次启动 Eureka Server,Member 和 order 服务:
访问:http://localhost:8200/getUserInfoByMemberHystrix和 http://localhost:8200/getOrderInfo
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
证明 @HystrixCommand 注解会默认开启服务隔离,以线程池隔离方式。

测试服务熔断降级

打开测试工具,Apache JMeter,开200个线程,循环100组,测试20000个并发

访问http://localhost:8200/getUserInfoByMemberHystrix 接口测试
【Java】Hystrix服务保护框架

【Java】Hystrix服务保护框架
可以看到只执行了10次,默认并发请求数为10,说明服务熔断生效,而我们测试普通接口 http://localhost:8200/getOrderInfo
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
可以看到没有做降级处理。

浏览器测试熔断接口

现在我们使用浏览器访问 http://localhost:8200/getUserInfoByMemberHystrix
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
【Java】Hystrix服务保护框架
可以发现 Feign 客户端 getUserInfo()接口能访问到,但是走的是服务降级方法,原因是因为浏览器(默认1s,可以配置)在1s内没有拿到请求结果就会走服务降级方法(即响应时间,而非调用接口时间)。

解决方案,因为我们在会员接口设置了休眠时间,而我们 hystrix 是默认开启超时时间的,所以想要我们接口可以正常访问,需要关闭超时配置:

hystrix:

command:

default:

execution:

timeout:

enabled:

false

【Java】Hystrix服务保护框架

重启后再次访问 http://localhost:8200/getUserInfoByMemberHystrix
等待1.5s后,接口能够正常访问!
【Java】Hystrix服务保护框架
注意:这里只是演示效果,正常线上是一定要开始超时时间的

以上是 【Java】Hystrix服务保护框架 的全部内容, 来源链接: utcz.com/a/108935.html

回到顶部