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

中间件(二)dubbo负载均衡介绍

一、负载均衡概述

支持轮询、随机、一致性hash和最小活跃数等。

1、轮询

① sequences:内部的序列计数器
② 服务器接口方法权重一样:(sequences+1)%服务器的数量=(决定调用)哪个服务器的服务。
③ 服务器接口方法权重不一样:找到最大权重(权重数)%(sequences+1),然后找出权重比该取模后的值大服务器列表,最后进行【①】所述。

2、随机

统计服务器上该接口的方法权重总和,然后对这个总和随机nextInt一下,看生成的随机数落到哪个段内,就调用哪个服务器上的该服务。

3、一致性hash

保证了同样的请求(参数)将会落到同一台服务器上。

4、最小活跃数

每个接口和接口方法都对应一个RpcStatus,记录它们的活跃数、失败等相关统计信息,调用时活跃数+1,调用结束时活跃数-1,所以活跃值越大,表明该提供者服务器的该接口方法耗时越长,而消费能力强的提供者接口往往活跃值很低。最少活跃负载均衡保证了“慢”提供者能接收到更少的服务器调用。

二、负载均衡策略配置

1、多注册中心集群负载均衡

在这里插入图片描述

2、Cluster Invoker

支持的选址策略如下(dubbo2.7.5+ 版本,具体使用请参见文档)

2-1、指定优先级

<!-- 来自 preferred=“true” 注册中心的地址将被优先选择,
只有该中心无可用地址时才 Fallback 到其他注册中心 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" preferred="true" />

2-2、同zone优先

<!-- 选址时会和流量中的 zone key 做匹配,流量会优先派发到相同 zone 的地址 -->
<dubbo:registry address="zookeeper://${zookeeper.address1}" zone="beijing" />

2-3、权重轮询

<!-- 来自北京和上海集群的地址,将以 10:1 的比例来分配流量 -->
<dubbo:registry id="beijing" address="zookeeper://${zookeeper.address1}" weight=”100“ />
<dubbo:registry id="shanghai" address="zookeeper://${zookeeper.address2}" weight=”10“ />

三、负载均衡解读

(1)负载均衡:AbstractClusterInvoker.invoke(final Invocation invocation)方法

@Override
public Result invoke(final Invocation invocation) throws RpcException {//...... 省略代码 List<Invoker<T>> invokers = list(invocation);LoadBalance loadbalance = initLoadBalance(invokers, invocation);RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);return doInvoke(invocation, invokers, loadbalance);
}
/** 获取负载均衡的实现方法,未配置时默认random */
protected LoadBalance initLoadBalance(List<Invoker<T>> invokers, Invocation invocation) {if (CollectionUtils.isNotEmpty(invokers)) {return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(invokers.get(0).getUrl().getMethodParameter(RpcUtils.getMethodName(invocation), LOADBALANCE_KEY, DEFAULT_LOADBALANCE));} else {return ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension(DEFAULT_LOADBALANCE);}
}

(2)实现入口:AbstractClusterInvoker.doSelect(…)

① 在dubbo中,所有负载均衡均继承 AbstractLoadBalance 类,该类实现了LoadBalance接口,并封装了一些公共的逻辑。

/** 1. LoadBalance.java接口 */
@SPI(RandomLoadBalance.NAME)
public interface LoadBalance {/*** select one invoker in list.** @param invokers   invokers.* @param url        refer url* @param invocation invocation.* @return selected invoker.*/@Adaptive("loadbalance")<T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) throws RpcException;
}
/** 2. AbstractLoadBalance.java 抽象类 */
@Override
public <T> Invoker<T> select(List<Invoker<T>> invokers, URL url, Invocation invocation) {if (CollectionUtils.isEmpty(invokers)) {return null;}// 如果invokers列表中仅一个Invoker,直接返回即可,无需进行负载均衡if (invokers.size() == 1) {return invokers.get(0);}// 调用doSelect方法进行负载均衡,该方法为抽象方法,由子类实现return doSelect(invokers, url, invocation);
}protected abstract <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation);

/** 2-1. 公共方法,权重计算逻辑 */

protected int getWeight(Invoker<?> invoker, Invocation invocation) {int weight;URL url = invoker.getUrl();// Multiple registry scenario, load balance among multiple registries.if (REGISTRY_SERVICE_REFERENCE_PATH.equals(url.getServiceInterface())) {weight = url.getParameter(REGISTRY_KEY + "." + WEIGHT_KEY, DEFAULT_WEIGHT);} else {// 从url中获取权重 weight配置值weight = url.getMethodParameter(invocation.getMethodName(), WEIGHT_KEY, DEFAULT_WEIGHT);if (weight > 0) {// 获取服务提供者启动时间戳long timestamp = invoker.getUrl().getParameter(TIMESTAMP_KEY, 0L);if (timestamp > 0L) {// 计算服务提供者运行时长long uptime = System.currentTimeMillis() - timestamp;if (uptime < 0) {return 1; // 未启动直接返回权重为1}// 获取服务预热时间,默认为10分钟int warmup = invoker.getUrl().getParameter(WARMUP_KEY, DEFAULT_WARMUP);// 如果服务运行时间小于预热时间,则重新计算服务权重,即降级if (uptime > 0 && uptime < warmup) {weight = calculateWarmupWeight((int)uptime, warmup, weight);}}}}return Math.max(weight, 0);
}

// 2-2. 重新计算服务权重

static int calculateWarmupWeight(int uptime, int warmup, int weight) {// 计算权重,下面代码逻辑上形似于 (uptime / warmup) * weight// 随着服务运行时间 uptime 增大,权重计算值 ww 会慢慢接近配置值 weightint ww = (int) ( uptime / ((float) warmup / weight));return ww < 1 ? 1 : (Math.min(ww, weight));
}

注:
select 方法的逻辑比较简单,首先会检测 invokers 集合的合法性,然后再检测 invokers 集合元素数量。如果只包含一个 Invoker,直接返回该 Inovker 即可。如果包含多个 Invoker,此时需要通过负载均衡算法选择一个 Invoker。具体的负载均衡算法由子类实现。
权重的计算主要用于保证当服务运行时长小于服务预热时间时,对服务进行降权,避免让服务在启动之初就处于高负载状态。服务预热是一个优化手段,与此类似的还有 JVM 预热。主要目的是让服务启动后“低功率”运行一段时间,使其效率慢慢提升至最佳状态。
配置方式(默认100):dubbo.provider.weight=300dubbo.provider.weight=300

② RandomLoadBalance 加权随机负载均衡
算法思路:根据权重比,随机选择哪台服务器,如:servers=[A,B,C],weights = [5, 3, 2],权重和为10,调用A的次数约有50%,B有30%,C有20%。

@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {// Number of invokersint length = invokers.size();// 判断是否需要权重负载均衡if (!needWeightLoadBalance(invokers,invocation)){return invokers.get(ThreadLocalRandom.current().nextInt(length));}// Every invoker has the same weight?boolean sameWeight = true;// the maxWeight of every invokers, the minWeight = 0 or the maxWeight of the last invokerint[] weights = new int[length];// The sum of weightsint totalWeight = 0;// ① 计算总权重,totalWeight;② 检测每个服务提供者的权重是否相同for (int i = 0; i < length; i++) {int weight = getWeight(invokers.get(i), invocation);// SumtotalWeight += weight;// save for later use// 如果权重分别为5,3,2,则weights[0]=5,weights[1]=8,weights[2]=10weights[i] = totalWeight;// 判断每个服务权重是否相同,如果不相同则sameWeight置为falseif (sameWeight && totalWeight != weight * (i + 1)) {sameWeight = false;}}// 各提供者服务权重不一样时,计算随机数落在哪个区间上if (totalWeight > 0 && !sameWeight) {// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on totalWeight.// 随机获取一个[0, totalWeight]区间内的随机的数字int offset = ThreadLocalRandom.current().nextInt(totalWeight);// Return a invoker based on the random value.for (int i = 0; i < length; i++) {// weights[0]=5,offset=[0, 5)// weights[1]=8,offset=[5, 8)// weights[2]=10,offset=[8, 10)if (offset < weights[i]) {return invokers.get(i);}}}// If all invokers have the same weight value or totalWeight=0, return evenly.// 如果所有服务提供者权重值相同,此时直接随机返回一个即可return invokers.get(ThreadLocalRandom.current().nextInt(length));
}

注:RandomLoadBalance的算法比较简单,多次请求后,能够按照权重进行“均匀“分配。调用次数少时,可能产生的随机数比较集中,此缺点并不严重,可以忽略。它是一个高效的负载均衡实现,因此Dubbo选择它作为缺省实现。

③ LeastActiveLoadBalance 加权最小活跃数负载均衡
活跃调用数越小,表明该服务提供者效率越高,单位时间内可处理更多的请求。此时应优先将请求分配给该服务提供者。
在具体实现中,每个服务提供者对应一个活跃数 active。初始情况下,所有服务提供者活跃数均为0。每收到一个请求,活跃数加1,完成请求后则将活跃数减1。
除了最小活跃数,LeastActiveLoadBalance 在实现上还引入了权重值。所以准确的来说,LeastActiveLoadBalance 是基于加权最小活跃数算法实现的。

@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {// Number of invokersint length = invokers.size();// The least active value of all invokers// 最小活跃数int leastActive = -1;// The number of invokers having the same least active value (leastActive)// 具有相同“最小活跃数”的服务提供者int leastCount = 0;// The index of invokers having the same least active value (leastActive)// leastIndexes 用于记录具有相同“最小活跃数”的 Invoker 在 invokers 列表中的下标信息int[] leastIndexes = new int[length];// the weight of every invokersint[] weights = new int[length];// The sum of the warmup weights of all the least active invokersint totalWeight = 0;// The weight of the first least active invoker// 第一个最小活跃数的 Invoker 权重值,用于与其他具有相同最小活跃数的 Invoker 的权重进行对比,// 以检测是否“所有具有相同最小活跃数的 Invoker 的权重”均相等int firstWeight = 0;// Every least active invoker has the same weight value?// 表示各服务的权重是否相同boolean sameWeight = true;// Filter out all the least active invokersfor (int i = 0; i < length; i++) {Invoker<T> invoker = invokers.get(i);// Get the active number of the invoker// 获取invoker对应的活跃数int active = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName()).getActive();// Get the weight of the invoker's configuration. The default value is 100.// 获取权重int afterWarmup = getWeight(invoker, invocation);// save for later useweights[i] = afterWarmup;// If it is the first invoker or the active number of the invoker is less than the current least active number// 发现更小的活跃数,重新开始if (leastActive == -1 || active < leastActive) {// Reset the active number of the current invoker to the least active number// 使用当前活跃数 active 更新最小活跃数 leastActiveleastActive = active;// Reset the number of least active invokersleastCount = 1;// Put the first least active invoker first in leastIndexes// 记录当前下标值到 leastIndexes 中leastIndexes[0] = i;// Reset totalWeighttotalWeight = afterWarmup;// Record the weight the first least active invokerfirstWeight = afterWarmup;// Each invoke has the same weight (only one invoker here)sameWeight = true;// If current invoker's active value equals with leaseActive, then accumulating.// 当前 Invoker 的活跃数 active 与最小活跃数 leastActive 相同} else if (active == leastActive) {// Record the index of the least active invoker in leastIndexes orderleastIndexes[leastCount++] = i;// Accumulate the total weight of the least active invoker// 累加权重totalWeight += afterWarmup;// If every invoker has the same weight?// 检测当前 Invoker 的权重与 firstWeight 是否相等,不相等则将 sameWeight 置为 falseif (sameWeight && afterWarmup != firstWeight) {sameWeight = false;}}}// Choose an invoker from all the least active invokers// 1. 当只有一个 Invoker 具有最小活跃数,此时直接返回该 Invoker 即可if (leastCount == 1) {// If we got exactly one invoker having the least active value, return this invoker directly.return invokers.get(leastIndexes[0]);}// 2. 有多个 Invoker 具有相同的最小活跃数,但它们之间的权重不同if (!sameWeight && totalWeight > 0) {// If (not every invoker has the same weight & at least one invoker's weight>0), select randomly based on // totalWeight.// 随机生成一个 [0, totalWeight) 之间的数字int offsetWeight = ThreadLocalRandom.current().nextInt(totalWeight);// Return a invoker based on the random value.for (int i = 0; i < leastCount; i++) {// 获取权重数组的下标int leastIndex = leastIndexes[i];// 随机权重 - 具有最小活跃数的 Invoker 的权重值offsetWeight -= weights[leastIndex];if (offsetWeight < 0) { // 与RandomLoadBalance一致,权重越大调用的次数越多return invokers.get(leastIndex);}}}// If all invokers have the same weight value or totalWeight=0, return evenly.// 如果权重相同或权重为0时,随机返回一个 Invokerreturn invokers.get(leastIndexes[ThreadLocalRandom.current().nextInt(leastCount)]);
}

④ ConsistentHashLoadBalance
cache-1、cache-2、cache-3、cache-4分别为不同的节点
根据IP或者其他信息为缓存节点生成一个hash,并将这个hash投射到[0,2^32 - 1] 的圆环上。当有查询或写入请求时,则为缓存项的key生成一个hash值。然后查找第一个大于或等于该hash值的缓存节点,并到这个节点中查询或写入缓存项。
如果当前节点挂了,则在下一次查询或写入缓存时,为缓存项查找另一个大于或其hash值的缓存节点即可。
如下图,每个节点在圆环上占据一个位置,如果缓存项的key的hash值小于缓存节点hash值,则到该缓存节点中存储或读取缓存项。
比如下面绿色点对应的缓存项将会被存储到 cache-2 节点中。由于 cache-3 挂了,原本应该存到该节点中的缓存项最终会存储到 cache-4 节点中。
请添加图片描述
⑤ RoundRobinLoadBalance
轮询:是指将请求轮流分配给每台服务器。
例如:有三台服务器A、B、C,我们将第一个请求分配给A服务器,第二个请求分配给B服务器,第三个请求分配给C服务器,第四个请求再次分配给A服务器,如此循环,这个过程叫做轮询(轮询是一种无状态负载均衡算法)。适用于每台服务器性能相近的场景下。
轮询加权:对每台性能不一样的服务器进行加权处理,如服务器A、B、C的权重分别为5:2:1时,在8次请求中,服务器A将收到5次请求、B收到2次请求、C收到一次请求(请求次数越多,每台服务器得到的请求数,接近服务器的权重比)。

@Override
protected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL url, Invocation invocation) {// key = [group/]path[:version].methodName;注:path = com.jyt.*.service.接口名String key = invokers.get(0).getUrl().getServiceKey() + "." + invocation.getMethodName();// 获取key对应值,如果key的值不存在,则将第二个参数的返回值存入并返回ConcurrentMap<String, WeightedRoundRobin> map = methodWeightMap.computeIfAbsent(key, k -> new ConcurrentHashMap<>());int totalWeight = 0;long maxCurrent = Long.MIN_VALUE;long now = System.currentTimeMillis();Invoker<T> selectedInvoker = null;WeightedRoundRobin selectedWRR = null;// 遍历服务提供者for (Invoker<T> invoker : invokers) {// dubbo://11.1.1.109:21001/com.jyt.*.service.类名String identifyString = invoker.getUrl().toIdentityString();// 获取当前服务提供者的权重int weight = getWeight(invoker, invocation);// 根据identifyString获取当前提供者对应的权重,如果不存在则使用第二个参数返回值,并返回WeightedRoundRobin weightedRoundRobin = map.computeIfAbsent(identifyString, k -> {WeightedRoundRobin wrr = new WeightedRoundRobin();wrr.setWeight(weight);return wrr;});// 如果提供者的权重被修改了,则更新weightedRoundRobin的权重值if (weight != weightedRoundRobin.getWeight()) {// weight changedweightedRoundRobin.setWeight(weight);}// current加上weight并获取结果(初始的current为0)long cur = weightedRoundRobin.increaseCurrent();/*** 如果A服务权重weight=500,B权重weight=100时,totalWeight = 600,初始cur=0;服务调用场景* 第一次:A服务器:cur=weight + curA = 500,cur > maxCurrent,所以maxCurrent = curA = 500*        B服务器:cur=weight + curB = 100 <= maxCurrent(500为true);故走A服务器,即curA = curA - 600 = -100** 第二次:A服务器:cur=weight + curA = 400,cur > maxCurrent,所以maxCurrent = curA = 400*        B服务器:cur=weight + curB = 200 <= maxCurrent(400为true);故走A服务器,即curA = curA - 600 = -200** 第三次:A服务器:cur=weight + curA = 300,cur > maxCurrent,所以maxCurrent = curA = 300*        B服务器:cur=weight + curB = 300 <= maxCurrent(300为true);故走A服务器,即curA = curA - 600 = -300** 第四次:A服务器:cur=weight + curA = 200,cur > maxCurrent,所以maxCurrent = curA = 200*        B服务器:cur=weight + curB = 400 <= maxCurrent(200为false);故走B服务器,即curB = curB - 600 = -200** 第五次:A服务器:cur=weight + curA = 700,cur > maxCurrent,所以maxCurrent = curA = 700*        B服务器:cur=weight + curB = -100 <= maxCurrent(700为true);故走A服务器,即curA = curA - 600 = 100** 第六次:A服务器:cur=weight + curA = 600,cur > maxCurrent,所以maxCurrent = curA = 600*        B服务器:cur=weight + curB = 0 <= maxCurrent(600为true);故走A服务器,即curA = curA - 600 = 0*        * ... ... 如此循环:A、A、A、B、A、A*/weightedRoundRobin.setLastUpdate(now);// 判断是否比最大的值大if (cur > maxCurrent) {// 如果大,则将当前服务提供者置为本次服务提供者maxCurrent = cur;selectedInvoker = invoker;selectedWRR = weightedRoundRobin;}// 权重累计totalWeight += weight;}// 当两者大小不一致时,map中可能会存在一些已经下线的服务,本次剔除一些很久节点信息if (invokers.size() != map.size()) {map.entrySet().removeIf(item -> now - item.getValue().getLastUpdate() > RECYCLE_PERIOD);}// 如果存在选择好的提供者,则改变他的current值 - totalWeight;if (selectedInvoker != null) {selectedWRR.sel(totalWeight);return selectedInvoker;}// should not happen herereturn invokers.get(0);
}

相关文章:

中间件(二)dubbo负载均衡介绍

一、负载均衡概述 支持轮询、随机、一致性hash和最小活跃数等。 1、轮询 ① sequences&#xff1a;内部的序列计数器 ② 服务器接口方法权重一样&#xff1a;&#xff08;sequences1&#xff09;%服务器的数量&#xff08;决定调用&#xff09;哪个服务器的服务。 ③ 服务器…...

springboot异步文件上传获取输入流提示找不到文件java.io.FileNotFoundException

springboot上传文件&#xff0c;使用异步操作处理上传的文件数据&#xff0c;出现异常如下&#xff1a; 这个是在异步之后使用传过来的MultipartFile对象尝试调用getInputStream方法发生的异常。 java.io.FileNotFoundException: C:\Users\Administrator\AppData\Local\Temp\to…...

安装jenkins-cli

1、要在 Linux 操作系统上安装 jcli curl -L https://github.com/jenkins-zh/jenkins-cli/releases/latest/download/jcli-linux-amd64.tar.gz|tar xzv sudo mv jcli /usr/local/bin/ 在用户根目录下&#xff0c;增加 jcli 的配置文件&#xff1a; jcli config gen -ifalse …...

linux通过NC工具启动临时端口监听

1.安装nc工具 yum install nc -y2. 启动监听指定端口 #例如监听8080端口 nc -lk 8080#后台监听 nc -lk 8080 &3. 验证 #通过另外一台网络能通的机器&#xff0c;telnet 该机器ip 监听端口能通&#xff0c;并且能接手数据 telnet 192.xxx.xxx.xx 8080...

开源语音聊天软件Mumble

网友 大气 告诉我&#xff0c;Openblocks在国内还有个版本叫 码匠&#xff0c;更贴合国内软件开发的需求&#xff0c;如接入了国内常用的身份认证&#xff0c;接入了国内的数据库和云服务&#xff0c;也对小程序、企微 sdk 等场景做了适配。 在 https://majiang.co/docs/docke…...

JDK 1.6与JDK 1.8的区别

ArrayList使用默认的构造方式实例 jdk1.6默认初始值为10jdk1.8为0,第一次放入值才初始化&#xff0c;属于懒加载 Hashmap底层 jdk1.6与jdk1.8都是数组链表 jdk1.8是链表超过8时&#xff0c;自动转为红黑树 静态方式不同 jdk1.6是先初始化static后执行main方法。 jdk1.8是懒加…...

单片机实训报告

这周我们进行了单片机实训&#xff0c;一周中我们通过七个项目1&#xff1a;P1 口输入/输出 2&#xff1a;继电器控制 3 音频控制 4&#xff1a;子程序设计 5&#xff1a;字符碰头程序设计 6&#xff1a;外部中断 7&#xff1a; 急救车与交通信号灯&#xff0c;练习编写了子程…...

【编织时空四:探究顺序表与链表的数据之旅】

本章重点 链表的分类 带头双向循环链表接口实现 顺序表和链表的区别 缓存利用率参考存储体系结构 以及 局部原理性。 一、链表的分类 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 1. 单向或者双向 2. 带头或者不带头 3. 循环或者非…...

PHP8的字符串操作1-PHP8知识详解

字符串是php中最重要的数据之一&#xff0c;字符串的操作在PHP编程占有重要的地位。在使用PHP语言开发web项目的过程中&#xff0c;为了实现某些功能&#xff0c;经常需要对某些字符串进行特殊的处理&#xff0c;比如字符串的格式化、字符串的连接与分割、字符串的比较、查找等…...

电脑提示msvcp140.dll丢失的解决方法,dll组件怎么处理

Windows系统有时在打开游戏或者软件时&#xff0c; 系统会弹窗提示缺少“msvcp140.dll.dll”文件 或者类似错误提示怎么办&#xff1f; 错误背景&#xff1a; msvcp140.dll是Microsoft Visual C Redistributable Package中的一个动态链接库文件&#xff0c;它在运行软件时提…...

stable diffusion基础

整合包下载&#xff1a;秋叶大佬 【AI绘画8月最新】Stable Diffusion整合包v4.2发布&#xff01; 参照&#xff1a;基础04】目前全网最贴心的Lora基础知识教程&#xff01; VAE 作用&#xff1a;滤镜微调 VAE下载地址&#xff1a;C站&#xff08;https://civitai.com/models…...

Greiner–Hormann裁剪算法深度探索:C++实现与应用案例

介绍 在计算几何中&#xff0c;裁剪是一个核心的主题。特别是&#xff0c;多边形裁剪已经被广泛地应用于计算机图形学&#xff0c;地理信息系统和许多其他领域。Greiner-Hormann裁剪算法是其中之一&#xff0c;提供了一个高效的方式来计算两个多边形的交集、并集等。在本文中&…...

Automatically Correcting Large Language Models

本文是大模型相关领域的系列文章&#xff0c;针对《Automatically Correcting Large Language Models: Surveying the landscape of diverse self-correction strategies》的翻译。 自动更正大型语言模型&#xff1a;综述各种自我更正策略的前景 摘要1 引言2 自动反馈校正LLM的…...

【学习FreeRTOS】第8章——FreeRTOS列表和列表项

1.列表和列表项的简介 列表是 FreeRTOS 中的一个数据结构&#xff0c;概念上和链表有点类似&#xff0c;列表被用来跟踪 FreeRTOS中的任务。列表项就是存放在列表中的项目。 列表相当于链表&#xff0c;列表项相当于节点&#xff0c;FreeRTOS 中的列表是一个双向环形链表列表的…...

分布式图数据库 NebulaGraph v3.6.0 正式发布,强化全文索引能力

本次 v3.6.0 版本&#xff0c;主要强化全文索引能力&#xff0c;以及优化部分场景下的 MATCH 性能。 强化 强化增强全文索引功能&#xff0c;具体 pr 参见&#xff1a;#5567、#5575、#5577、#5580、#5584、#5587 优化 支持使用 MATCH 子句检索 VID 或属性索引时使用变量&am…...

在 ubuntu 18.04 上使用源码升级 OpenSSH_7.6p1到 OpenSSH_9.3p1

1、检查系统已安装的当前 SSH 版本 使用命令 ssh -V 查看当前 ssh 版本&#xff0c;输出如下&#xff1a; OpenSSH_7.6p1 Ubuntu-4ubuntu0.7, OpenSSL 1.0.2n 7 Dec 20172、安装依赖&#xff0c;依次执行以下命令 sudo apt update sudo apt install build-essential zlib1g…...

python中可以处理word文档的模块:docx模块

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 话不多说&#xff0c;直接开搞&#xff0c;如果有什么疑惑/资料需要的可以点击文章末尾名片领取源码 一.docx模块 Python可以利用python-docx模块处理word文档&#xff0c;处理方式是面向对象的。 也就是说python-docx模块…...

TikTok或将于8月底关闭半闭环、速卖通或将推出“半托管”模式

《出海周报》是运营坛为外贸企业主和外贸人独家打造的重要资讯栏目&#xff0c;聚焦企业出海、海外市场动态、海外监管政策等方面&#xff0c;以简捷的方式&#xff0c;提升读者获取资讯的效率。 接下来运营坛为大家带来第15期出海周报&#xff0c;快来看看这周国内外市场发生了…...

《凤凰架构》第二章——访问远程服务

前言 这章挺难的&#xff0c;感觉离我比较远&#xff0c;不太好懂&#xff0c;简单记录吧。 这章主要讲访问远程服务&#xff0c;主要对比了RPC和REST的区别&#xff0c;可以结合知乎上的文章《既然有 HTTP 请求&#xff0c;为什么还要用 RPC 调用&#xff1f;》 这篇文章进行…...

【Diffusion】李宏毅2023机器学习Diffusion笔记

文章目录 1 想法概述2 实际过程阶段1 Add Noise阶段2 Denoise 3 数学原理4 为什么推理时要额外加入noise5 一些不知道对不对的Summary 1 想法概述 从一张充满噪声的图中不断denoise&#xff0c;最终得到一张clear的图片。为了确定当前图片中噪声占比的大小&#xff0c;同时输入…...

CloudEvents—云原生事件规范

我们的系统中或多或少都会用到如下两类业务技术&#xff1a; 异步任务&#xff0c;用于降低接口时延或削峰&#xff0c;提升用户体验&#xff0c;降低系统并发压力&#xff1b;通知类RPC&#xff0c;用于微服务间状态变更&#xff0c;用户行为的联动等场景&#xff1b; 以上两种…...

神经网络基础-神经网络补充概念-51-局部最优问题

概念 局部最优问题是在优化问题中常见的一个挑战&#xff0c;特别是在高维、非凸、非线性问题中。局部最优问题指的是算法在优化过程中陷入了一个局部最小值点&#xff0c;而不是全局最小值点。这会导致优化算法在某个局部区域停止&#xff0c;而无法找到更好的解。 解决方案…...

深度学习中,什么是batch-size?如何设置?

什么是batch-size? batch-size 是深度学习模型在训练过程中一次性输入给模型的样本数量。它在训练过程中具有重要的意义&#xff0c;影响着训练速度、内存使用以及模型的稳定性等方面。 以下是 batch-size 大小的一些影响和意义&#xff1a; 训练速度&#xff1a;较大的 bat…...

[保研/考研机试] KY26 10进制 VS 2进制 清华大学复试上机题 C++实现

题目链接&#xff1a; 10进制 VS 2进制http://www.nowcoder.com/share/jump/437195121691738172415 描述 对于一个十进制数A&#xff0c;将A转换为二进制数&#xff0c;然后按位逆序排列&#xff0c;再转换为十进制数B&#xff0c;我们称B为A的二进制逆序数。 例如对于十进制…...

JSP-学习笔记

文章目录 1.JSP介绍2 JSP快速入门3 JSP 脚本3.1 JSP脚本案例3.2 JSP缺点 4 EL表达式4.1 快速入门案例 5. JSTL标签6. MVC模式和三层架构6.1 MVC6.2 三层架构 7. 案例-基于MVC和三层架构实现商品表的增删改查 1.JSP介绍 概念 JSP&#xff08;JavaServer Pages&#xff09;是一种…...

Golang协程,通道详解

进程、线程以及并行、并发 关于进程和线程 进程&#xff08;Process&#xff09;就是程序在操作系统中的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;进程是一个动态概念&#xff0c;是程序在执行过程中分配和管理资源的基本单位&#xff0c;每一…...

unity 之 Vector 数据类型

文章目录 Vector 1Vector 2Vector 3Vector 4 Vector 1 在Unity中&#xff0c;Vector1 并不是一个常见的向量类型。 如果您需要表示标量&#xff08;单个值&#xff09;或者只需要一维的数据&#xff0c;通常会直接使用浮点数&#xff08;float&#xff09;或整数&#xff08;in…...

私密数据采集:隧道爬虫IP技术的保密性能力探究

作为一名专业的爬虫程序员&#xff0c;今天要和大家分享一个关键的技术&#xff0c;它能够为私密数据采集提供保密性能力——隧道爬虫IP技术。如果你在进行敏感数据采集任务时需要保护数据的私密性&#xff0c;那么这项技术将是你的守护神。 在进行私密数据采集任务时&#xff…...

使用git rebase 之后的如何恢复到原始状态

我们常常喜欢使用git rebase去切换分支提交代码,操作流程就是: 先切换分支:比如当前是master 我们修改了一堆代码产生一个commit id :5555555567777 那么我们常常比较懒就直接切换了:git checkout dev 然后呢?使用命令git rebase 5555555567777,想把这笔修改提交到d…...

matlab相机标定知识整理

matlab相机标定知识整理 单目相机标定 单目相机标定 内参矩阵&#xff1a;cameraParams.Intrinsics.K 或者 cameraParams.K旋转矩阵&#xff1a;cameraParams.RotationMatrices 有待确定 cameraParams.RotationVectors平移矩阵&#xff1a;cameraParams.TranslationVectors径向…...

win11安装ubuntu 子系统安装过程及注意事项

第一步 &#xff1a;安装系统必须组件 由于子系统是系统自带组件&#xff0c;需要安装软件支持 第二步&#xff1a;应用商店安装 ubuntu 编辑 编辑 这个时候打开会报错 第三步&#xff0c;运行linux子系统 选择Windows PowerShell 以管理员身份运行&#xff09; 输入&#…...

torch.cat((A,B),dim=1)解析

官方说明torch.cat 引用自&#xff1a;Pytorch中的torch.cat()函数 torch.cat(tensors, dim0, *, outNone) → Tensor # 连接给定维数的给定序列的序列张量。所有张量要么具有相同的形状(除了连接维度)&#xff0c;要么为空。示例 输入&#xff1a; import torch a torch.Tens…...

apache配置安全证书https踩坑记录

apache配置安全证书有如下几步 一、申请证书 这个网上有很多免费的&#xff0c;我用的是阿里云的服务器&#xff0c;在阿里云后台就可以申请免费证书。 二、上传证书 申请好证书后&#xff0c;根据服务器用的什么软件&#xff0c;是apache还是ngnix&#xff0c;下载相应的证书…...

SQL Server Express 自动备份方案

文章目录 SQL Server Express 自动备份方案前言方案原理SQL Server Express 自动备份1.创建存储过程2.设定计划任务3.结果检查sqlcmd 参数说明SQL Server Express 自动备份方案 前言 对于许多小型企业和个人开发者来说,SQL Server Express是一个经济实惠且强大的数据库解决方…...

Docker资源控制

目录 一、CPU 资源控制 1.设置CPU使用率上限 2.设置CPU资源占用比&#xff08;设置多个容器时才有效&#xff09; 3.设置容器绑定指定的CPU 二、对内存使用的限制 三、对磁盘IO配额控制&#xff08;blkio&#xff09;的限制 一、CPU 资源控制 cgroups&#xff0c;是一个非常强…...

微服务中间件-分布式缓存Redis

分布式缓存 a.Redis持久化1) RDB持久化1.a) RDB持久化-原理 2) AOF持久化3) 两者对比 b.Redis主从1) 搭建主从架构2) 数据同步原理&#xff08;全量同步&#xff09;3) 数据同步原理&#xff08;增量同步&#xff09; c.Redis哨兵1) 哨兵的作用2) 搭建Redis哨兵集群3) RedisTem…...

java面试强基(16)

目录 clone方法的保护机制 Java中由SubString方法是否会引起内存泄漏&#xff1f; Java中提供了哪两种用于多态的机制? 程序计数器(线程私有) 如何判断对象是否是垃圾&#xff1f; clone方法的保护机制 clone0方法的保护机制在Object中是被声明为 protected的。以User…...

Python可视化在量化交易中的应用(13)_Seaborn直方图

Seaborn中带核密度的直方图的绘制方法 seaborn中绘制直方图使用的是sns.histlot()函数&#xff1a; sns.histplot(data,x,y,hue,weights,stat‘count’,bins‘auto’,binwidth,binrange,discrete,cumulative,common_bins,common_norm,multiple‘layer’,element‘bars’,fill,…...

NOIP 2006 普及组 第二题 开心的金明

开心的金明 说明 金明今天很开心&#xff0c;家里购置的新房就要领钥匙了&#xff0c;新房里有一间他自己专用的很宽敞的房间。 更让他高兴的是&#xff0c;妈妈昨天对他说&#xff1a;“你的房间需要购买哪些物品&#xff0c;怎么布置&#xff0c;你说了算&#xff0c;只要不超…...

「UG/NX」Block UI 指定点SpecifyPoint

✨博客主页何曾参静谧的博客📌文章专栏「UG/NX」BlockUI集合📚全部专栏「UG/NX」NX二次开发「UG/NX」BlockUI集合「VS」Visual Studio「QT」QT5程序设计「C/C+&#...

Linux Shell如果ping失败就重启网卡(详解)

直接上脚本 -------------------------------------------------------------------------- #vi /tmp/ping_check.sh #!/bin/bash IP="1.1.1.1" PacketLoss=`ping -c 4 -w 4 1.1.1.1 | grep packet loss | awk -F packet loss {print $1} | awk {print $NF}|se…...

每天一道leetcode:剑指 Offer 13. 机器人的运动范围(中等广度优先遍历剪枝)

今日份题目&#xff1a; 地上有一个m行n列的方格&#xff0c;从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0]的格子开始移动&#xff0c;它每次可以向左、右、上、下移动一格&#xff08;不能移动到方格外&#xff09;&#xff0c;也不能进入行坐标和列坐标的数位之…...

TypeError: a bytes-like object is required, not ‘str‘

raceback (most recent call last): File "D:\pycharmcode\client.py", line 12, in <module> tcp_socket.send(send_data) TypeError: a bytes-like object is required, not str 使用socket进行ubuntu与windows通信时&#xff0c;发送数据时报了以上错…...

题解 | #1005.List Reshape# 2023杭电暑期多校9

1005.List Reshape 签到题 题目大意 按一定格式给定一个纯数字一维数组&#xff0c;按给定格式输出成二维数组。 解题思路 读入初始数组字符串&#xff0c;将每个数字分离&#xff0c;按要求输出即可 参考代码 参考代码为已AC代码主干&#xff0c;其中部分功能需读者自行…...

会声会影2023旗舰版电脑端视频剪辑软件

随着短视频、vlog等媒体形式的兴起&#xff0c;视频剪辑已经成为了热门技能。甚至有人说&#xff0c;不会修图可以&#xff0c;但不能不会剪视频。实际上&#xff0c;随着各种智能软件的发展&#xff0c;视频剪辑已经变得越来越简单。功能最全的2023新版&#xff0c;全新视差转…...

【linux基础(四)】对Linux权限的理解

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:Linux从入门到开通⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学更多操作系统知识   &#x1f51d;&#x1f51d; Linux权限 1. 前言2. shell命…...

maven项目指定数据源

springboot项目 直接在pom.xml文件中添加以下配置 <!--使用阿里云maven中央仓库--> <repositories><repository><id>aliyun-repos</id><url>http://maven.aliyun.com/nexus/content/groups/public/</url><snapshots><ena…...

web3:使用Docker-compose方式部署blockscout

最近做的项目,需要blockscout来部署一个区块链浏览器,至于blockscout是什么,咱们稍后出一篇文章专门介绍下,本次就先介绍一下如何使用Docker-compose方式部署blockscout,以及过程中遇到的种种坑 目录 先决条件我的环境准备工作Docker-compose1.安装方式一:下载 Docker Co…...

C++11实用技术(五)泛型编程加载dll接口函数

C11泛型编程简化加载dll代码 常见的加载dll方式&#xff1a; HMODULE m_hDataModule; m_hDataModule LoadLibrary("myDll.dll");typedef int (*PfunA)(int a, int b);//定义函数指针 PfunA fun (PfunA)(GetProcAddress(m_hDataModule , "funA"));//加载…...

使用wxPython和PyMuPDF提取PDF页面指定页数的内容的应用程序

在本篇博客中&#xff0c;我们将探讨如何使用wxPython和PyMuPDF库创建一个简单的Bokeh应用程序&#xff0c;用于选择PDF文件并提取指定页面的内容&#xff0c;并将提取的内容显示在文本框中。 C:\pythoncode\new\pdfgetcontent.py 准备工作 首先&#xff0c;确保你已经安装了…...