【2.1】Java微服务:详解Hystrix

 ✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。
🍎个人主页:Meteors.的博客
💞当前专栏: Java微服务
✨特色专栏: 知识分享
🥭本文内容:【2.1】Java微服务:详解Hystrix
📚 ** ps **  : 阅读这篇文章如果有问题或者疑惑,欢迎各位在评论区提问或指出!

 -----------------------------------------------------       目录       ---------------------------------------------------------

目录

 一、基本介绍

1. 基本介绍

2. 实现原理

二、相关功能

1. 请求缓存

概述

缺点

Redis的方式

1) 导入依赖

2) 添加配置文件

3) 增加Redis 配置

4)增加缓存注解

5) 接口实现类增加缓存注解

6)结果

2. 请求合并实现

1). pom文件添加依赖

2). 在实现类进行请求合并

3)开启熔断注解

4)模拟同时发起多个请求

3.线程池隔离

1)介绍

2)优点

3)缺点

4)代码示例

4. 信号量隔离

1)介绍

2)代码示例

3) 线程池颗粒与信号隔离对比

5.服务熔断

1)介绍

2)调用

 其他

 参考文献:


---------------------------------------------------------------------------------------------------------------------------------

 一、基本介绍

1. 基本介绍

Hystix是一个延迟和容错库,旨在隔离对远程系统、服务和第三方库的访问点,停止级联故障,并在不可避免发生故障的复杂分布式系统中实现快速恢复。主要靠Spring的AOP实现


2. 实现原理

  • 正常情况下,断路器关闭,服务消费者正常请求微服务
  • 一段时间内,失败率达到一定阈值,断路器将断开,此时不在请求服务提供者,而只是快速失败的方法(断路方法)
  • 断路器打开一段时间,自动进入“半开”状态,此时,断路器可允许一个请求方法服务提供者,如果请求调用成功,则关闭断路器,否则将保持断路器打开状态

断路器hystrix是保证了局部发生的错误,不会错扩展到整个系统, 从而保证系统 的即便出现局部问题也不会造成系统雪崩

二、相关功能

1. 请求缓存

概述

Hystirx为了降低访问服务的评率,支持将一个q8ingqiu与返回接口做缓存处理。如果再次请求的URL没有变化,nameHystrix不会请求服务,而是直接从请求中将结果放回。这样可以大大降低访问服务的压力。

缺点

  • 本地缓存,集群模式下缓存无法同步
  • 不支持第三方缓存容器,如Redis、MemCache

(现在一般都是使用Redis集成方案)

Redis的方式

1) 导入依赖

        <!--  spring boot data redis 依赖  --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--  commons-pool2 对象池依赖 1  --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency>

2) 添加配置文件

  # redis缓存redis:timeout: 10000 #设置连接超时时间host: 127.0.0.1port: 6379database: 0lettuce:pool:max-active: 8 # 最大连接数,默认8max-wait: 10000 # 最大连接阻塞时间,单位毫秒,默认-1max-idle: 200 #最大空闲连接,默认8min-idle: 5 #最小空闲连接默认 0

3) 增加Redis 配置

package cn.itmeteors.order.config;/*** Redis 配置类*/import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@Configuration
public class RedisConfig {// 重写 RedisTemplate 序列化@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();// 为 String 类型 key 设置序列化器template.setKeySerializer(new StringRedisSerializer());// 为 String 类型 value 设置序列化器template.setValueSerializer(new GenericJackson2JsonRedisSerializer());// 为 Hash 类型 key 设置序列化器template.setHashKeySerializer(new StringRedisSerializer());// 为 Hash 类型 value 设置序列化器template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());template.setConnectionFactory(redisConnectionFactory);return template;}// 重写 Cache 序列化@Beanpublic RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory());RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()// 设置默认过期时间 30 min.entryTtl(Duration.ofMinutes(30))// 设置 key 和 value 的序列化.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getKeySerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));return new RedisCacheManager (redisCacheWriter, redisCacheConfiguration);}}

4)增加缓存注解

5) 接口实现类增加缓存注解

    @Cacheable(cacheNames = "orderService:order:select")public Order selectOrderById(Long orderId) {    // 调用list// 1.查询订单Order order = orderMapper.findById(orderId);// 2.利用RestTemplate发起http请求,查询用户// 2.1.url路径String url = "http://userservice/user/list";// 2.2.发送http请求,实现远程调用List<User> userList = restTemplate.getForObject(url, List.class);assert userList != null;order.setUser(userList);return order;}

6)结果

2. 请求合并实现

1). pom文件添加依赖

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

2). 在实现类进行请求合并

 3)开启熔断注解

@EnableCaching
// 开启熔断器注解 2 选 1,@EnableHystrix 封装了 @EnableCircuitBreaker
// @EnableHystrix
@EnableCircuitBreaker
@EnableFeignClients(clients = UserClient.class,defaultConfiguration = DefaultFeignConfiguration.class)
public class OrderApplication {

4)模拟同时发起多个请求

    public Order queryOrderById(Long orderId) {// 1.查询订单Order order = orderMapper.findById(orderId);// 2.利用RestTemplate发起http请求,查询用户// 2.1.url路径String url = "http://userservice/user/1";String url2 = "http://userservice/user/2";String url3 = "http://userservice/user/3";String url4 = "http://userservice/user/4";String url5 = "http://userservice/user/5";// 2.2.发送http请求,实现远程调用Future<User> user = (Future<User>) restTemplate.getForObject(url, User.class);Future<User> user2 = (Future<User>) restTemplate.getForObject(url2, User.class);Future<User> user3 = (Future<User>) restTemplate.getForObject(url3, User.class);Future<User> user4 = (Future<User>) restTemplate.getForObject(url4, User.class);Future<User> user5 = (Future<User>) restTemplate.getForObject(url5, User.class);// 3.封装user到OrderList<User> userList = new ArrayList<>(1);try {userList.add(user.get());userList.add(user2.get());userList.add(user3.get());userList.add(user4.get());userList.add(user5.get());} catch (InterruptedException e) {throw new RuntimeException(e);} catch (ExecutionException e) {throw new RuntimeException(e);}order.setUser(userList);// 4.返回return order;}

3.线程池隔离

1)介绍

对调用的接口进行隔离,一个接口因为并发过高瘫痪时,掉用的另一个接口不会瘫痪

2)优点

  • 使用线程池隔离可以安全「隔离依赖的服务」,减少所依赖服务发生故障时的影响面。比如 A 服务发生异常,导致请求大量超时,对应的线程池被打满,这时并不影响 C、D 服务的调用。

  • 当失败的服务再次变得可用时,线程池将清理并立即恢复,而不需要一个长时间的恢复。

  • 独立的线程池「提高了并发性」

3)缺点

  • 请求在线程池中执行,肯定会带来任务调度、排队和上下文切换带来的 CPU 开销。

  • 因为涉及到跨线程,那么就存在 ThreadLocal 数据的传递问题,比如在主线程初始化的 ThreadLocal 变量,在线程池线程中无法获取。

4)代码示例

   // 声明需要服务容错的方法// 线程池隔离@HystrixCommand(groupKey = "order-userService-listPool",// 服务名称,相同名称使用同一个线程池commandKey = "getList",// 接口名称,默认为方法名threadPoolKey = "order-userService-listPool",// 线程池名称,相同名称使用同一个线程池commandProperties = {// 超时时间,默认 1000ms@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")},threadPoolProperties = {// 线程池大小@HystrixProperty(name = "coreSize", value = "6"),// 队列等待阈值(最大队列长度,默认 -1)@HystrixProperty(name = "maxQueueSize", value = "100"),// 线程存活时间,默认 1min@HystrixProperty(name = "keepAliveTimeMinutes", value = "2"),// 超出队列等待阈值执行拒绝策略@HystrixProperty(name = "queueSizeRejectionThreshold", value = "100")}, fallbackMethod = "selectUserListFallback")public List<User> getList() {return userMapper.getAll();}// 托底数据private List<User> selectUserListFallback() {System.out.println("-----获得托底数据-----");return Arrays.asList(new User(1L, "A", "地点1"),new User(2L, "B", "地点2"),new User(3L, "C", "地点3"));}

4. 信号量隔离

1)介绍

每次调用线程,当前请求通过计数信号量进行限制,当信号量大于了最大请求数 maxConcurrentRequests 时,进行限制,调用 fallback 接口快速返回。信号量的调用是同步的,也就是说,每次调用都得阻塞调用方的线程,直到结果返回。这样就导致了无法对访问做超时(只能依靠调用协议超时,无法主动释放)

2)代码示例

// 声明需要服务容错的方法// 信号量隔离@HystrixCommand(commandProperties = {// 超时时间,默认 1000ms@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000"),// 信号量隔离@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY,value = "SEMAPHORE"),// 信号量最大并发,调小一些方便模拟高并发@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS,value = "6")}, fallbackMethod = "selectUserListFallback")public List<User> getList() {return userMapper.getAll();}// 托底数据private List<User> selectUserListFallback() {System.out.println("-----获得托底数据-----");return Arrays.asList(new User(1L, "A", "地点1"),new User(2L, "B", "地点2"),new User(3L, "C", "地点3"));}

3) 线程池颗粒与信号隔离对比

隔离方式是否支持超时是否支持熔断隔离原理是否是异步调用资源消耗
线程池隔离支持支持每个服务单独用线程池支持同步或异步
信号量隔离不支持支持通过信号量的计数器同步调用,不支持异步

5.服务熔断

1)介绍

服务熔断是一种机制,用于在出现服务故障、超时或异常情况时,阻止请求继续发送到故障的服务上。当达到一定的失败阈值时,熔断器会打开,后续的请求将被快速失败,而不再去调用故障的服务。当故障情况得到修复后,熔断器会尝试关闭,恢复对服务的正常调用。

2)调用

在上面的代码执行fallbackMethod就会执行服务熔断

 其他

除了上述功能,Hystrix还有实时监控、指标收集、恢复等功能,这里会留到后面的时候进行更新,大家如果现在要学习的话,可以从官网或其它地方得到相关的介绍和代码

 参考文献:

GitHub - Netflix/Hystrix: Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable. - GitHub - Netflix/Hystrix: Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.https://github.com/Netflix/Hystrix

 最后,

后续文章会陆续更新,希望文章对你有所帮助..!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/30309.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VGG16模型详解

VGG16模型详解 0、VGG16介绍 VGG16是一种深度卷积神经网络&#xff0c;由牛津大学的研究团队于2014年开发。 VGG16在2014年的ImageNet Large Scale Visual Recognition Challenge (ILSVRC) 竞赛中取得了显著的成绩。它在图像分类任务中获得了当年的第二名&#xff0c;其准确…

matplotlib 笔记 plt.grid

用于添加网格线 主要参数 visible 布尔值&#xff0c;True表示画网格 which表示要显示的刻度线类型&#xff0c;可以是 major&#xff08;主刻度&#xff09;或 minor&#xff08;次刻度&#xff09;&#xff0c;或者同时显示&#xff08;both&#xff09;alpha 透明度 …

音视频--视频数据传输

参考文献 H264码流RTP封装方式详解&#xff1a;https://blog.csdn.net/water1209/article/details/126019272H264视频传输、编解码----RTP协议对H264数据帧拆包、打包、解包过程&#xff1a; https://blog.csdn.net/wujian946110509/article/details/79129338H264之NALU解析&a…

【Redis】初学Redis

目录 使用Redisyum安装redis启动redis操作redis设置远程连接 Redis路线Redis 使用Redis yum安装redis 使用命令&#xff0c;直接将Redis安装到linux服务器&#xff1a; yum -y install redis启动redis redis-server /etc/redis.conf &操作redis redis-cli设置远程连接…

Shopee虾皮买家号注册时需要注意什么问题

虾皮是一家在线购物平台&#xff0c;如果您打算在虾皮上注册一个买家账号&#xff0c;以下是一些需要注意的问题&#xff1a; 账号安全&#xff1a;确保您选择一个安全的密码&#xff0c;并定期更改密码&#xff0c;以保护您的账号免受未经授权的访问。 个人信息&#xff1a;…

网页版Java(Spring/Spring Boot/Spring MVC)五子棋项目(四)对战模块

网页版Java&#xff08;Spring/Spring Boot/Spring MVC&#xff09;五子棋项目&#xff08;四&#xff09;对战模块 一、约定前后端交互接口1. 建立连接接口2. 针对落子的请求和响应 二、实现前端页面三、实现后端1. 当用户进入房间&#xff0c;更新用户状态 OnlineUserManager…

Linux mysql5.7开启 binlog

查看 mysql是否开启 binlog。 查看命令&#xff1a; show variables like %log_bin%; log_bin OFF 是关闭的状态。 编辑my.cnf配置文件 vim /etc/my.cnf 默认的配置文件内容&#xff1a; 增加下面内容 server_id 1 binlog_format ROW log-bin mysql_log_bin 重启mysq…

木马免杀(篇一)基础知识学习

木马免杀&#xff08;篇一&#xff09;基础知识学习 ———— 简单的木马就是一个 exe 文件&#xff0c;比如今年hw流传的一张图&#xff1a;某可疑 exe 文件正在加载。当然木马还可能伪造成各式各样的文件&#xff0c;dll动态链接库文件、lnk快捷方式文件等&#xff0c;也可能…

MySQL单表查询

单表查询 素材&#xff1a; 表名&#xff1a;worker-- 表中字段均为中文&#xff0c;比如 部门号 工资 职工号 参加工作 等 CREATE TABLE worker ( 部门号 int(11) NOT NULL, 职工号 int(11) NOT NULL, 工作时间 date NOT NULL, 工资 float(8,2) NOT NULL, 政治面貌 varch…

Spring MVC项目概述及创建

Spring MVC项目概述及创建 1.什么是Spring MVC Spring MVC是基于SevletAPI的原始Web框架。Spring MVC项目也叫做SpringWeb项目。 它是在springboot项目中引入了web框架&#xff0c;原本的spring项目不具备网络通信能力&#xff0c;而spring mvc允许http响应&#xff0c;当用…

无刷电机控制

无刷电机控制 特点: 线圈不动&#xff0c;磁极转动电子换向方式消除了有刷电机的缺点单位质量/功率转矩大驱动较复杂

徐雷,太委屈

文 | 螳螂观察 作者 | 仲夏 自3月8日上线以来&#xff0c;京东百亿补贴已整整5个月。相比首月投入10个亿&#xff0c;京东百亿补贴如今的存在显得尴尬与鸡肋。 眼看百亿补贴难以肩负发力下沉市场、扛起低价策略的重任&#xff0c;京东近期又将“京喜拼拼”更名“京东拼拼”卷…

FFmpeg 编码详细流程

介绍 FFmpeg的 libavcodec 模块完成音视频多媒体的编解码模块。FFmpeg 本身不具有音视频编码的功能和底层能力&#xff0c;只是对各类第三方的编码器API 进行封装调用。老版本的 FFmpeg 将avcodec_encode_video2()作为视频的解码函数 API&#xff0c;将avcodec_encode_audio2(…

(学习笔记-进程管理)进程间有哪些通信方式?

每个进程的用户地址空间都是独立的&#xff0c;一般而言是不能互相访问的&#xff0c;但内核空间时每个进程都共享的&#xff0c;所以进程之间要通信必须通过内核 管道 在Linux命令中 [ | ] 这个竖线就是一个管道。 $ ps auxf | grep mysql 它的功能是讲前一个命令&#xf…

如何使用 AT+WEBSERVER 指令实现自定义的 Webserver html 网页配网

开启 AT 固件中的 Webserver 指令和 FS 指令支持 乐鑫官网发布的默认通用 AT 固件不支持 webserver 配网功能&#xff0c; 需要用户自己搭建 esp-at 环境&#xff0c;并在 sdkconfig 中开启 webserver AT 指令 和 FS 指令的支持&#xff0c; 如下图所示&#xff1a; 测试 AT 固…

java中try-with-resources自动关闭io流

文章目录 java中try-with-resources自动关闭io流0 简要说明try-with-resources java中try-with-resources自动关闭io流 0 简要说明 在传统的输入输出流处理中&#xff0c;我们一般使用的结构如下所示&#xff0c;使用try - catch - finally结构捕获相关异常&#xff0c;最后不…

Mybatis-plus的使用

1、介绍 2、开发方式 3、MyBatisPlus-01-MybatisPlus入门案例_哔哩哔哩_bilibili&#xff0c;105,3.55分钟 Mybatis使用流程可以看这&#xff1a; 4、創建一張表&#xff1a; ​ 5、创建一个SpringBoot工程 ​ ​ 6、版本调成8 ​ 7、这里之只做数据层&#xff0c;不弄we…

SpringBoot 依赖管理

Spring Boot 依赖管理 在 Spring Boot 中&#xff0c;依赖管理是通过 Maven 或 Gradle 进行管理的。Spring Boot 提供了一种简化的方式来管理和引入依赖项&#xff0c;使得构建和管理项目变得更加容易。下面是一些关于 Spring Boot 依赖管理的基本信息和示例&#xff1a; 使用…

如何系统的学习单片机?

一、学习单片机需要的一些基础知识 &#xff08;1&#xff09;要具有一些模电、数电的知识&#xff08;不一定要精通&#xff0c;但基本至少要知道&#xff09; &#xff08;2&#xff09;具备C语言基础&#xff0c;有基础就可以入门了。数据结构、设计模式、汇编这些&#x…

管理类联考——逻辑——论证逻辑——汇总篇——真题和典例——假设

通用方法/没有特点 方法关系 199-2013-1-41——方法关系——方法有效或方法可行 新近一项研究发现&#xff0c;海水颜色能够让飓风改变方向&#xff0c;也就是说&#xff0c;如果海水变色&#xff0c;飓风的移动路径也会变向。这也就意味着科学家可以根据海水的“脸色”判断…