【Go】-限流器的四种实现方法
目录
关于限流和限流器
固定窗口限流器
滑动窗口限流器
漏桶限流器
令牌桶限流器
总结
关于限流和限流器
限流(Rate Limiting)是一种控制资源使用率的机制,通常用于防止系统过载和滥用。
限流器(Rate Limiter)是一种实现限流的组件或服务。以下是限流器的一些主要用途和原因:
-
防止系统过载:在高流量的情况下,如网络服务或API,限流可以确保系统不会因为过多的并发请求而崩溃。通过限制每个用户或客户端的请求频率,系统可以维持稳定的性能。
-
资源分配:在多用户环境中,限流可以确保所有用户都公平地使用资源,防止某些用户占用过多资源而影响其他用户。
-
成本控制:对于云服务和API提供商来说,限流可以帮助控制成本。通过限制免费层级用户的使用量,可以鼓励用户升级到付费服务。
-
提高用户体验:如果一个服务因为过载而变得缓慢或不可用,限流可以提高用户体验,因为它可以保证服务在高负载下的响应速度。
-
防止滥用:限流可以防止恶意用户或自动化脚本滥用服务,例如防止暴力破解密码或发送垃圾邮件。
-
服务降级:在某些情况下,系统可能会故意降低服务质量,以保护关键功能的正常运行。限流是实现服务降级的一种方式。
-
合规性:某些行业法规可能要求服务提供商限制数据传输速率,以符合隐私和安全标准。
-
缓存友好:限流可以减少对缓存系统的冲击,因为缓存系统可能无法处理非常高的请求率。
固定窗口限流器
这种限流器一时间为周期,用一个计数器配合定时器,限制周期内访问的次数。
type FixedWindowRateLimiter struct {windowSize time.Durationlimit uint64counter uint64ticker *time.Tickerstop chan struct{}status bool}func NewFixedWindowRateLimiter(windowSize time.Duration, limit uint64) *FixedWindowRateLimiter {now := uint64(time.Now().UnixNano())return &FixedWindowRateLimiter{windowSize: windowSize,limit: limit,start: now,stop: make(chan struct{}),status: false,}}
-
windowSize
限流器周期 -
limit
最大访问次数限制 -
counter
计数器 -
ticker
计时器 -
stop
关闭信号管道 -
status
限流器状态
启动和关闭:
Start启动定时器用go协程处理周期更新和收到关闭信号,Close向关闭信号管道发送关闭信号。
func (fwrl *FixedWindowRateLimiter) Start() {fwrl.ticker = time.NewTicker(fwrl.windowSize)fwrl.status = truego func() {for {select {case <-fwrl.ticker.C:atomic.StoreUint64(&fwrl.counter, 0)case <-fwrl.stop:fwrl.ticker.Stop()fwrl.status = falsereturn}}}()}func (fwrl *FixedWindowRateLimiter) Close() {close(fwrl.stop)}
实现的方法:
// 请求一次访问func (fwrl *FixedWindowRateLimiter) Do() bool {if !fwrl.status {return false}currentCounter := atomic.LoadUint64(&fwrl.counter)if currentCounter >= fwrl.limit {return false}atomic.AddUint64(&fwrl.counter, 1)return true}// 剩余可访问次数func (fwrl *FixedWindowRateLimiter) Check() uint64 {if !fwrl.status {return 0}return fwrl.limit - atomic.LoadUint64(&fwrl.counter)}// 更新并重启限流器func (fwrl *FixedWindowRateLimiter) Update(windowSize time.Duration, limit uint64) {fwrl.windowSize = windowSizefwrl.limit = limitif fwrl.status {fwrl.ticker.Stop()fwrl.Start()}}
关于原子操作:
在代码中使用了atomic包的原子操作,目的是为了保证高并发读写下限流器的数据准确性。atomic包的实现在sre/internal/runtime/atomic,本质上使用汇编语言保证了操作的原子性。
例如swapUint64函数中,调用.Xchg64的代码如下:
TEXT ·Xchg64(SB), NOSPLIT, $0-24MOVD ptr+0(FP), R0MOVD new+8(FP), R1#ifndef GOARM64_LSEMOVBU internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4CBZ R4, load_store_loop#endifSWPALD R1, (R0), R2MOVD R2, ret+16(FP)RET#ifndef GOARM64_LSEload_store_loop:LDAXR (R0), R2STLXR R1, (R0), R3CBNZ R3, load_store_loopMOVD R2, ret+16(FP)RET#endif
计数器限流的严重问题: 这个算法虽然简单,但是有一个十分致命的问题,那就是临界问题,我们看下图:
从上图中我们可以看到,假设有一个恶意用户,他在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在 1秒里面,瞬间发送了200个请求。
我们刚才规定的是1分钟最多100个请求(规划的吞吐量),也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求, 可以瞬间超过我们的速率限制。
用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。
滑动窗口限流器
跟固定窗口限流器差不多,只不过粒度更小了。
type SlidingWindowRateLimiter struct {windowSize time.DurationsubWindow time.Durationlimit uint64counters []uint64start uint64ticker *time.Tickersubticker *time.Tickerstop chan struct{}status bool}func NewSlidingWindowRateLimiter(windowSize, subWindow time.Duration, limit uint64) (*SlidingWindowRateLimiter, error) {if windowSize <= subWindow {return nil, errors.New("wrong size")}numSubWindows := int(windowSize / subWindow)return &SlidingWindowRateLimiter{windowSize: windowSize,subWindow: subWindow,limit: limit,counters: make([]uint64, numSubWindows),start: uint64(time.Now().UnixNano()),stop: make(chan struct{}),}, nil}
-
windowSize
限流器周期 -
subWindow
滑动窗口周期 -
limit
最大访问次数限制 -
counters
滑动窗口计数器切片 -
start
周期开启时间 -
ticker
周期计时器 -
subticker
窗口计时器 -
stop
关闭信号管道 -
status
限流器状态
启动和关闭:
滑窗是小粒度的固定窗口,计算index并且重置计数
func (swrl *SlidingWindowRateLimiter) Start() {swrl.ticker = time.NewTicker(swrl.windowSize)swrl.subticker = time.NewTicker(swrl.subWindow)swrl.status = truego func() {for {select {case <-swrl.subticker.C:now := uint64(time.Now().UnixNano())index := int((now - swrl.start) / uint64(swrl.subWindow))atomic.StoreUint64(&swrl.counters[index%len(swrl.counters)], 0)case <-swrl.ticker.C:swrl.start = uint64(time.Now().UnixNano())case <-swrl.stop:swrl.ticker.Stop()swrl.status = falsereturn}}}()}func (swrl *SlidingWindowRateLimiter) Close() {close(swrl.stop)}
其他方法:
这里Do和Check都是要计算周期内每个滑窗总和
func (swrl *SlidingWindowRateLimiter) Do() bool {if !fwrl.status {return false}now := uint64(time.Now().UnixNano())startIndex := int((now - swrl.start) / uint64(swrl.subWindow))endIndex := int((now - swrl.start + uint64(swrl.windowSize)) / uint64(swrl.subWindow))// 计算周期内每个滑窗总和是否大于limitsum := uint64(0)for i := startIndex; i <= endIndex; i++ {index := iif index >= len(swrl.counters) {index -= len(swrl.counters)}sum += atomic.LoadUint64(&swrl.counters[index])}if sum >= swrl.limit {return false}// 增加当前子窗口的计数currentIndex := int((now - swrl.start) / uint64(swrl.subWindow))atomic.AddUint64(&swrl.counters[currentIndex], 1)return true}func (swrl *SlidingWindowRateLimiter) Check() uint64 {if !fwrl.status {return 0}now := uint64(time.Now().UnixNano())startIndex := int((now - swrl.start) / uint64(swrl.subWindow))endIndex := int((now - swrl.start + uint64(swrl.windowSize)) / uint64(swrl.subWindow))sum := uint64(0)for i := startIndex; i <= endIndex; i++ {index := iif index >= len(swrl.counters) {index -= len(swrl.counters)}sum += atomic.LoadUint64(&swrl.counters[index])}return swrl.limit - sum}func (swrl *SlidingWindowRateLimiter) Update(windowSize time.Duration, subWindow time.Duration, limit uint64) {swrl.windowSize = windowSizeswrl.limit = limitswrl.subWindow = subWindowif swrl.status {swrl.ticker.Stop()numSubWindows := int(windowSize / swrl.subWindow)swrl.counters = make([]uint64, numSubWindows)swrl.Start()}}
漏桶限流器
漏桶,可以想象成一个木桶下面钻了一个小孔,把水倒进来就是请求访问,水漏出去就是允许请求。
理论上小孔流出水的速率是不变的,也就是允许请求的速率是不变的,这就是漏桶的特点,你可以随便倒水,但是流出水速率恒定,实现按了平稳的访问速率。
type LeakyBucket struct {capacity uintremaining uintticker *time.Tickerreset time.Timerate time.Durationmutex sync.Mutexstop chan struct{}status bool}func NewLeakyBucket(capacity uint, rate time.Duration) (*LeakyBucket, error) {return &LeakyBucket{capacity: capacity,remaining: capacity,rate: rate,status: false,}}
-
capacity
桶的容量 -
remaining
剩余的容量 -
ticker
计时器 -
reset
重置的时间 -
rate
漏桶的速率 -
mutes
互斥锁 -
stop
关闭信号管道 -
status
桶的状态
启动和关闭:
func (lb *LeakyBucket) Start() {lb.ticker = time.NewTicker(swrl.rate)lb.status = truelb.reset = time.Now().Add(rate)go func() {for {select {case <-lb.ticker.C:lb.mutex.lock()if lb.remaining < lb.capacity {lb.remaining += 1}lb.mutex.unlock()case <-lb.stop:lb.ticker.Stop()lb.status = falsereturn}}}()}func (lb *LeakyBucket) Close() {close(lb.stop)}
其他方法:
// 返回容量func (lb *LeakyBucket) Capacity() uint {return lb.capacity}// 桶里剩余容量func (lb *LeakyBucket) Remaining() uint {return lb.remaining}// 重置桶func (lb *LeakyBucket) Reset() time.Time {lb.remaining = lb.capacity// 更新reset时间为一个rate后,这样就不用加锁了lb.reset = time.Now().Add(rate)return lb.reset}// 往桶里加请求func (lb *LeakyBucket) Add(amount uint) (bool, error) {lb.mutex.Lock()defer lb.mutex.Unlock()// 时间在重置前那就重置后再取if time.Now().After(lb.reset) {lb.reset = time.Now().Add(lb.rate)lb.remaining = lb.capacity}if amount > lb.remaining {return false, errors.New("too many")}lb.remaining -= amountreturn true, nil}
漏桶的问题:
漏桶的出水速度固定,也就是请求放行速度是固定的,因此漏桶不能有效应对突发流量,但是能起到平滑突发流量(整流)的作用。
漏桶出口的速度固定,不能灵活的应对后端能力提升,比如,通过动态扩容,后端流量从1000QPS提升到1WQPS,漏桶没有办法。
令牌桶限流器
令牌桶算法以一个设定的速率产生令牌并放入令牌桶,每次用户请求都得申请令牌,如果令牌不足,则拒绝请求。 令牌桶算法中新请求到来时会从桶里拿走一个令牌,如果桶内没有令牌可拿,就拒绝服务。当然,令牌的数量也是有上限的。令牌的数量与时间和发放速率强相关,时间流逝的时间越长,会不断往桶里加入越多的令牌,如果令牌发放的速度比申请速度快,令牌桶会放满令牌,直到令牌占满整个令牌桶。
type TookenBucket struct {capacity uinttooken uintticker *time.Tickerreset time.Timerate time.Durationmutex sync.Mutexstop chan struct{}status bool}func NewTookenBucket(capacity uint, rate time.Duration) (*TookenBucket, error) {return &TookenBucket{capacity: capacity,tooken: 0,rate: rate,status: false,}}
-
capacity
桶的容量 -
tooken
剩余的tooken -
ticker
计时器 -
reset
重置的时间 -
rate
漏桶的速率 -
mutes
互斥锁 -
stop
关闭信号管道 -
status
桶的状态
启动和关闭:
func (lb *TookenBucket) Start() {tb.ticker = time.NewTicker(swrl.rate)tb.status = truetb.reset = time.Now().Add(rate)go func() {for {select {case <-tb.ticker.C:tb.mutex.lock()if tb.tooken < lb.capacity {tb.tooken += 1}tb.mutex.unlock()case <-tb.stop:tb.ticker.Stop()tb.status = falsereturn}}}()}func (tb *TookenBucket) Close() {close(tb.stop)}
其他方法:
// 返回容量func (tb *TookenBucket) Capacity() uint {return tb.capacity}// 桶里tookenfunc (tb *TookenBucket) Cheak() uint {return tb.tooken}// 重置桶func (tb *TookenBucket) Reset() time.Time {tb.tooken = 0// 更新reset时间为一个rate后,这样就不用加锁了tb.reset = time.Now().Add(rate)return tb.reset}// 往桶里取令牌func (tb *TookenBucket) Took(amount uint) (bool, error) {tb.mutex.Lock()defer tb.mutex.Unlock()// 时间在重置前那就重置后再取if time.Now().After(tb.reset) {tb.reset = time.Now().Add(tb.rate)tb.token = 0return false, nil}if amount > tb.tooken {return false, errors.New("too many")}tb.tooken -= amountreturn true, nil}
总结
以上就是四种限流方法实现,一般在高并发实战中,采用漏桶+令牌桶。
相关文章:
【Go】-限流器的四种实现方法
目录 关于限流和限流器 固定窗口限流器 滑动窗口限流器 漏桶限流器 令牌桶限流器 总结 关于限流和限流器 限流(Rate Limiting)是一种控制资源使用率的机制,通常用于防止系统过载和滥用。 限流器(Rate Limiter)是…...
精准识别花生豆:基于EfficientNetB0的深度学习检测与分类项目
精准检测花生豆:基于EfficientNet的深度学习分类项目 在现代农业生产中,作物的质量检测和分类是确保产品质量的重要环节。针对花生豆的检测与分类需求,我们开发了一套基于深度学习的解决方案,利用EfficientNetB0模型实现高效、准…...
【信息系统项目管理师】第11章:项目成本管理过程详解
更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 一、规划成本管理1、输入2、工具与技术3、输出二、估算成本1、输入2、工具与技术3、输出三、制定预算1、输入2、工具与技术3、输出四、控制成本1、输入2、工具与技术3、输出一、规划成本管理 定义:规划成本管…...
微信流量主挑战:用户破16!新增文档转换(新纪元3)
朋友们,报告好消息!我的小程序用户数量已经涨到16个了!没错,真没拉朋友圈亲戚好友来撑场子,全靠实力(和一点点运气)吸引了16位陌生小伙伴光临!这波进步,连我自己都感动了…...
DFS【东北大学oj数据结构11-2】C++
题面 深度优先搜索(DFS)是一种基于尽可能多地访问相邻顶点策略的图搜索算法。如果顶点 v 有未搜索的顶点则递归搜索直至 v 的最后一条边。在搜索了 v 的所有边之后,搜索继续返回到找到 v 时经过的边。 搜索从原来的起点开始,直到…...
运维项目部署的环境准备
这里用的安装工具是yum,yum作为一个安装工具,用起来比较方便 用yum安装以下软件,组成项目的可运行环境 yum 先更新 yum update -y 安装一个外置仓库 yum install epel-release 安装redis yum install redis 安装nginx yum install nginx 安装vim yum install vim…...
URDF文件中inertial数据的描述坐标系说明
这件事的来源是这样的:结构手动把连杆坐标系下描述的惯性张量数据写入了urdf中,给我到以后发现有问题,给我搞懵了,以为我错了这么多年,于是有了本次的深度调研,先上结论,感兴趣的可以参考后文。…...
OpenCV-Python实战(5)——图形绘制基础
一、直线 cv2.line(img*,pt1*,pt2*,color*,thickness*,lineTypeLINE_8) img:绘图的背景(画布)。 pt1、pt2:始/终点坐标,格式为元组()。 color:直线颜色,BGR格式。 t…...
科技云报到:人工智能时代“三大件”:生成式AI、数据、云服务
科技云报到原创。 就像自行车、手表和缝纫机是工业时代的“三大件”。生成式AI、数据、云服务正在成为智能时代的“新三大件”。加之全球人工智能新基建加速建设,成为了人类社会数字化迁徙的助推剂,让新三大件之间的耦合越来越紧密。从物理世界到数字世…...
HarmonyOS NEXT 实战之元服务:静态案例效果(二)
背景: 前几篇学习了元服务,后面几期就让我们开发简单的元服务吧,里面丰富的内容大家自己加,本期案例 仅供参考 先上本期效果图 ,里面图片自行替换 效果图代码案例如下: Index里面实现 import { authent…...
Qt学习记录
Qt学习记录 Qt6读取GBK文件 在Qt5中,有QTextCodec模块,支持各种编码设置。 // Qt5 QCoreApplication a(argc, argv); auto desk QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); QFile file(QDir(desk).filePath("test.tx…...
用于汽车碰撞仿真的 Ansys LS-DYNA
使用 Ansys LS-DYNA 进行汽车碰撞仿真汽车碰撞仿真 简介 汽车碰撞仿真是汽车设计和安全工程的一个关键方面。这些仿真使工程师能够预测车辆在碰撞过程中的行为,从而有助于改进安全功能、增强车辆结构并符合监管标准。Ansys LS-DYNA 是一款广泛用于此类仿真的强大工具…...
Android--java实现手机亮度控制
文章目录 1、开发需求2、运行环境3、主要文件4、布局文件信息5、手机界面控制代码6、debug 1、开发需求 需求:开发一个Android apk实现手机亮度控制 2、运行环境 Android studio最新版本 3、主要文件 app\src\main\AndroidManifest.xml app\src\main\res\layou…...
300多种复古手工裁剪拼贴艺术时尚字母、数字、符号海报封面Vlog视频MOV+PNG素材
300复古时尚大小写字母、数字、符号拼贴海报封面平面设计Vlog视频标题动画 Overlay - Cut-Out Letters Animations Pack - Animated Letters, Numbers, and Symbols 使用 Cut-Out Letters Animations Pack 提升您的内容!包含 300多个高品质动画资源,包括…...
免押租赁系统的优势与应用解析
内容概要 免押租赁系统,听上去是不是很未来?其实,它的基本概念就是在租赁过程中,消费者无需交付押金,直接使用所租物品。这样一来,不仅降低了租赁的门槛,也让许多想尝试的用户能够更轻松地参与…...
feign 针对某一个特定接口设置超时时间
一、对feign所有接口设置超时配置 如果是当前feign所有接口的超时配置,需要在 FeignClient 的 configuration 属性中设置。 详情见: https://blog.csdn.net/sinat_32502451/article/details/136884349 二、针对某一个特定接口设置超时时间 调用 feig…...
Chrome被360导航篡改了怎么改回来?
一、Chrome被360导航篡改了怎么改回来? 查看是否被360主页锁定,地址栏输入chrome://version,看命令行end后面(蓝色部分),是否有https://hao.360.com/?srclm&lsn31c42a959f 修改步骤 第一步:…...
GitLab 将停止为中国区用户提供服务,60天迁移期如何应对? | LeetTalk Daily
“LeetTalk Daily”,每日科技前沿,由LeetTools AI精心筛选,为您带来最新鲜、最具洞察力的科技新闻。 GitLab作为一个广受欢迎的开源代码托管平台,近期宣布将停止服务中国大陆、澳门和香港地区的用户提供服务。根据官方通知&#x…...
Linux系统和makefile详解
### Linux系统详解 Linux是一个开源且功能强大的操作系统内核,自1991年由林纳斯托瓦兹首次发布以来,它已经成为全球最流行的操作系统之一。Linux的核心特性包括开源、多用户多任务、高稳定性与安全性,以及良好的跨平台能力。 1. **开源**&a…...
基于导频方法的MIMO信道估计详解
多输入多输出(MIMO)技术作为现代无线通信系统的核心,通过利用多天线阵列在发射端和接收端同时传输和接收多个数据流,显著提高了系统的频谱效率和数据传输速率。然而,MIMO系统的性能在很大程度上依赖于对信道状态的准确…...
#!/bin/bash^M 坏的解释器:没有哪个文件或者目录
#!/bin/bash^M 坏的解释器:没有哪个文件或者目录 问题背景问题分析问题解决dos2unixsedvim编辑器(推荐)在Windows上转换文件格式 最后 问题背景 工作中,在Windows上编写的shell脚本上传到Linux服务器,在执行的时候提示…...
aj-report本地前后端分离部署运行
github项目地址 aj-report-mine 在源代码v1.4版本基础上,本地进行前后端分离部署开发 这里我是进行了整合,把自己在拉取源代码到成功运行过程中的一些东西直接整合,根据下面的步骤即可成功运行 资源获取 夸克网盘(16-github-aj-report-re…...
1435A 信号发生器
1435A 信号发生器 1435系列信号发生器基于创新的技术实现了性能、经济性和体积重量的平衡设计。具有优良的频谱纯度,单边带相位噪声1GHz载波10kHz频偏达到-136dBc/Hz,10GHz载波10kHz频偏达到-116dBc/Hz;具有高功率输出和大动态范围ÿ…...
计算机组成原理的学习笔记(9)-- CPU·其一 CPU的基本概念/流水线技术/数据通路
学习笔记 前言 本文主要是对于b站尚硅谷的计算机组成原理的学习笔记,仅用于学习交流。 CPU(中央处理器) 1. 组成 定义:计算机的核心部件,负责执行指令和处理数据。 组成部分: 核心:多个处…...
【Python】 -- python3 读取 aws athena 表数据
目录 1、环境准备 2、安装环境 3、举例查询某张表数据和执行 add partition 操作 3.1、编辑文件 athena_jdbc.py 3.2、查找 JVM 的动态链接库路径 3.3、保存文件,执行以下命令 1、环境准备 oracle jdk 11centos 8依赖:pandas、pyathenajdbc 和 sq…...
子网掩码计算route命令
子网掩码 - 站长工具 1.子网掩码 子网掩码就是用来遮掩IP地址并划分网段的工具,根据遮掩的位数不同来划分不同的网段。 2.网关 网关(Gateway)又称网间连接器、协议转换器。默认网关在网络层上以实现网络互连,是最复杂的网络互连设备,仅用…...
店铺营业状态设置
admineShopController RestController("admineShopController") RequestMapping("/admin/shop") Api(tags "店铺相关接口") Slf4j public class ShopController {//设置一个常量 因为经常使用public static final String KEY "SHOP-ST…...
JavaWeb 开发基础入门
在当今互联网时代,JavaWeb 开发是构建各类网络应用的核心技术之一。无论是大型企业级应用,还是小型的个人网站,JavaWeb 都展现出强大的生命力。今天,就让我们一起踏入 JavaWeb 开发的基础入门之旅。 一、认识 JavaWeb JavaWeb 是…...
Unity Dots理论学习-2.ECS有关的模块(1)
Unity的实体组件系统(ECS)是支撑DOTS模块和技术的面向数据架构。ECS为Unity中的内存数据和runtime进程调度提供了高度的控制和确定性。 ECS for Unity 2022 LTS 配备了两个兼容的物理引擎,一个高级的Netcode package,以及一个用来…...
CentOS下安装RabbitMQ
提示:“奔跑吧邓邓子” 的高效运维专栏聚焦于各类运维场景中的实际操作与问题解决。内容涵盖服务器硬件(如 IBM System 3650 M5)、云服务平台(如腾讯云、华为云)、服务器软件(如 Nginx、Apache、GitLab、Redis、Elasticsearch、Kubernetes、Docker 等)、开发工具(如 Gi…...
【JAVA高级篇教学】第四篇:MySQL 5.7 与 MySQL 8 的区别
MySQL 是最流行的开源数据库管理系统之一,而 MySQL 8 的发布相较于 MySQL 5.7 带来了大量的改进与功能增强。 目录 一、性能改进 二、功能增强 三、安全性 四、开发体验 五、默认排序规则 六、支持的排序规则数量 七、区分敏感性(Sensitivity&…...
【Git】-- 版本说明
Alpha:是内部测试版,一般不向外部发布,会有很多 Bug .一般只有测试人员使用。Beta:也是测试版,这个阶段的版本会一直加入新的功能。在 Alpha 版之后推出。RC:(Release Candidate) 顾名思义么 ! 用在软件上就是候选版本。系统平台…...
Flink优化----FlinkSQL 调优
目录 FlinkSQL 调优 1 设置空闲状态保留时间 2 开启 MiniBatch 3 开启 LocalGlobal 3.1 原理概述 3.2 提交案例:统计每天每个 mid 出现次数 3.3 提交案例:开启 miniBatch 和 LocalGlobal 4 开启 Split Distinct 4.1 原理概述 4.2 提交案例&…...
云上「算力浪费」,正在掣肘企业应用落地。
投入算力,真的能换来利润吗?这是每个想“入局”大模型的企业都会思考的问题。 人工智能行业一直困于成本,无论从模型训练到推理,都充满了“烧钱”的气息。无法避免的高昂算力,成为企业入局大模型的“铁门槛”。 据多…...
科技创新 数智未来|清科·沙丘投研院走进竹云
12月20日,清科沙丘投研院带领企投家团队走进竹云交流分享,聚焦技术创新、企业数字化管理、行业前沿应用案例等热点议题,深入探讨数字技术如何点燃企业高质量发展的澎湃动力,共话企业数字化、智能化发展之道。 达晨财智股权管理部…...
spring专题笔记(六):bean的自动装配(自动化注入)-根据名字进行自动装配、根据类型进行自动装配。代码演示,通俗易懂。
目录 一、根据名字进行自动装配--byName 二、根据类型进行自动装配 byType 本文章主要是介绍spring的自动装配机制, 用代码演示spring如何根据名字进行自动装配、如何根据类型进行自动装配。代码演示,通俗易懂。 一、根据名字进行自动装配--byName Us…...
EDGE浏览器每次关闭时再次打开保存的密码就消失如何解决
文章目录 EDGE浏览器每次重启的时候保存的密码都消失如何解决? 打开EDGE浏览器点击三个点 点击设置 点击隐私、搜索和服务 找到选择每次关闭浏览器时要清除的内容 将开启的关闭即可...
Python - 获取当前函数中的所有参数信息(名称和值)
代码 import inspect import randomclass P:def start(self, p1, p2, p3None, p4None):arg_info inspect.getargvalues(inspect.currentframe())kwargs arg_info.locals # 获取到所有参数print(kwargs)del kwargs["self"]try:self._start(**kwargs)except Except…...
pyqt5冻结+分页表
逻辑代码 # -*- coding: utf-8 -*- import sys,time,copy from PyQt5.QtWidgets import QWidget,QApplication, QDesktopWidget,QTableWidgetItem from QhTableWidgetQGN import Ui_QhTableWidgetQGN from PyQt5.QtCore import Qt from PyQt5 import QtCore, QtGui, QtWidgets…...
uniapp中实现APP调用本地通知栏通知、震动、本地提示音或者mp3提醒
要在uniapp中实现APP调用本地通知栏通知、震动和本地提示音或者mp3提醒,你可以使用uni-app提供的原生API和插件来实现。 通知栏通知: 你可以使用uni-app的原生API uni.showToast() 或者 uni.showModal() 来实现通知栏通知的功能。可以在需要发送通知的地…...
JS 数组创建、访问、常用方法
文章目录 创建访问常用属性和相关方法1. length 长度属性2. push() 新增元素 - 末尾添加3. unshift() 新增元素 - 开头添加4. pop() 移除元素 - 末尾删除5. shift() 移除元素 - 开头删除6. concat() 复制数组后新增7. slice() 复制数组8. splice() 增删改9. toString() 转字符串…...
【C++】ceil 和 floor 函数的实现与分析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯ceil 和 floor 函数的基础介绍1. ceil 函数定义与功能示例代码输出结果功能分析使用场景 2. floor 函数定义与功能示例代码输出结果功能分析使用场景 💯自行实现…...
每天40分玩转Django:Django类视图
Django类视图 一、今日学习内容概述 学习模块重要程度主要内容类视图基础⭐⭐⭐⭐⭐View类、URLconf配置通用视图⭐⭐⭐⭐⭐ListView、DetailView等Mixin机制⭐⭐⭐⭐多重继承、功能组合自定义类视图⭐⭐⭐⭐视图定制、方法重写 二、类视图基础 2.1 基本类视图 # views.py…...
运动控制卡网络通讯的心跳检测之C#上位机编程
本文导读 今天,正运动小助手给大家分享一下如何使用C#上位机编程实现运动控制卡网络通讯的心跳检测功能。 01 ECI2618B硬件介绍 ECI2618B经济型多轴运动控制卡是一款脉冲型、模块化的网络型运动控制卡。控制卡本身最多支持6轴,可扩展至12轴的运动控制…...
秒验简介与下载说明
秒验简介与下载说明 产品概述 秒验是一款帮助开发者实现一键验证功能的产品,从根源上降低企业验证成本, 有效提高拉新转化率,降低因验证带来的流失率,3秒完成手机号验证 SDK信息 下载SDK 下载地址 SDK提供Maven和pod引入两种方…...
Redis中的数据类型
文章目录 前言一、字符串(String)应用场景常用命令 二、哈希(Hash)应用场景常用命令 三、列表(List)应用场景常用命令 四、集合(Set)应用场景常用命令 五、有序集合(Sort…...
esp8266_TFTST7735语音识别UI界面虚拟小助手
文章目录 一 实现思路1 项目简介1.1 项目效果1.2 实现方式 2 项目构成2.1 软硬件环境2.2 完整流程总结(重点整合)(1) 功能逻辑图(2) 接线(3) 使用esp8266控制TFT屏(4)TFT_espI库配置方法(5) TFT_esp库常用代码详解(6)TFT屏显示图片(7) TFT屏显示汉字(8) …...
RTOS 基础知识
**实时操作系统(RTOS, Real-Time Operating System)**是一种专为实时性要求设计的操作系统,具有确定性和高效性。RTOS 的系统架构围绕任务调度、时间管理和资源管理展开,以确保系统能够在规定时间内响应外部事件。以下是RTOS的系统…...
【 thefuck 安装与使用】Linux 终端自动纠错工具:一头GitHub上的“草泥马“ - thefuck,妈妈再也不用担心我打错命令行了!
目录 快速安装使用 . 1.简介 2.安装 3.配置 4.补充 官方盗料参考 快速安装使用 快速安装使用,四步即可: #Ubuntu/Debian系统 sudo apt update sudo apt install python3-dev python3-pip sudo pip3 install thefuck #编辑bashrc配置文件 vim ~/.bashrc…...
在Nginx部署Web应用,如何保障后端API的安全
1. 使用HTTPS和http2.0 参考:Nginx配置HTTP2.0_nginx 支持 2.0-CSDN博客 2. 设置严格的CORS策略 通过add_header指令设置CORS头。 只允许来自https://frontend.yourdomain.com的请求访问API location /api/ {if ($http_origin ~* (https://frontend\.yourdomai…...