Redisson分布式限流器
Redisson分布式限流器
- 一、使用
- 1.1、方法
- 1.2、示例
- 二、原理
- 2.1、设置限流器
- 2.2、获取令牌
- 三、总结
最近有需求在做分布式限流,调研的限流框架大概有:
1、spring cloud gateway集成redis限流,但属于网关层限流
2、阿里Sentinel,功能强大、带监控平台
3、srping cloud hystrix,属于接口层限流,提供线程池与信号量两种方式
4、其他:redission、手撸代码
一、使用
1.1、方法
使用很简单、主要代码如下:
// 1、 声明一个限流器
RRateLimiter rateLimiter = redissonClient.getRateLimiter(key);
// 2、 设置速率,5秒中产生3个令牌
rateLimiter.trySetRate(RateType.OVERALL, 3, 5, RateIntervalUnit.SECONDS);
// 3、 试图获取一个令牌,获取到返回true
rateLimiter.tryAcquire(1)
- 创建限流器
/*** Returns rate limiter instance by name* * @param name of rate limiter* @return RateLimiter object*/
RRateLimiter getRateLimiter(String name);
- 设置限流参数
/*** Initializes RateLimiter's state and stores config to Redis server.* * @param mode - rate mode* @param rate - rate* @param rateInterval - rate time interval* @param rateIntervalUnit - rate time interval unit* @return true if rate was set and false otherwise*/
boolean trySetRate(RateType mode, long rate, long rateInterval, RateIntervalUnit rateIntervalUnit);
trySetRate
用于设置限流参数。其中 RateType 包含 OVERALL
和 PER_CLIENT
两个枚举常量,分别表示全局限流和单机限流。后面三个参数表明了令牌的生成速率,即每 rateInterval
生成 rate
个令牌,rateIntervalUnit
为 rateInterval
的时间单位。
- 获取令牌
/*** Acquires a specified permits from this RateLimiter, * blocking until one is available.** Acquires the given number of permits, if they are available * and returns immediately, reducing the number of available permits * by the given amount.* * @param permits the number of permits to acquire*/
void acquire(long permits);/*** Acquires the given number of permits only if all are available* within the given waiting time.** Acquires the given number of permits, if all are available and returns immediately,* with the value true, reducing the number of available permits by one.** If no permit is available then the current thread becomes* disabled for thread scheduling purposes and lies dormant until* the specified waiting time elapses.** If a permits is acquired then the value true is returned.** If the specified waiting time elapses then the value false* is returned. If the time is less than or equal to zero, the method* will not wait at all.** @param permits amount* @param timeout the maximum time to wait for a permit* @param unit the time unit of the timeout argument* @return true if a permit was acquired and false* if the waiting time elapsed before a permit was acquired*/
boolean tryAcquire(long permits, long timeout, TimeUnit unit);
acquire
和 tryAcquire
均可用于获取指定数量的令牌,不过 acquire
会阻塞等待,而 tryAcquire
会等待 timeout
时间,如果仍然没有获得指定数量的令牌直接返回 false
。
1.2、示例
<!-- 添加Redisson依赖 -->
<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.XX.X</version> <!-- 替换为你使用的Redisson版本 -->
</dependency>
import org.redisson.Redisson;
import org.redisson.api.RRateLimiter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;public class RedissonRateLimiterExample {public static void main(String[] args) {// 1. 配置RedissonClientConfig config = new Config();config.useSingleServer().setAddress("redis://127.0.0.1:6379");RedissonClient redisson = Redisson.create(config);// 2. 获取RRateLimiter对象RRateLimiter rateLimiter = redisson.getRateLimiter("myRateLimiter");// 3. 设置限流策略,例如每秒钟不超过10个请求rateLimiter.trySetRate(RateType.OVERALL, 10, 1, RateIntervalUnit.SECONDS);// 4. 尝试获取许可证,超时时间为500毫秒if (rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS)) {// 如果获取到许可证,执行业务逻辑System.out.println("许可证获取成功,执行业务逻辑");} else {// 如果未获取到许可证,执行拒绝策略System.out.println("许可证获取失败,业务逻辑拒绝执行");}// 5. 关闭Redisson客户端redisson.shutdown();}
}
在这个例子中,我们配置了一个名为myRateLimiter
的限流器,允许每秒钟10个请求的通过率。通过tryAcquire
方法尝试获取许可证,如果在指定的时间内获取到许可证,则执行业务逻辑,否则执行拒绝策略。最后,不要忘了关闭Redisson
客户端以释放资源。
二、原理
Redisson 的 RRateLimiter
基于令牌桶实现,令牌桶的主要特点如下:
- 令牌以固定速率生成。
- 生成的令牌放入令牌桶中存放,如果令牌桶满了则多余的令牌会直接丢弃,当请求到达时,会尝试从令牌桶中取令牌,取到了令牌的请求可以执行。
- 如果桶空了,那么尝试取令牌的请求会被直接丢弃。
2.1、设置限流器
trySetRate()
方法,通过下面 Lua 脚本设置限流器的相关参数,底层源码如下:
@Overridepublic RFuture<Boolean> trySetRateAsync(RateType type, long rate, long rateInterval, RateIntervalUnit unit) {return commandExecutor.evalWriteNoRetryAsync(getRawName(), LongCodec.INSTANCE, RedisCommands.EVAL_BOOLEAN,"redis.call('hsetnx', KEYS[1], 'rate', ARGV[1]);"+ "redis.call('hsetnx', KEYS[1], 'interval', ARGV[2]);"+ "return redis.call('hsetnx', KEYS[1], 'type', ARGV[3]);",Collections.singletonList(getRawName()), rate, unit.toMillis(rateInterval), type.ordinal());}
举个例子,更容易理解:
比如下面这段代码,5秒中产生3个令牌,并且所有实例共享(RateType.OVERALL所有实例共享、RateType.CLIENT单实例端共享)
trySetRate(RateType.OVERALL, 3, 5, RateIntervalUnit.SECONDS);
那么redis中就会设置3个参数:
hsetnx,key,rate,3hsetnx,key,interval,5hsetnx,key,type,0
2.2、获取令牌
tryAcquire(1)
方法,获取令牌则是通过以下的 Lua 脚本实现的,底层源码如下:
-- 速率
local rate = redis.call("hget", KEYS[1], "rate")
-- 时间区间(ms)
local interval = redis.call("hget", KEYS[1], "interval")
local type = redis.call("hget", KEYS[1], "type")
assert(rate ~= false and interval ~= false and type ~= false, "RateLimiter is not initialized")-- {name}:value 分析后面的代码,这个key记录的是当前令牌桶中的令牌数
local valueName = KEYS[2]-- {name}:permits 这个key是一个zset,记录了请求的令牌数,score则为请求的时间戳
local permitsName = KEYS[4]-- 单机限流才会用到,集群模式不用关注
if type == "1" thenvalueName = KEYS[3]permitsName = KEYS[5]
end-- 原版本有bug(https://github.com/redisson/redisson/issues/3197),最新版将这行代码提前了
-- rate为1 arg1这里是 请求的令牌数量(默认是1)。rate必须比请求的令牌数大
assert(tonumber(rate) >= tonumber(ARGV[1]), "Requested permits amount could not exceed defined rate")-- 第一次执行这里应该是null,会进到else分支
-- 第二次执行到这里由于else分支中已经放了valueName的值进去,所以第二次会进if分支
local currentValue = redis.call("get", valueName)
if currentValue ~= false then-- 从第一次设的zset中取数据,范围是0 ~ (第二次请求时间戳 - 令牌生产的时间)-- 可以看到,如果第二次请求时间距离第一次请求时间很短(小于令牌产生的时间),那么这个差值将小于上一次请求的时间,取出来的将会是空列表。反之,能取出之前的请求信息-- 这里作者将这个取出来的数据命名为expiredValues,可认为指的是过期的数据local expiredValues = redis.call("zrangebyscore", permitsName, 0, tonumber(ARGV[2]) - interval)local released = 0-- lua迭代器,遍历expiredValues,如果有值,那么released等于之前所有请求的令牌数之和,表示应该释放多少令牌for i, v in ipairs(expiredValues) dolocal random, permits = struct.unpack("fI", v)released = released + permitsend-- 没有过期请求的话,released还是0,这个if不会进,有过期请求才会进if released > 0 then-- 移除zset中所有元素,重置周期redis.call("zrem", permitsName, unpack(expiredValues))currentValue = tonumber(currentValue) + releasedredis.call("set", valueName, currentValue)end-- 这里简单分析下上面这段代码:-- 1. 只有超过了1个令牌生产周期后的请求,expiredValues才会有值。-- 2. 以rate为3举例,如果之前发生了两个请求那么现在released为2,currentValue为1 + 2 = 3-- 以此可以看到,redisson的令牌桶放令牌操作是通过请求时间窗来做的,如果距离上一个请求的时间已经超过了一个令牌生产周期时间,那么令牌桶中的令牌应该得到重置,表示生产rate数量的令牌。-- 如果当前令牌数 < 请求的令牌数if tonumber(currentValue) < tonumber(ARGV[1]) then-- 从zset中找到距离当前时间最近的那个请求,也就是上一次放进去的请求信息local nearest = redis.call('zrangebyscore', permitsName, '(' .. (tonumber(ARGV[2]) - interval), tonumber(ARGV[2]), 'withscores', 'limit', 0, 1); local random, permits = struct.unpack("fI", nearest[1])-- 返回 上一次请求的时间戳 - (当前时间戳 - 令牌生成的时间间隔) 这个值表示还需要多久才能生产出足够的令牌return tonumber(nearest[2]) - (tonumber(ARGV[2]) - interval)else-- 如果当前令牌数 ≥ 请求的令牌数,表示令牌够多,更新zsetredis.call("zadd", permitsName, ARGV[2], struct.pack("fI", ARGV[3], ARGV[1]))-- valueName存的是当前总令牌数,-1表示取走一个redis.call("decrby", valueName, ARGV[1])return nilend
else-- set一个key-value数据 记录当前限流器的令牌数redis.call("set", valueName, rate)-- 建了一个以当前限流器名称相关的zset,并存入 以score为当前时间戳,以lua格式化字符串{当前时间戳为种子的随机数、请求的令牌数}为value的值。-- struct.pack第一个参数表示格式字符串,f是浮点数、I是长整数。所以这个格式字符串表示的是把一个浮点数和长整数拼起来的结构体。我的理解就是往zset里记录了最后一次请求的时间戳和请求的令牌数redis.call("zadd", permitsName, ARGV[2], struct.pack("fI", ARGV[3], ARGV[1]))-- 从总共的令牌数 减去 请求的令牌数。redis.call("decrby", valueName, ARGV[1])return nil
end
总结一下,redisson用了zset
来记录请求的信息,这样可以非常巧妙的通过比较score,也就是请求的时间戳,来判断当前请求距离上一个请求有没有超过一个令牌生产周期。如果超过了,则说明令牌桶中的令牌需要生产,之前用掉了多少个就生产多少个,而之前用掉了多少个令牌的信息也在zset中保存了。
然后比较当前令牌桶中令牌的数量,如果足够多就返回了,如果不够多则返回到下一个令牌生产还需要多少时间。这个返回值特别重要。
三、总结
redission
分布式限流采用令牌桶思想和固定时间窗口,trySetRate
方法设置桶的大小,利用redis key
过期机制达到时间窗口目的,控制固定时间窗口内允许通过的请求量。
随着互联网的快速发展,高并发场景下的性能问题愈发凸显。特别是在处理大量数据的定时任务中,如何防止多机并发对下游服务造成过大压力成为了一个亟待解决的问题。传统的单机限流方法虽然能够在一定程度上控制请求量,但在分布式环境下往往无法达到预期效果。这时,Redisson
分布式限流的出现为我们提供了一种新的解决方案。
Redisson
是一个在Redis
能力上构建的开发库,它不仅支持Redis
的基础操作,还封装了布隆过滤器、分布式锁、限流器等工具。其中,RRateLimiter
是Redisson
实现分布式限流的核心组件。它基于Redis
的分布式特性,能够在多台机器之间协同工作,实现对请求量的精确控制。
那么,Redisson分布式限流的实现原理是什么呢?
首先,我们需要了解Redisson
分布式限流的核心思想:通过Redis
的原子操作来保证多个节点之间的限流策略一致。RRateLimiter
内部使用了Redis
的Lua
脚本功能,确保了在执行限流操作时的原子性。
其次,RRateLimiter
采用了滑动窗口算法来计算请求速率。在滑动窗口内,RRateLimiter
会记录通过的请求数量,并根据窗口大小和时间间隔来判断是否超出限流阈值。当请求速率超过阈值时,后续请求将被拒绝,从而实现限流效果。
此外,Redisson
还提供了丰富的限流策略,如固定窗口限流、漏桶算法限流等。这些策略可以根据具体场景进行灵活选择,以满足不同业务需求。
在实际应用中我们可以通过以下步骤来使用Redisson
实现分布式限流:
- 引入
Redisson
依赖:首先,我们需要在项目中引入Redisson
的依赖,以便能够使用其提供的分布式限流功能。 - 创建
Redisson
客户端:然后,我们需要创建一个Redisson
客户端实例,用于与Redis
服务器进行通信。 - 配置
RRateLimiter
:接下来,我们需要配置RRateLimiter
的参数,包括限流阈值、时间窗口大小等。这些参数将决定限流策略的具体实施。 - 使用
RRateLimiter
进行限流:最后,在业务代码中,我们可以使用RRateLimiter
实例来进行限流操作。当接收到请求时,先通过RRateLimiter
判断是否超出限流阈值,若超出则拒绝请求,否则继续处理。
通过以上步骤,我们可以轻松地在分布式环境下实现高效的限流功能。Redisson
分布式限流不仅解决了多机并发对下游服务造成过大压力的问题,还提供了灵活的限流策略和丰富的功能支持。在实际应用中,我们可以根据具体需求选择合适的限流策略,并结合Redisson
的其他功能来提升系统的性能和稳定性。
总之,Redisson
分布式限流是一种高效、灵活且易于实现的解决方案,对于处理高并发场景下的性能瓶颈问题具有重要意义。通过深入了解其实现原理和应用方法,我们可以更好地利用Redisson
库来优化系统性能,提升用户体验。
参考地址:
https://www.cnblogs.com/guoziyi/p/18266627
https://github.com/oneone1995/blog/issues/13
https://blog.csdn.net/qq_43686863/article/details/135634098
相关文章:
Redisson分布式限流器
Redisson分布式限流器 一、使用1.1、方法1.2、示例 二、原理2.1、设置限流器2.2、获取令牌 三、总结 最近有需求在做分布式限流,调研的限流框架大概有: 1、spring cloud gateway集成redis限流,但属于网关层限流 2、阿里Sentinel,功能强大、带监控平台 …...
xvisor调试记录
Xvisor是一种开源hypervisor,旨在提供完整、轻量、移植且灵活的虚拟化解决方案,属于type-1类型的虚拟机,可以直接在裸机上启动。 启动xvisor步骤: 1、搭建riscv编译环境 首先从github上下载riscv-gnu-toolchain很费劲,建议直接从国内的源下载 git clone https://gitee…...
Android问题记录 - Inconsistent JVM-target compatibility detected for tasks
文章目录 前言开发环境问题描述问题分析解决方案补充内容最后 前言 前段时间升级Android Studio后修复了一堆问题,详情请看:Android问题记录 - 适配Android Studio Ladybug/Java 21/AGP 8.0(持续更新)。我以为问题已经全部解决了…...
【Python系列】使用 `psycopg2` 连接 PostgreSQL 数据库
???欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老…...
家庭路由器跑PCND的优点
在当今数字化的时代,PCDN(Peer-to-Peer Content Delivery Network)技术逐渐走入人们的视野,有人考虑在家庭路由器上跑PCDN,下面是优点: 1.资源利用最大化 家庭网络在很多时候存在闲置的带宽和计算资源。通…...
ASP.NET Core API + MySql
环境 数据库: mysql8.0 后端: vs2022 ASP.NET Core API .net 8 前端: Hbuilderx bootstrap 5.3.0 jquery v3.7.1 bootstrap-table 1.23.5 创建项目 添加资源包 AutoMapper Microsoft.EntityFrameworkCore.Tools 8.0.0 Pomelo.EntityFramew…...
torch.optim.lr_scheduler.ReduceLROnPlateau
torch.optim.lr_scheduler.ReduceLROnPlateau 是 PyTorch 中的一种学习率调度器,主要用于在模型训练过程中根据某些指标(如验证损失)动态调整学习率。它是一种基于性能指标动态调整学习率的策略,而不是预定义的固定时间调整。 主要…...
Dubbo
官方文档: Java SDK 手册 | Apache Dubbo 一 RPC及Dubbo 1 什么是RPC dubbo是⼀款⾼性能的rpc框架。什么是rpc呢? rpc是⼀种协议:是⼀种远程过程调⽤(remote procudure call)协议 rpc协议是在应⽤层之上的协议&…...
算法1(蓝桥杯18)-删除链表的倒数第 N 个节点
问题: 给你一个链表,删除链表的倒数第 n 个节点,并且返回链表的头节点。 输入:head 1 -> 2 -> 3 -> 4 -> 5 -> null, n 2 输出:1 -> 2 -> 3 -> 5 -> null输入:head 1 ->…...
SEC_ASA 第一天作业
拓扑: 实验需求: 注意:在开始作业之前必须先读“前言”,以免踩坑!!!(☞敢点我试试) 按照拓扑图配置VLAN连接。 注意:ASA防火墙的 Gi0/1口需要起子接口&#x…...
《C语言程序设计现代方法》note-8 指针和数组的关系
文章目录 助记提要12章 指针和数组12.1 指针的算术运算12.2 指针用于数组处理结合使用*和运算符 12.3 数组名作为指针数组名可以用作指针指针也可以当做数组名数组型实参 12.4 指针和多维数组处理每个元素处理行处理列多维数组名做指针 12.5 指针和变长数组 助记提要 指针支持…...
安科瑞电能质量治理产品在分布式光伏电站的应用-安科瑞黄安南
1.概述 随着全球对可再生能源需求的增加,分布式光伏电站的建设和发展迅速。然而,分布式光伏电站的运行过程中面临着一系列问题,比如导致企业关口计量点功率因数过低、谐波污染等。这些问题不仅影响光伏电站自身的运行效率,还会对…...
JavaScript 的原生数组方法和 Vue 的响应式系统之间的差异
发现宝藏 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。【宝藏入口】。 JavaScript 的原生数组方法和 Vue 的响应式系统之间的差异主要体现在 Vue 如何追踪数组的变化,以及 Vue 如何处理数组…...
项目组件框架介绍[bRPC]
文章目录 前言bRPC安装bRPC的简单使用protobuf简单使用Echo服务远程调用Echo服务 与etcd关联 前言 bRPC是百度开源的一款工业级RPC框架,功能强大, 常用于搜索、存储、机器学习、广告、推荐等高性能系统。 bRPC安装 使用源码安装即可, 在安装前要确认依赖 sudo apt…...
基于MobileNetV3架构动物声音分类识别与应用系统实现
1.摘要 本文主要实现了一个基于MobileNetV3架构的深度学习模型用于动物声音分类识别任务。该MobileNetV3是一种轻量级的卷积神经网络,旨在实现高效分类性能,本章在猫、狗、海豚等三个动物声音(.wav数据集)上进行了训练和测试,即在…...
ragflow连ollama时出现的Bug
ragflow和ollama连接后,已经添加了两个模型但是ragflow仍然一直warn:Please add both embedding model and LLM in Settings > Model providers firstly.这里可能是我一开始拉取的镜像容器太小,容不下当前添加的模型,导…...
[大数据]Hudi编译集成
1. 编译环境准备 相关组件版本如下: Hadoop3.3.1Hive3.1.3Flink1.13.6,scala-2.12Spark3.3.1,scala-2.12 1)安装Maven (1)上传apache-maven-3.6.1-bin.tar.gz到/opt/software目录,并解压更名…...
rk3588-ubuntu22.04系统网关实现路由器功能:
rk3588-ubuntu22.04系统网关实现路由器功能: 场景需求描述: 需求背景: 场景一:通过网线eth0/(路由器wlan0)访问外网: 如果网关 和 设备所处的环境可以通过网线联网或者路由器联网,那么不需要将网关配置成…...
Python部署教程-Python项目怎样在Pycharm中运行
大家好,我是程序员徐师兄,今天为大家带来的是Python部署教程-Python项目怎样在Pycharm中运行。Python安装部署教程,包括软件的下载,软件的安装。该系统采用 Python语言开发,flask、Django 框架,MySql 作为数…...
代码随想录算法训练营第51期第14天 | 226. 翻转二叉树、101. 对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
226. 翻转二叉树 226. 翻转二叉树https://leetcode.cn/problems/invert-binary-tree/1.昨天忘了声明,如果都用C的话,我大概率写不完,所以思路方面,我可能考虑用pyhon先写,后续会用文心一言转换成C 2.这里可以直接用层…...
C/C++常见符号与运算符
C/C常见符号与运算符对照表 符号用法与意义与Java类比:在条件运算符中 (cond ? x : y) 表示条件为假的分支;在 switch-case 中如 case 1:表示标签结束点;在自定义标签如 label: 中用于 goto 跳转Java中? :三元运算相同;switch-case中也有:…...
maven报错“找不到符号“
问题 springboot项目 maven编译打包过程,报错"找不到符号" 解决 很多网上方法都试过,都没用 换jdk,把17->21...
开源数据同步中间件(Dbsyncer)简单玩一下 mysql to mysql 的增量,全量配置
一、什么是Dbsyncer 1、介绍 Dbsyncer是一款开源的数据同步中间件,提供MySQL、Oracle、SqlServer、PostgreSQL、Elasticsearch(ES)、Kafka、File、SQL等同步场景,支持上传插件自定义同步转换业务,提供监控全量和增量数据统计图、应用性能预警…...
【Kubernetes理论篇】容器集群管理系统Kubernetes(K8S)
Kubernetes集群部署基本管理实战 这么好的机会,还在等什么! 01、Kubernetes 概述 K8S是什么 K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,写”。不如整个缩写 K8s 作为缩写的结果…...
鸿蒙ArkTS语言基础语法详解
文章目录 鸿蒙ArkTS语言基础语法详解一、引言二、ArkTS语言概述1. ArkTS语言特点2. TypeScript基础语法2.1 类型注解2.2 接口2.3 泛型2.4 类的继承2.5 类的访问修饰符 三、ArkTS的基本组成3.1 装饰器3.2 UI描述3.3 自定义组件3.4 系统组件3.5 属性方法和事件方法 四、自定义组件…...
两条链表相同位数相加
优质博文IT-BLOG-CN 一、题目 给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这…...
C语言单元总结
黑色加粗表示刷题刷到这样的题 红色加粗表示可能重要 单元一 程序设计宏观认识 C语言程序框架 C语言程序最基本的程序框架由两部分构成,分别是 1) 编译预处理 2) 函数组 C语言程序构成 C程序最大的特点就是所有的程序都是用函数来装配的,函数是构成…...
【Golang】Go语言编程思想(六):Channel,第二节,使用Channel等待Goroutine结束
使用 Channel 等待任务结束 首先回顾上一节 channel 这一概念介绍时所写的代码: package mainimport ("fmt""time" )func worker(id int, c chan int) {for n : range c {fmt.Printf("Worker %d received %c\n",id, n)} }func crea…...
Oracle RAC开启和关闭日志归档Log Archive
一、开启日志归档模式 # srvctl stop database -d <DB_NAME> # srvctl start instance -d <DB_NAME> -i <INSTANCE_NAME> -o mount # 停止 RAC 数据库的所有实例: [oracleora19crac1:/home/oracle]$srvctl stop database -d orcl # 启动第一个实…...
今天调了个转速的小BUG
同事说转速表有个bug,转速停止后,继电器没有恢复到初始状态。若停止之前是报警,继电器吸合,则停止后继电器还是吸合。我心想不会啊,这软件都弄了好几年了,一直也没出现过状况。 经过与调试同事的沟通&#…...
RabbitMQ七种工作模式之 RPC通信模式, 发布确认模式
文章目录 六. RPC(RPC通信模式)客户端服务端 七. Publisher Confirms(发布确认模式)1. Publishing Messages Individually(单独确认)2. Publishing Messages in Batches(批量确认)3. Handling Publisher Confirms Asynchronously(异步确认) 六. RPC(RPC通信模式) 客⼾端发送消息…...
【Python教程】Python3基础篇之基础语法
博主介绍:✌全网粉丝21W+,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物联网、机器学习等设计与开发。 感兴趣的可…...
`yarn list --pattern element-ui` 是一个 Yarn 命令,用于列出项目中符合指定模式(`element-ui`)的依赖包信息
文章目录 命令解析:功能说明:示例输出:使用场景: yarn list --pattern element-ui 是一个 Yarn 命令,用于列出项目中符合指定模式( element-ui)的依赖包信息。 命令解析: yarn list…...
使用docker-compose安装Milvus向量数据库及Attu可视化连接工具
首先确保系统已经安装上了docker 然后去https://github.com/docker/compose/releases/下载安装docker-compose 跟随自己下系统和服务器情况下载 上传到服务器 mv docker-compose-linux-aarch64 docker-compose chmod x docker-compose2.dockr-compose命令 docker-compose …...
IoTDB Allocate WAL Buffer Fail Because out of memory
问题及现象 时序数据库 IoTDB 集群报错: The write is rejected because the wal directory size has reached the threshold 53687091200 bytes. You may need to adjust the flush policy of the storage storageengine or the IoTConsensus synchronization pa…...
Go支付中台方案:多平台兼容与多项目对接
一、中台的概念 中台是一种企业级的架构模式,它处于前台应用和后台资源之间,将企业核心能力进行整合、封装,形成一系列可复用的业务能力组件。这些组件就像乐高积木一样,可以被不同的前台业务快速调用,从而避免重复开…...
设计模式:23、享元模式
目录 0、定义 1、享元模式的三种角色 2、享元模式的UML类图 3、示例代码 0、定义 运营共享技术有效地支持大量细粒度的对象 1、享元模式的三种角色 享元接口(Flyweight):是一个接口,该接口定义了享元对外公开其内部数据的方…...
如何使用靜態IP代理?【詳細教程】
靜態IP地址是手動分配給設備或伺服器的固定不變的 IP。與動態 IP 地址不同,動態 IP 地址由 DHCP 伺服器自動分配,並且會隨時間而變化。 如何獲取和設置靜態IP地址 一、檢查是否需要靜態IP? 在配置靜態 IP 之前,請…...
C++day3
1、把课上类的三个练习题的构造函数写出来 #include <iostream> #include <cstring>using namespace std;class Car {string color;string brond;double speed; public:Car(string c,string b,double s):color("black"),brond("Benz"),speed(…...
ABAP开发-批量导入BAPI和BDC_1
系列文章目录 文章目录 系列文章目录[TOC](文章目录) 前言一、概念二、BDC和BAPI数据导入1、BDC数据导入(录屏)2、BAPI数据导入 三、实例1、BAPI2、BDC 总结 前言 一、概念 SAP中,对一个事务码反复操作并且达到批量处理数据的效果࿰…...
iOS 语音循环播放设置
本地文件、网络文件,区别就是URL创建方式 1、使用AVPlayerItem与AVPlayer(这个简单,只需要设置回调),而不是AVAudioPlayer(这个麻烦,需要设置代理、计时器等等) 2、设置AVPlayerIte…...
PlantUML——类图
背景 类图是UML模型中的静态视图,其主要作用包括: 描述系统的结构化设计,显示出类、接口以及它们之间的静态结构和关系。简化对系统的理解,是系统分析与设计阶段的重要产物,也是系统编码和测试的重要模型依据。 在U…...
ASP.NET Core实现鉴权授权的几个库
System.IdentityModel.Tokens.Jwt 和 Microsoft.AspNetCore.Authentication.JwtBearer 是两个常用的库,分别用于处理 JWT(JSON Web Token)相关的任务。它们在功能上有一定重叠,但侧重点和使用场景有所不同。 1. System.IdentityM…...
生成:安卓证书uniapp
地址: https://ask.dcloud.net.cn/article/35777 // 使用keytool -genkey命令生成证书: 官网: keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore ----------------------------------…...
探索Web3:从去中心化应用到全球数字化未来
Web3 是互联网发展的下一步,它通过去中心化的理念重新定义了数字世界。与传统的Web2相比,Web3将数据主权交还给用户,让每个人都可以在没有中介的情况下安全地交换信息和价值。本文将探索Web3的基本概念,去中心化应用(D…...
AR向左,AI向右,智能眼镜来到十字路口
从Google Glass到Vision Pro,人类对智能眼镜的探索有进展,但都不算成功,直至Ray-Ban Meta的出现,这才让行业对智能眼镜重燃信心,从去年开始,随着AI大模型应用的深入,智能眼镜又有了新的故事可说…...
CTF靶场搭建及Web赛题制作与终端docker环境部署
写在前面 ╔══════════════════════════════════════════════════════════════════════════╗ 哈喽大家好!我是Myon,趁着我的云服务器还没过期,这次给大家出一…...
Java 应用程序CPU 100%问题排查优化实战
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
计网(王道的总结)-数据链路层-网络层-传输层
由于时间有限,把每个王道的章节最后一节放在一起,分别看看复习知识点。 3.6.4 IEEE 802.11 无线局域网 重点: 3.7 广域网 真题考频:极低 3.8以太网交换机 4.1网络层的功能 4.2.1IPv4分组 最重要的: TTL:…...
1-4 C单向链表
目录 1.0 基本概念 2.0 初始化链表 2.0 插入数据 3.0 删除数据 4.0 获取链长度 5.0 查询链表 6.0 返回第一个节点 7.0 打印链表节点 8.0 释放内存 9.0 链表调用 1.0 基本概念 线性表的顺序存储:用一块连续的内存空间,线性表的链式存储ÿ…...