当前位置: 首页 > news >正文

【Sentinel Go】新手指南、流量控制、熔断降级和并发隔离控制

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
文档

1.新手指南

资源的定义:可以是应用、接口、函数或一段代码,目的是保护这段资源的运行。

1.1使用方法:

  1. 通用配置及初始化:配置方式使用文档
  • InitDefault():从环境变量指定的配置文件以及环境变量中读取相应配置来初始化 Sentinel,若环境变量不存在则使用默认值。
  • Init(configPath string):从给定的 YAML 文件中读取相应配置来初始化 Sentinel。
  • InitWithConfig(confEntity *config.Entity): 用户硬编码配置对象*config.Entity来初始化Sentinel。
  1. **埋点(定义资源):**每个埋点都有一个资源名称,代表触发了这个资源的调用和访问

    Entry(resource string, opts ...Option) (*base.SentinelEntry, *base.BlockError)

resource表示资源名称,opts表示埋点配置。返回值列表的第一个参数和第二个参数是互斥的,如果pass的话,就会返回(*base.SentinelEntry, nil);如果执行blocked,那么Sentinel会返回(nil, *base.BlockError)

埋点配置:

  • WithTrafficType(entryType base.TrafficType):标记该埋点资源的流量类型,其中 Inbound 代表入口流量,Outbound 代表出口流量。若不指定,默认为 Outbound
  • WithResourceType(resourceType base.ResourceType):标记该埋点资源的分类。
  • WithAcquireCount(acquireCount uint32):标记每次触发该埋点计为几次调用(可以理解为 batch count)。若不指定,默认为 1。
  • WithArgs(args ...interface{}):埋点携带的参数列表,为热点参数统计预留。
  • WithSlotChain(chain *base.SlotChain):埋点执行的检查的slotchain,若不指定,默认使用全局slotchain

示例:在这里假设业务逻辑是很复杂的函数,记作ExcuteSteps,所以在Exit的时候可以使用defer

import (sentinel "github.com/alibaba/sentinel-golang/api"
)// Entry 方法用于埋点
e, b := sentinel.Entry("resource-name", sentinel.WithTrafficType(base.Inbound))
if b != nil {// 请求被流控,可以从 BlockError 中获取限流详情// block 后不需要进行 Exit()
} else {// 请求可以通过// 务必保证业务逻辑结束后 Exitdefer e.Exit()
}
ExcuteSteps()
  1. 规则配置:支持硬编码方式或是动态数据源

    流控规则为例

    _, err = flow.LoadRules([]*flow.Rule{{Resource:               "some-test",Threshold:              10,TokenCalculateStrategy: flow.Direct,ControlBehavior:        flow.Reject,},
    })
    if err != nil {// 加载规则失败,进行相关处理
    }
    

    1.2规则配置

    Sentinel Go支持 流控规则、流量隔离规则(并发控制)、熔断规则、自适应过载保护规则和热点参数流控规则。

    基于QPS限流的完整示例

    import (sentinel "github.com/alibaba/sentinel-golang/api"
    )func main() {// 务必先进行初始化err := sentinel.InitDefault()if err != nil {log.Fatal(err)}// 配置一条限流规则_, err = flow.LoadRules([]*flow.Rule{{Resource:               "some-test",Threshold:              10,TokenCalculateStrategy: flow.Direct,ControlBehavior:        flow.Reject,},})if err != nil {fmt.Println(err)return}ch := make(chan struct{})for i := 0; i < 10; i++ {go func() {for {// 埋点逻辑,埋点资源名为 some-teste, b := sentinel.Entry("some-test")if b != nil {// 请求被拒绝,在此处进行处理time.Sleep(time.Duration(rand.Uint64() % 10) * time.Millisecond)} else {// 请求允许通过,此处编写业务逻辑fmt.Println(util.CurrentTimeMillis(), "Passed")time.Sleep(time.Duration(rand.Uint64() % 10) * time.Millisecond)// 务必保证业务结束后调用 Exite.Exit()}}}()}<-ch
    }
    

2.流量控制

​ 流量控制是监控资源的统计指标,根据token计算策略来计算资源的可用token(阈值),根据流量控制策略对请求进行控制,避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

Sentinel 通过定义流控规则来实现对 Resource 的流量控制。在Sentinel内部会在加载流控规则时候将每个 flow.Rule 都会被转换成流量控制器(TrafficShapingController)。 每个流量控制器实例都会有自己独立的统计结构,这里统计结构是一个滑动窗口Sentinel 内部会尽可能复用 Resource 级别的全局滑动窗口,如果流控规则的统计设置没法复用Resource的全局统计结构,那么Sentinel为流量控制器创建一个全新的私有的滑动窗口,然后通过 flow.StandaloneStatSlot 这个统计Slot来维护统计指标。

2.1流控规则

type Rule struct {ID string `json:"id,omitempty"` //ID表示规则的唯一ID(可选)Resource               string                 `json:"resource"` //资源名字TokenCalculateStrategy TokenCalculateStrategy `json:"tokenCalculateStrategy"` //当前流量控制器的Token计算策略。Direct表示直接使用字段 Threshold 作为阈值;WarmUp表示使用预热方式计算Token的阈值。ControlBehavior        ControlBehavior        `json:"controlBehavior"`//表示流量控制器的控制策略;Reject表示超过阈值直接拒绝,Throttling表示匀速排队。Threshold         float64          `json:"threshold"`//表示流控阈值 RelationStrategy  RelationStrategy `json:"relationStrategy"`// 调用关系限流策略RefResource       string           `json:"refResource"` //关联的resourceMaxQueueingTimeMs uint32           `json:"maxQueueingTimeMs"` //匀速排队的最大等待时间WarmUpPeriodSec   uint32           `json:"warmUpPeriodSec"` //预热的时间长度WarmUpColdFactor  uint32           `json:"warmUpColdFactor"`//预热的因子,默认是3,该值的设置会影响预热的速度StatIntervalInMs uint32 `json:"statIntervalInMs"`//规则对应的流量控制器的独立统计结构的统计周期
}

补充:

如果字段StatIntervalInMs是1000(也就是1秒),那么Threshold就表示QPS,流量控制器也就会依据资源的QPS来做流控。

RelationStrategy: 调用关系限流策略,CurrentResource表示使用当前规则的resource做流控;AssociatedResource表示使用关联的resource做流控,关联的resource在字段 RefResource 定义;

这里特别强调一下 StatIntervalInMsThreshold 这两个字段,这两个字段决定了流量控制器的灵敏度。以 Direct + Reject 的流控策略为例,流量控制器的行为就是在 StatIntervalInMs 周期内,允许的最大请求数量是Threshold。比如如果 StatIntervalInMs 是 10000,Threshold 是10000,那么流量控制器的行为就是控制该资源10s内运行最多10000次访问。

2.2流量控制策略

由规则里的TokenCalculateStrategyControlBehavior 两个字段决定。

TokenCalculateStrategy 表示流量控制器的Token计算方式:

  1. Direct表示直接使用规则中的 Threshold 表示当前统计周期内的最大Token数量。
  2. WarmUp表示通过预热的方式计算当前统计周期内的最大Token数量,预热的计算方式会根据规则中的字段 WarmUpPeriodSecWarmUpColdFactor 来决定预热的曲线。

字段 ControlBehavior 表示表示流量控制器的控制行为:

  1. Reject:表示如果当前统计周期内,统计结构统计的请求数超过了阈值,就直接拒绝
  2. Throttling:表示匀速排队的统计策略。它的中心思想是,以固定的间隔时间让请求通过。当请求到来的时候,如果当前请求距离上个通过的请求通过的时间间隔不小于预设值,则让当前请求通过;否则,计算当前请求的预期通过时间,如果该请求的预期通过时间小于规则预设的 timeout 时间,则该请求会等待直到预设时间到来通过(排队等待处理);若预期的通过时间超出最大排队时长,则直接拒接这个请求。主要用于处理间隔性突发的流量,例如消息队列,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。

2.3流量控制器的统计结构

每个流量控制器实例都会有自己独立的统计结构。流量控制器的统计结构由规则中的 StatIntervalInMs 字段设置,StatIntervalInMs表示统计结构的统计周期。Sentinel 默认会为每个Resource创建一个全局的滑动窗口统计结构,这个全局的统计结构默认是一个间隔为10s,20个格子的滑动窗口,也就是每个统计窗口长度是500ms。

流量控制器实例会尽可能复用这个Resource级别的全局统计结构,复用逻辑原则是:优先复用Resource级别的全局统计结构,如果不可复用,就重新创建一个独立的滑动窗口统计结构(BucketLeapArray),具体的逻辑细节如下:

  1. 如果StatIntervalInMs大于全局滑动窗口的间隔(默认10s),那么将不可复用全局统计结构。Sentinel会给流量控制器创建一个长度是StatIntervalInMs,格子数是1的全新统计结构,这个全新的统计结构由Sentinel内部的StandaloneStatSlot来维护统计。
  2. 如果StatIntervalInMs小于全局滑动窗口的窗口长度(默认是500ms), 那么将不可复用全局统计结构。Sentinel会给流量控制器创建一个长度是StatIntervalInMs,格子数是1的全新统计结构,这个全新的统计结构由Sentinel内部的StandaloneStatSlot来维护统计。
  3. 如果StatIntervalInMs在集合[全局滑动窗口的窗口长度,全局滑动窗口的间隔]之间,首先需要计算格子数:如果StatIntervalInMs可以被全局滑动窗口的窗口长度(默认是500ms)整除,那么格子数就为 StatIntervalInMs/GlobalStatisticBucketLengthInMs,如果不可整除,格子数是1。然后会调用 core/base/CheckValidityForReuseStatistic函数来判断当前统计结构间隔和格子数是否可以复用全局统计结构。如果可以复用,就会基于resource级别的全局统计结构ResourceNode创建SlidingWindow,SlidingWindow是一个虚拟结构,SlidingWindow只可读,而且读的数据是通过聚合ResourceNode数据得到的。如果不可复用,就使用统计结构间隔和格子数创建全新的滑动窗口(BucketLeapArray)。

CheckValidityForReuseStatistic函数参考:https://github.com/alibaba/sentinel-golang/blob/master/core/base/stat.go#func CheckValidityForReuseStatistic

基于规则创建统计结构的逻辑参考:https://github.com/alibaba/sentinel-golang/blob/master/core/flow/rule_manager.go#func generateStatFor

2.4常见场景的规则配置

2.4.1基于QPS对某个资源限流

{Resource:                "some-test",TokenCalculateStrategy:  flow.Direct,ControlBehavior:         flow.Reject,Threshold:               500,StatIntervalInMs:        1000,
}

StatIntervalInMs必须是1000,表示统计周期是1s,那么Threshold所配置的值也就是QPS的阈值

2.4.2基于一定统计间隔时间来控制总的请求数

{Resource:                "some-test",TokenCalculateStrategy:  flow.Direct,ControlBehavior:         flow.Reject,Threshold:               10000,StatIntervalInMs:        10000,
}

在一定统计周期内控制请求的总量。比如上面的例子指的是在10000ms(10s)里的最大请求数是10000。但是对于脉冲类型流量的抵抗力很弱

2.4.3毫秒级别流控

如果一些流量在毫秒级别的波动很大,那建议StatIntervalInMs的配置在毫秒级别,除非特殊场景,建议配置的值为100ms的倍数,比如100,200这种。这种相当于缩小了统计周期,将QPS的周期缩小了10倍,控制周期降低到了100ms。这种配置能够很好的应对脉冲流量,保障系统稳定性,比如sample:

{Resource:                "some-test",TokenCalculateStrategy:  flow.Direct,ControlBehavior:         flow.Reject,Threshold:               80,StatIntervalInMs:        100,
}

上面限制了100ms的阈值是80,实际QPS大概是800。

注意:这种配置也是有缺点的,脉冲流量很大可能造成有损(会拒绝很多流量)。

2.4.4脉冲流量无损

针对前面第三点场景,如果既想控制流量曲线,又想无损,一般做法是通过匀速排队的控制策略,平滑掉流量。

2.4.5基于调用关系的流量控制

Sentinel 支持关联流量控制策略。当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写得速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢。

2.5 demo

示例

3. 熔断降级

现在的分布式架构里,一个服务常常会调用第三方服务,比如另一个RPC接口、数据库、API等。如果依赖的外部服务出现了不稳定的情况,比如请求的响应时间变长,那么服务自身调用第三方服务的响应时间也会变长,自身的线程可能会产生堆积,耗尽业务自身的线程池,最终服务本身也变得不可用。因此我们需要对不稳定的 弱依赖服务调用 进行 熔断降级,暂时切断不稳定的服务调用,避免局部不稳定因素导致整个分布式系统的雪崩。熔断降级作为保护服务自身的手段,通常在**客户端(调用端)**进行配置。
比如A服务需要调用B服务的接口,在A服务里需要配置熔断器,避免B服务不稳定从而拖垮A服务。

3.1 熔断器模型

熔断器内部维护了一个状态机:
在这里插入图片描述

  1. CLOSED状态:初始状态,熔断器保持闭合,对资源的访问通过熔断器的检查
  2. OPEN状态:断开状态,熔断器开启,切断对资源的访问
  3. HALF OPEN:半开状态,周期性的允许一定数目的探测请求通过。如果探测请求能够正常的返回,则探测成功,转换到CLOSED状态,结束熔断;探测失败,回滚到OPEN状态。

3.2 熔断器的设计

衡量下游服务质量,指标是RT、异常数量和异常比例等等。支持三种熔断策略:慢调用比例熔断、异常比例熔断和异常数量熔断
用户通过设置熔断规则(Rule)来给资源添加熔断器。Sentinel会将每一个熔断规则转换成对应的熔断器,熔断器对用户是不可见的。Sentinel 的每个熔断器都会有自己独立的统计结构。

熔断器的整体检查逻辑可以用几点来精简概括:

  1. 基于熔断器的状态机来判断对资源是否可以访问;
  2. 对不可访问的资源会有探测机制,探测机制保障了对资源访问的弹性恢复;
  3. 熔断器会在对资源访问的完成态去更新统计,然后基于熔断规则更新熔断器状态机。

3.3 熔断策略

静默期: 三种熔断策略都支持静默期,静默期指的是最小的静默请求数,在一个统计周期里,如果对资源的请求数小于设置的静默数,熔断器不会基于统计值去更改熔断器的状态
比如在统计周期刚开始的时候,第一个请求恰好是慢请求,这时候慢调用比例是100%,显然不合理。静默期提高了熔断器的精准性且降低了误判的可能性。
支持的几种熔断策略:(前提都是不在静默期)
**慢调用比例策略:**慢调用的比例大于设置的阈值,需要设置RT临界值(最大响应时间),对该资源访问的响应时间大于该阈值即为慢调用。
错误比例策略: 统计周期内资源请求访问异常的比例大于阈值。
错误计数策略: 请求访问异常数大于设定的阈值。

如果规则指定熔断器策略采用错误比例或则错误计数,那么为了统计错误比例或错误计数,需要调用API: api.TraceError(entry, err) 埋点每个请求的业务异常。

3.4 熔断降级规则定义

// Rule encompasses the fields of circuit breaking rule.
type Rule struct {Id string `json:"id,omitempty"`//全局唯一ID 可选Resource string   `json:"resource"` //资源名称Strategy Strategy `json:"strategy"` //熔断策略RetryTimeoutMs uint32 `json:"retryTimeoutMs"`//熔断出发后持续时间 msMinRequestAmount uint64 `json:"minRequestAmount"` //静默数量StatIntervalMs uint32 `json:"statIntervalMs"` //统计的时间窗口长度 msMaxAllowedRtMs uint64 `json:"maxAllowedRtMs"` //最大响应时间Threshold float64 `json:"threshold"` //阈值 
}

补充说明:
Strategy: 熔断策略,目前支持SlowRequestRatioErrorRatioErrorCount三种;

  • 选择以慢调用比例(SlowRequestRatio) 作为阈值,需要设置允许的最大响应时间(MaxAllowedRtMs),**请求的响应时间大于该值则统计为慢调用**。通过Threshold字段设置触发熔断的慢调用比例,取值范围为[0.0, 1.0]。规则配置后,**在单位统计时长内请求数目大于设置的最小请求数目(静默期),并且慢调用的比例大于阈值**,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求响应时间小于设置的最大 RT则结束熔断,若大于设置的最大RT` 则会再次被熔断。
  • 选择以错误比例 (ErrorRatio) 作为阈值,需要设置触发熔断的异常比例(Threshold),取值范围为 [0.0, 1.0]。规则配置后,在单位统计时长内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态,若接下来的一个请求没有错误则结束熔断,否则会再次被熔断。代码中可以通过 api.TraceError(entry, err) 函数来记录 error

Threshold: 对于慢调用熔断策略,Threshold表示是慢调用比例的阈值(小数表示,比如0.1表示10%),也就是如果当前资源的慢调用比例如果高于Threshold,那么熔断器就会断开;否则保持闭合状态。 对于错误比例策略,Threshold表示的是错误比例的阈值(小数表示,比如0.1表示10%)。对于错误数策略,Threshold是错误计数的阈值

ResourceStrategyRetryTimeoutMsMinRequestAmountStatIntervalMsThreshold 每个规则都必设的字段,MaxAllowedRtMs是慢调用比例熔断规则必设的字段。
MaxAllowedRtMs 字段仅仅对慢调用比例 (SlowRequestRatio) 策略有效,对其余策略均属于无效字段。
StatIntervalMs 表示熔断器的统计周期,单位是毫秒,这个值我们不建议设置的太大或则太小,一般情况下设置10秒左右都OK,当然也要根据实际情况来适当调整。
RetryTimeoutMs 的设置需要根据实际情况设置探测周期,一般情况下设置10秒左右都OK,当然也要根据实际情况来适当调整。

配置参考

// 慢调用比例规则
rule1 := &Rule{Resource:         "abc",Strategy:         SlowRequestRatio,RetryTimeoutMs:   5000,MinRequestAmount: 10,StatIntervalMs:   10000,MaxAllowedRtMs:   20,Threshold:        0.1,
},
// 错误比例规则
rule1 := &Rule{Resource:         "abc",Strategy:         ErrorRatio,RetryTimeoutMs:   5000,MinRequestAmount: 10,StatIntervalMs:   10000,Threshold:        0.1,
},
// 错误计数规则
rule1 := &Rule{Resource:         "abc",Strategy:         ErrorCount,RetryTimeoutMs:   5000,MinRequestAmount: 10,StatIntervalMs:   10000,Threshold:        100,
},

3.5 最佳场景实践

熔断器一般用于应用对外部资源访问时的保护措施。这里简单描述一些场景:

  • 分布式系统中降级:假设存在应用A需要调用应用B的接口(特别是一些对接外部公司或者业务的接口时候),那么一般用于A调用B的接口时的防护;
  • 数据库慢调用的防护: 假设应用需要读/写数据库,但是该读写SQL存在潜在慢SQL的可能性,那么可以对该读写接口做防护,当接口不稳定时候(存在慢SQL),那么基于熔断器做降级。
  • 也可以是应用中任意弱依赖接口做降级防护(即自动降级后不影响业务核心链路)。

3.6 demo

demo

4. 并发隔离控制

并发隔离控制是基于资源访问的并发协程数来控制对资源的访问,也就是控制资源访问的最大并发数,避免因为资源的异常导致协程耗尽。

4.1 隔离规则

// Rule describes the concurrency num control, that is similar to semaphore
type Rule struct {ID         string     `json:"id,omitempty"`Resource   string     `json:"resource"` //资源名称MetricType MetricType `json:"metricType"`//目标度量类型Threshold  uint32     `json:"threshold"`//阈值
}

配置示例:其中Concurrency表示并发数,如果资源的当前并发数超过阈值,资源将不可访问。

r1 := &Rule{Resource:   "abc",MetricType: Concurrency,Threshold:  100,
}

4.2 最佳实践场景

客户端(调用端) 做一层软隔离(并发隔离控制),达到对资源访问的并发控制的目的

4.3 demo

demo

package mainimport (sentinel "github.com/alibaba/sentinel-golang/api""github.com/alibaba/sentinel-golang/core/config""github.com/alibaba/sentinel-golang/core/isolation""github.com/alibaba/sentinel-golang/logging""math/rand""os""testing""time"
)func Test_concurrency_limitation(t *testing.T) {cfg := config.NewDefaultConfig()                     //生成默认配置cfg.Sentinel.Log.Logger = logging.NewConsoleLogger() //控制台日志err := sentinel.InitWithConfig(cfg)                  //初始化if err != nil {logging.Error(err, "fail")os.Exit(1)}logging.ResetGlobalLoggerLevel(logging.DebugLevel) //设置日志级别 debugch := make(chan struct{})                          //通道r1 := &isolation.Rule{ //定义规则Resource:   "abc",MetricType: isolation.Concurrency, //并发数Threshold:  12,                    //阈值} //并发数>12触发熔断器_, err = isolation.LoadRules([]*isolation.Rule{r1})if err != nil {logging.Error(err, "fail")os.Exit(1)}for i := 0; i < 15; i++ { //开辟15个协程go func() {for {e, b := sentinel.Entry("abc", sentinel.WithBatchCount(1)) //WithBatchCount 表示每次占用的资源个数if b != nil {                                             //限流logging.Info("[Isolation] Blocked", "reason", b.BlockType().String(), "rule", b.TriggeredRule(), "snapshot", b.TriggeredValue())time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)} else { //通过 处理业务逻辑logging.Info("[Isolation] Passed")time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)e.Exit() //务必要写!}}}()}<-ch //保证主进程不退出
}

在这里插入图片描述

5.源码

阿里 双11 同款,流量防卫兵 Sentinel go 源码解读
Sentinel-Go 源码系列(一)|开篇
Sentinel Go 核心统计结构滑动窗口的深度解析

相关文章:

【Sentinel Go】新手指南、流量控制、熔断降级和并发隔离控制

随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开…...

iOS自定义滚动条

引言 最近一直在做数据通信相关的工作&#xff0c;导致了UI上的一些bug一直没有解决。这两天终于能腾出点时间大概看了一下Redmine上的bug&#xff0c;发现有很多bug都是与系统滚动条有关系的。所以索性就关注一下这个小小的滚动条。 为什么要自定义ScrollIndictor 原有的Scrol…...

C++知识点2:把数据写进switch case结构,和写进json结构,在使用上有什么区别

将数据存储在Switch Case结构和JSON结构中有明显的区别&#xff0c;它们用于不同的目的和方式。以下是它们之间的主要区别&#xff1a; 1、用途和结构&#xff1a; Switch Case结构&#xff1a;Switch Case是一种条件语句&#xff0c;通常用于根据条件执行不同的代码块。它通常…...

肖sir__linux详解__003(vim命令)

linux 文本编辑命令 作用&#xff1a;用于编辑一个文件 用法&#xff1a;vim 文件名称 或者vi &#xff08;1&#xff09;编辑一个存在的文档 例子&#xff1a;编辑一个file1文件 vim aa &#xff08;2&#xff09;编辑一个文件不存在&#xff0c;会先创建文件&#xff0c;再…...

瑞芯微RK3588开发板:虚拟机yolov5模型转化、开发板上python脚本调用npu并部署 全流程

目录 0. 背景1. 模型转化1.1 基础环境1.2 创建python环境1.3 将yolov5s.pt转为yolov5s.onnx1.4 将yolov5s.onnx转为yolov5s.rknn 2. 开发板部署2.1. c版本2.1. python版本&#xff08;必须是python 3.9&#xff09; 3. 性能测试 0. 背景 全面国产化&#xff0c;用瑞芯微rk3588…...

【Redis专题】RedisCluster集群运维与核心原理剖析

目录 课程内容一、Redis集群架构模型二、Redis集群架构搭建&#xff08;单机搭建&#xff09;2.1 在服务器下新建各个节点的配置存放目录2.2 修改配置&#xff08;以redis-8001.conf为例&#xff09; 三、Java代码实战四、Redis集群原理分析4.1 槽位定位算法4.2 跳转重定位4.3 …...

我眼中的《视觉测量技术基础》

为什么会写这篇博客&#xff1a; 首先给大家说几点&#xff1a;看我的自我介绍对于学习这本书没有任何帮助&#xff0c;如果你是为了急切的想找一个视觉测量的解决方案那可以跳过自我介绍往下看或者换一篇博客看看&#xff0c;如果你是刚入门想学习计算机视觉的同学&#xff0…...

【Cisco Packet Tracer】管理方式,命令,接口trunk,VLAN

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

深入协议栈了解TCP的三次握手、四次挥手、CLOSE-WAIT、TIME-WAIT。

TCP网络编程的代码网上很多&#xff0c;这里就不再赘述&#xff0c;简单用一个图展示一下tcp网络编程的流程&#xff1a; 1、深入connect、listen、accept系统调用&#xff0c;进一步理解TCP的三次握手 这三个函数都是系统调用&#xff0c;我们可以分为请求连接方和被…...

接口自动化测试系列-yml管理测试用例

项目源码 目录结构及项目介绍 整体目录结构&#xff0c;目录说明参考 测试用例结构类似httprunner写法&#xff0c;可参考demo 主要核心函数 用例读取转换json import yaml import main import os def yaml_r():curpath f{main.BASE_DIR}/quality_management_logic/ops_ne…...

开源对象存储系统minio部署配置与SpringBoot客户端整合访问

文章目录 1、MinIO安装部署1.1 下载 2、管理工具2.1、图形管理工具2.2、命令管理工具2.3、Java SDK管理工具 3、MinIO Server配置参数3.1、启动参数&#xff1a;3.2、环境变量3.3、Root验证参数 4、MinIO Client可用命令 官方介绍&#xff1a; MinIO 提供高性能、与S3 兼容的对…...

Matlab之数组字符串函数汇总

一、前言 在MATLAB中&#xff0c;数组字符串是指由字符组成的一维数组。字符串可以包含字母、数字、标点符号和空格等字符。MATLAB提供了一些函数和操作符来创建、访问和操作字符串数组。 二、字符串数组具体怎么使用&#xff1f; 1、使用单引号或双引号括起来的字符序列 例…...

基于深度学习网络的火灾检测算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ................................................................................ load F…...

【Linux】高级IO和多路转接 | select/poll/epoll

多路转接和高级IO 咳咳&#xff0c;写的时候出了点问题&#xff0c;标点符号全乱了&#xff08;批量替换了几次&#xff09;&#xff0c;干脆就把全文的逗号和句号都改成英文的了&#xff08;不然代码块里面的代码都是中文标点就跑不动了&#xff09; 1.高级IO 1.1 五种IO模型…...

el-select 支持多选 搜索远程数据 组件抽取

el-select 支持多选 搜索远程数据 组件抽取 使用方式 import selectView from ./components/selectView<el-form><el-form-item label"选择器"><selectView v-model"selValue" change"handleChange"></el-form-item> …...

el-table纵向垂直表头

参考&#xff1a;https://www.jianshu.com/p/1f38eaffd070 <el-tablestyle"width: 100%":data"getValues":show-header"false"border:cell-style"cellStyle" ><el-table-columnv-for"(item, index) in getHeaders"…...

Pinyin4j介绍和简单使用

前言 Pinyin4j是一个Java库&#xff0c;用于将汉字转换为拼音。它是由中国清华大学的Tsinghua University和中国科学院计算技术研究所的研究人员开发的。Pinyin4j可以用于Java应用程序中&#xff0c;以便在需要时将汉字转换为拼音。例如&#xff0c;它可以用于中文输入法、文本…...

【数据结构】查找

【数据结构】查找 数据结构中&#xff0c;有顺序查找、二分查找、散列查找、插值查找、斐波那契额查找 1.顺序查找 条件&#xff1a;待查找的元素与数组中的元素按顺序排列。算法&#xff1a;从数组的第一个元素开始&#xff0c;逐个比较&#xff0c;直到找到目标元素或遍历完…...

第一次面试

1.多态的原理 2.编译原理 3.HTTPS的加密原理 4.说一说C11新特性 5.平时用过哪些STL容器 6.STL的比较器 原来就是自定义工具类hhhhhh 7.函数指针用过吗 8.I/O多路复用 9.Redis 问的基本都背过&#xff0c;但是一紧张啥都忘了hhhhhhhhh...

Nacos配置文件更新+热更新+多环境配置共享+集群搭建

对服务配置文件 场景&#xff1a; 如果多个服务对应的配置文件都需要更改时&#xff0c;可以利用配置管理&#xff0c;方便对配置文件进行更新&#xff0c;而且是在本地配置前先读取nacos的配置文件&#xff0c;优先级大于本地配置文件 配置步骤 1.首先在Nacos中的配置列表中增…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...