elasticsearch源码分析-03选举集群状态
选举集群状态
es中存储的数据有一下几种,state元数据、lucene索引文件、translog事务日志
元数据信息可以分为:
- 集群层面的元信息-对应着metaData数据结构,主要是clusterUUid、settings、templates等
- 索引层面的元信息-对应着indexMetaData数据结构,主要存储分片数量、mappings索引字段映射等
- 分片层面的元信息-对应着shardStateMetaData,主要是version、indexUUid、主分片等
每个节点可能会有不同的集群状态,需要选择正确的元数据作为权威源数据。状态信息的管理在gatewayService中,它实现了ClusterStateListener接口,当选择完主节点后会发布一个集群状态task,触发回调方法clusterChanged
//恢复分片分配状态
performStateRecovery(enforceRecoverAfterTime, reason);
集群层和索引层元数据恢复在gateway模块完成
public void clusterChanged(final ClusterChangedEvent event) {if (lifecycle.stoppedOrClosed()) {return;}final ClusterState state = event.state();//只有主节点才能执行if (state.nodes().isLocalNodeElectedMaster() == false) {// not our job to recoverreturn;}//已经执行过了集群状态和索引状态恢复了if (state.blocks().hasGlobalBlock(STATE_NOT_RECOVERED_BLOCK) == false) {// already recoveredreturn;}//这段省略主要是检查是否达到恢复状态条件......//恢复状态performStateRecovery(enforceRecoverAfterTime, reason);
}
首先判断只有主节点可以执行状态选举,然后判断是否已经在执行了状态恢复任务了,如果是则直接返回;如果没有则执行恢复状态任务
最终会调用recoveryRunnable.run()
final Gateway gateway = new Gateway(settings, clusterService, listGatewayMetaState);recoveryRunnable = () ->gateway.performStateRecovery(new GatewayRecoveryListener());
执行gateway的performStateRecovery方法
首先回去所有master资格的节点信息
//具有master资格的node节点final String[] nodesIds = clusterService.state().nodes().getMasterNodes().keys().toArray(String.class);
获取其他master节点的元数据
//获取集群及信息final TransportNodesListGatewayMetaState.NodesGatewayMetaState nodesState = listGatewayMetaState.list(nodesIds, null).actionGet();
这里我们看下TransportNodesListGatewayMetaState的构造函数
public TransportNodesListGatewayMetaState(ThreadPool threadPool, ClusterService clusterService, TransportService transportService,ActionFilters actionFilters, GatewayMetaState metaState) {super(ACTION_NAME, threadPool, clusterService, transportService, actionFilters,Request::new, NodeRequest::new, ThreadPool.Names.GENERIC, NodeGatewayMetaState.class);this.metaState = metaState;
}//注册action处理类
transportService.registerRequestHandler(actionName, executor, false, canTripCircuitBreaker, requestReader,new TransportHandler());
回到list方法,会调用doExecute方法
public ActionFuture<NodesGatewayMetaState> list(String[] nodesIds, @Nullable TimeValue timeout) {PlainActionFuture<NodesGatewayMetaState> future = PlainActionFuture.newFuture();execute(new Request(nodesIds).timeout(timeout), future);return future;
}protected void doExecute(Task task, NodesRequest request, ActionListener<NodesResponse> listener) {//执行new AsyncAction(task, request, listener).start();
}
发送所有节点获取元数据
void start() {final DiscoveryNode[] nodes = request.concreteNodes();if (nodes.length == 0) {//没有需要获取数据的node// nothing to notifythreadPool.generic().execute(() -> listener.onResponse(newResponse(request, responses)));return;}TransportRequestOptions.Builder builder = TransportRequestOptions.builder();if (request.timeout() != null) {builder.withTimeout(request.timeout());}//循环发送请求给所有节点for (int i = 0; i < nodes.length; i++) {final int idx = i;final DiscoveryNode node = nodes[i];final String nodeId = node.getId();try {TransportRequest nodeRequest = newNodeRequest(request);if (task != null) {nodeRequest.setParentTask(clusterService.localNode().getId(), task.getId());}//发送请求transportService.sendRequest(node, transportNodeAction, nodeRequest, builder.build(),new TransportResponseHandler<NodeResponse>() {@Overridepublic NodeResponse read(StreamInput in) throws IOException {return newNodeResponse(in);}//处理返回@Overridepublic void handleResponse(NodeResponse response) {onOperation(idx, response);}@Overridepublic void handleException(TransportException exp) {onFailure(idx, node.getId(), exp);}@Overridepublic String executor() {return ThreadPool.Names.SAME;}});} catch (Exception e) {onFailure(idx, nodeId, e);}}
}
对端接收请求后处理在上面注册的NodeTransportHandler,构造每个节点元数据返回
//node请求处理class NodeTransportHandler implements TransportRequestHandler<NodeRequest> {@Overridepublic void messageReceived(NodeRequest request, TransportChannel channel, Task task) throws Exception {channel.sendResponse(nodeOperation(request, task));}}protected NodeGatewayMetaState nodeOperation(NodeRequest request) {return new NodeGatewayMetaState(clusterService.localNode(), metaState.getMetadata());}
我们继续回到每个节点发送请求的返回处理
//处理返回
@Override
public void handleResponse(NodeResponse response) {onOperation(idx, response);
}private void onOperation(int idx, NodeResponse nodeResponse) {//记录node的返回结果responses.set(idx, nodeResponse);//当所有节点都返回结果了无论是失败还是成功了if (counter.incrementAndGet() == responses.length()) {finishHim();}
}private void finishHim() {NodesResponse finalResponse;try {finalResponse = newResponse(request, responses);} catch (Exception e) {logger.debug("failed to combine responses from nodes", e);listener.onFailure(e);return;}//触发监听回调listener.onResponse(finalResponse);
}
及获取到了其他节点的元数据,继续回到performStateRecovery
需要获取的master角色节点数
//需要分配数量
final int requiredAllocation = Math.max(1, minimumMasterNodes);
开始通过版本号选择集群层元数据,比较版本号,选择版本号最大的集群状态
//集群元数据
for (final TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) {if (nodeState.metadata() == null) {continue;}found++;if (electedGlobalState == null) {electedGlobalState = nodeState.metadata();//比较版本号大的胜出} else if (nodeState.metadata().version() > electedGlobalState.version()) {electedGlobalState = nodeState.metadata();}for (final ObjectCursor<IndexMetadata> cursor : nodeState.metadata().indices().values()) {indices.addTo(cursor.value.getIndex(), 1);}
}
检查是否有足够数量节点返回了集群状态
//没有获取足够的节点返回消息
if (found < requiredAllocation) {listener.onFailure("found [" + found + "] metadata states, required [" + requiredAllocation + "]");return;
}
构造集群状态,删除索引信息,下面会选择索引级元数据
//更新全局状态,清理索引,我们在下一阶段选择它们final Metadata.Builder metadataBuilder = Metadata.builder(electedGlobalState).removeAllIndices();
遍历所有节点选择返回的索引元数据版本最高的节点作为索引级元数据,然后将索引级元数据添加到metadataBuilder中
for (int i = 0; i < keys.length; i++) {if (keys[i] != null) {final Index index = (Index) keys[i];IndexMetadata electedIndexMetadata = null;int indexMetadataCount = 0;for (final TransportNodesListGatewayMetaState.NodeGatewayMetaState nodeState : nodesState.getNodes()) {if (nodeState.metadata() == null) {continue;}final IndexMetadata indexMetadata = nodeState.metadata().index(index);if (indexMetadata == null) {continue;}if (electedIndexMetadata == null) {electedIndexMetadata = indexMetadata;//比较版本号,选择最大版本号} else if (indexMetadata.getVersion() > electedIndexMetadata.getVersion()) {electedIndexMetadata = indexMetadata;}indexMetadataCount++;}if (electedIndexMetadata != null) {if (indexMetadataCount < requiredAllocation) {logger.debug("[{}] found [{}], required [{}], not adding", index, indexMetadataCount, requiredAllocation);} // TODO if this logging statement is correct then we are missing an else here//设置索引级元数据metadataBuilder.put(electedIndexMetadata, false);}}
}
构造恢复后的集群级元数据和索引级元数据
//恢复后的集群状态
ClusterState recoveredState = Function.<ClusterState>identity().andThen(state -> ClusterStateUpdaters.upgradeAndArchiveUnknownOrInvalidSettings(state, clusterService.getClusterSettings())).apply(ClusterState.builder(clusterService.getClusterName()).metadata(metadataBuilder).build());listener.onSuccess(recoveredState);
调用GatewayRecoveryListener的onSuccess向集群提交任务
class GatewayRecoveryListener implements Gateway.GatewayStateRecoveredListener {@Overridepublic void onSuccess(final ClusterState recoveredState) {logger.trace("successful state recovery, importing cluster state...");clusterService.submitStateUpdateTask("local-gateway-elected-state",new RecoverStateUpdateTask() {@Overridepublic ClusterState execute(final ClusterState currentState) {final ClusterState updatedState = ClusterStateUpdaters.mixCurrentStateAndRecoveredState(currentState, recoveredState);return super.execute(ClusterStateUpdaters.recoverClusterBlocks(updatedState));}});}@Overridepublic void onFailure(final String msg) {logger.info("state recovery failed: {}", msg);resetRecoveredFlags();}}
调用RecoverStateUpdateTask的execute方法
@Override
public ClusterState execute(final ClusterState currentState) {if (currentState.blocks().hasGlobalBlock(STATE_NOT_RECOVERED_BLOCK) == false) {logger.debug("cluster is already recovered");return currentState;}//状态信息恢复完成final ClusterState newState = Function.<ClusterState>identity().andThen(ClusterStateUpdaters::updateRoutingTable).andThen(ClusterStateUpdaters::removeStateNotRecoveredBlock).apply(currentState);//开始分配分片return allocationService.reroute(newState, "state recovered");
}
集群元数据和索引级元数据恢复完成开始分配分片
- 元数据的持久化
具有master资格的节点和数据节点可以持久化集群状态,当接收到集群状态变更时会将其持久化到磁盘GatewayClusterApplier实现了ClusterStateApplier,当集群状态变更时会调用applyClusterState方法
@Override
public void applyClusterState(ClusterChangedEvent event) {if (event.state().blocks().disableStatePersistence()) {incrementalClusterStateWriter.setIncrementalWrite(false);return;}try {// Hack: This is to ensure that non-master-eligible Zen2 nodes always store a current term// that's higher than the last accepted term.// TODO: can we get rid of this hack?if (event.state().term() > incrementalClusterStateWriter.getPreviousManifest().getCurrentTerm()) {incrementalClusterStateWriter.setCurrentTerm(event.state().term());}//更新磁盘上的元数据incrementalClusterStateWriter.updateClusterState(event.state());incrementalClusterStateWriter.setIncrementalWrite(true);} catch (WriteStateException e) {logger.warn("Exception occurred when storing new meta data", e);}
}
将集群级元数据和索引级元数据落盘
void updateClusterState(ClusterState newState) throws WriteStateException {//元数据Metadata newMetadata = newState.metadata();final long startTimeMillis = relativeTimeMillisSupplier.getAsLong();final AtomicClusterStateWriter writer = new AtomicClusterStateWriter(metaStateService, previousManifest);//全局元数据long globalStateGeneration = writeGlobalState(writer, newMetadata);//索引级元数据Map<Index, Long> indexGenerations = writeIndicesMetadata(writer, newState);Manifest manifest = new Manifest(previousManifest.getCurrentTerm(), newState.version(), globalStateGeneration, indexGenerations);writeManifest(writer, manifest);previousManifest = manifest;previousClusterState = newState;final long durationMillis = relativeTimeMillisSupplier.getAsLong() - startTimeMillis;final TimeValue finalSlowWriteLoggingThreshold = this.slowWriteLoggingThreshold;if (durationMillis >= finalSlowWriteLoggingThreshold.getMillis()) {logger.warn("writing cluster state took [{}ms] which is above the warn threshold of [{}]; " +"wrote metadata for [{}] indices and skipped [{}] unchanged indices",durationMillis, finalSlowWriteLoggingThreshold, writer.getIndicesWritten(), writer.getIndicesSkipped());} else {logger.debug("writing cluster state took [{}ms]; wrote metadata for [{}] indices and skipped [{}] unchanged indices",durationMillis, writer.getIndicesWritten(), writer.getIndicesSkipped());}
}
- 加载磁盘元数据
在node实例的start方法中会调用gatewayMetaState.start方法
//集群元数据
final GatewayMetaState gatewayMetaState = injector.getInstance(GatewayMetaState.class);
gatewayMetaState.start(settings(), transportService, clusterService, injector.getInstance(MetaStateService.class),injector.getInstance(MetadataIndexUpgradeService.class), injector.getInstance(MetadataUpgrader.class),injector.getInstance(PersistedClusterStateService.class));
然后会调用loadFullState方法
//加载元数据
manifestClusterStateTuple = metaStateService.loadFullState();public Tuple<Manifest, Metadata> loadFullState() throws IOException {//加载最新的状态文件final Manifest manifest = MANIFEST_FORMAT.loadLatestState(logger, namedXContentRegistry, nodeEnv.nodeDataPaths());if (manifest == null) {return loadFullStateBWC();}//构建元数据final Metadata.Builder metadataBuilder;if (manifest.isGlobalGenerationMissing()) {metadataBuilder = Metadata.builder();} else {final Metadata globalMetadata = METADATA_FORMAT.loadGeneration(logger, namedXContentRegistry, manifest.getGlobalGeneration(),nodeEnv.nodeDataPaths());if (globalMetadata != null) {metadataBuilder = Metadata.builder(globalMetadata);} else {throw new IOException("failed to find global metadata [generation: " + manifest.getGlobalGeneration() + "]");}}//索引级元数据for (Map.Entry<Index, Long> entry : manifest.getIndexGenerations().entrySet()) {final Index index = entry.getKey();final long generation = entry.getValue();final String indexFolderName = index.getUUID();final IndexMetadata indexMetadata = INDEX_METADATA_FORMAT.loadGeneration(logger, namedXContentRegistry, generation,nodeEnv.resolveIndexFolder(indexFolderName));if (indexMetadata != null) {metadataBuilder.put(indexMetadata, false);} else {throw new IOException("failed to find metadata for existing index " + index.getName() + " [location: " + indexFolderName +", generation: " + generation + "]");}}return new Tuple<>(manifest, metadataBuilder.build());
}
从磁盘读取构建索引级元数据和集群级元数据,用于构建集群状态对象ClusterState
相关文章:
elasticsearch源码分析-03选举集群状态
选举集群状态 es中存储的数据有一下几种,state元数据、lucene索引文件、translog事务日志 元数据信息可以分为: 集群层面的元信息-对应着metaData数据结构,主要是clusterUUid、settings、templates等索引层面的元信息-对应着indexMetaData数…...
MySQL 重要参数优化
max_connections = 3000 innodb_buffer_pool_size = 8G max_allowed_packet = 32M innodb_file_io_threads = 8 innodb_thread_concurrency = 16 innodb_flush_log_at_trx_commit = 2 innodb_log_buffer_size = 16M 参数说明 max_connections = 3000 运行MySQL的最大连…...
软件测试之接口测试(Postman/Jmeter)
🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 一、什么是接口测试 通常做的接口测试指的是系统对外的接口,比如你需要从别的系统来…...
14 卡尔曼滤波及代码实现
文章目录 14 卡尔曼滤波及代码实现14.0 基本概念14.1 公式推导14.2 代码实现 14 卡尔曼滤波及代码实现 14.0 基本概念 卡尔曼滤波是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据包括系统中的噪声和…...
计算机视觉 图像融合技术概览
在许多计算机视觉应用中(例如机器人运动和医学成像),需要将来自多幅图像的相关信息集成到一幅图像中。这种图像融合将提供更高的可靠性、准确性和数据质量。 多视图融合可以提高图像的分辨率,同时恢复场景的 3D 表示。多模态融合结合了来自不同传感器的图像,称为多传感器融…...
计算机网络课程实训:局域网方案设计与实现(基于ensp)
文章目录 前言基本要求操作分公司1分公司2总部核心交换机配置实现内部服务器的搭建acl_deny部分用户与服务器出口出口防火墙配置 前言 本篇文章是小编实训部分内容,内容可能会有错误,另外ensp对电脑兼容性及其挑剔,在使用之前一定要安装好。…...
【安全开发】内网扫描器
文章目录 前言现实现的功能较少后序开发会逐步加入简单漏洞探探测和代理功能。 一、开发过程1.项目结构2.main.go3.core模块3.1 scanner.go3.2 service.go 4.bruteforc4.1 bruteforce.go 二、使用步骤 前言 为什么要写这个? fscna被杀的概率太高(哪天二…...
ESP32-C3模组上跑通MQTT(5)
接前一篇文章:ESP32-C3模组上跑通MQTT(4) 本文内容参考: 《ESP32-C3 物联网工程开发实战》 一分钟了解MQTT协议 ESP32 MQTT API指南-CSDN博客 ESP-IDF MQTT 示例入门_mqtt outbox-CSDN博客 ESP32用自签CA进行MQTT的TLS双向认证通信_esp32 mqtt ssl-CSDN博客 特此致谢!…...
Arduino - LED 矩阵
Arduino - LED 矩阵 Arduino - LED Matrix LED matrix display, also known as LED display, or dot matrix display, are wide-used. In this tutorial, we are going to learn: LED矩阵显示器,也称为LED显示器,或点阵显示器,应用广泛。在…...
设计模式 - Observer Pattern 观察者模式
文章目录 定义观察者模式的实现构成构成UML图 观察者模式的代码实现场景代码实现 总结优点缺点应用场景 其他设计模式文章: 定义 观察者模式是行为型模式的一种,它定义对象间的一种一对多的依赖关系,使得每当一个对象改变状态,它…...
【面试系列】C++ 高频面试题
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、…...
程序猿大战Python——实现简单的图书馆系统操作
步骤1:安装和导入库 首先,确保已经安装了 pymysql 库。如果没有安装,请执行以下命令: pip install pymysql 然后,导入必要的库: import pymysql 步骤2:创建数据库和表的函数 编写一个函数来…...
液体粒子计数器的原理及常见型号选择 lighthouse代理商北京中邦兴业
液体颗粒计数用于测量液体样品中颗粒的大小和分布。通过用激光二极管照射液体样品并检测散射光来测量颗粒分布和尺寸。散射光的性质与粒子大小的大小有关。液体颗粒计数器可用于批量取样或在线(连续监测)应用,如水处理厂,或用于…...
Java知识点整理 16 — Spring Bean
在之前的文章 Java知识点整理 8 — Spring 简介 中介绍了 Spring 的两大核心概念 IoC 和 AOP,但对 Spring Bean 的介绍不全面,本文将补充 Spring 中 Bean 的概念。 一. 什么是 Spring Bean 在 Spring 官方文档中,对 bean 的定义为…...
Nvidia Jetson/RK3588+AI双目立体相机,适合各种割草机器人、扫地机器人、AGV等应用
双目立体视觉是基于视差原理,依据成像设备从不同位置获取的被测物体的图像,匹配对应点的位置偏移,得到视差数据,进而计算物体的空间三维信息。为您带来高图像质量的双目立体相机,具有高分辨率、低功耗、远距离等优点&a…...
springboot使用feign调用不依赖cloud
在使用spring boot调用第三方api中,常用的是okhttp、apache http client等,但是直接使用下来还是有点繁琐,需要手动转换实体。 在springcloud中有个openfeign调用,第一次体验到调用接口还能这么丝滑。注解写道接口上,…...
springboot中使用springboot cache
前言:SpringBoot中使用Cache缓存可以提高对缓存的开发效率 此图片是SpringBootCache常用注解 Springboot Cache中常用注解 第一步:引入依赖 <!--缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId…...
Promise,async/await的运用
一,了解Promise Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,它的出现避免了地狱回调。 (1)Promise的实例有三个状态: Pending(进行中) Re…...
图论·多源最短路径Floyddijsktra
例题地址 多源最短路径 多个源点多个终点可以使用Floyd算法直接求各源点到终点的最短距离,也可以直接多次使用dijsktra算法求单源点到终点的最短距离 Floyd算法 使用条件 多源最短路径权值正负皆可 核心思想:动态规划 子问题: 设(A,B)…...
微服务 | Springboot整合GateWay+Nacos实现动态路由
1、简介 路由转发 执行过滤器链。 网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。同时,基于Filter链的方式提供了网关的基本功能,比如:鉴权、流量控制、熔断、路径重写、黑白名单、日志监控等。 基本功能…...
做google SEO 有哪些好用的工具?这12款谷歌SEO工具值得收藏!
1、Google Trends 谷歌旗下一款基于搜索数据推出的一款免费分析工具 外贸人有句老话,七分靠选品,三分靠运营。在你开始做独立站之前,在你不清楚你的行业在Google上面能否有足够的流量时,那么Google Trends则是你最好的工具。 你只…...
【变频调速在锅炉引风机控制中的应用】
变频调速在锅炉引风机控制中的应用 变频器的选型 变频器是利用电力半导体器件的通断作用将工频电源变换为另一种频率的电能控制装置,能宏观对交流异步电机软启动,变频调速,提高运转精度,改变功率因数,过流/过压/过载保护等功能,国内技术较领先的品牌有汇川、欧瑞(原烟台…...
网络配置(IP、NETMASK、GATEWAY、DNS、DHCP) <持续更新中>
参考: 初学Linux之网络配置(IP、NETMASK、GATEWAY、DNS、DHCP)-CSDN博客【学习笔记】网关 & 路由_网关和路由-CSDN博客【学习笔记】计算机网络 IP地址与MAC地址_根据mac分配ip-CSDN博客【学习笔记】TCP 和 UDP 协议_tcp 发送 syn 应答没有syn ack-CSDN博客 一…...
【ArcGIS 脚本工具】拯救密恐,隐藏唯一值渲染图层的标记符号
最近拿到了【Hello 图狗】制作的三调/变更样式符号库,确实比之前网上下载的版本好用很多。 ArcGIS Pro三调23变更符号库V1.02(汇总)_中大比例尺.stylx和样式属性对调 不过使用过程中触发了一个旧病,就是匹配样式之后,…...
tensorflow学习1.3-创建会话,启动会话
tensorflow学习1.3-创建会话,启动会话 会话的由来与作用由来作用 会话的定义与结构定义 用法基本用法上下文管理器执行部分计算图获取多个结果 总结 练习代码报错原因:TensorFlow 2.x中的Eager Execution使用兼容模式来启用SessionEager Execution和计算…...
QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)
此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框(QFileDialog)、标准颜色对话框(QColorDialog)、标准字体对话框(QFontDialog)、标准输入对话框(QInputDialog)以及标…...
Docker 部署 MariaDB 数据库 与 Adminer 数据库管理工具
文章目录 MariaDBmariadb.cnf开启 binlog Adminerdocker-compose.ymlAdminer 连接 MariaDB MariaDB MariaDB是一个流行的开源关系型数据库管理系统(RDBMS),它是MySQL的一个分支和替代品。 官网:https://mariadb.com/镜像ÿ…...
qt 可以在一个函数中读一个文件,然后再将内容写入另一个文件中
是的,Qt 允许你在一个函数中读取一个文件的内容,并将这些内容写入到另一个文件中。这可以通过结合使用 QFile 和 QTextStream(或 QDataStream,取决于你的具体需求)来实现。以下是一个简单的示例,展示了如何…...
Dijkstra算法C代码
一个带权图n个点m条边,求起点到终点的最短距离 先定义一个邻接矩阵graph,graph[i][j]表示从i到j的距离,i到j没有路就表示为无穷 然后定义一个visit数组,visit[i]表示i结点是否被访问 然后定义一个dist数组,dist[i]表…...
P1064 [NOIP2006 提高组] 金明的预算方案
[NOIP2006 提高组] 金明的预算方案 题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置࿰…...
大型企业组网如何规划网络
大型企业组网是一个复杂的过程,它需要细致的规划和设计,以确保网络能够满足企业的业务需求,同时保证性能、安全性和可扩展性。以下是规划大型企业网络的一些关键步骤和考虑因素: 1. 需求分析 业务需求:与各个业务部门…...
java:aocache的单实例缓存(二)
之前一篇博客《java:aocache的单实例缓存》介绍了aoocache使用注解AoCacheable实现单实例缓存的方式,同时也指出了这种方式的使用限制,就是这个注解定义的构造方法,不能再创建出新实例。 为了更灵活方便的实现单实例。aocache最新版本0.4.0增…...
ElasticSearch安装部署
简介 Elasticsearch 是一个开源的分布式搜索和分析引擎,用于实时地存储、检索和分析大数据量。它基于 Apache Lucene 搜索引擎库构建而成,提供了一个强大、稳定且易于扩展的搜索解决方案。 主要特点和用途: 分布式存储和搜索: E…...
数据赋能(132)——开发:数据转换——影响因素、直接作用、主要特征
影响因素 数据转换过程中需要考虑的一些影响因素: 数据格式与结构: 不同系统或应用可能使用不同的数据格式(如JSON、XML、CSV等)和数据结构(如关系型数据库、非关系型数据库等)。数据转换需要确保原始数据…...
TMGM:ASIC撤销禁令,TMGM强化合规、重启差价合约服务
TMGM作为差价合约(CFDs)与保证金外汇交易领域的领航者,安全、合规、高效被奉为我集团的终身使命。澳大利亚证券和投资委员会(ASIC)已正式撤销了早前针对TMGM差价合约业务实施的临时止损令。这一误会的解除,…...
基于SpringBoot网吧管理系统设计和实现(源码+LW+调试文档+讲解等)
💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 Java精品实战案例《600套》 2025-2026年最值得选择的Java毕业设计选题大全࿱…...
实测2024年最佳的三款Socks5代理IP网站
一、引言 在浩瀚的网络世界中,Socks5代理IP服务如同导航灯塔,指引我们穿越数据海洋,安全、稳定地访问目标网站。作为专业的测评团队,我们深知一款优秀的Socks5代理IP网站需要具备哪些特质:稳定的IP资源、高效的连接速…...
Pythonnet能导入clr,但无法引入System模块?
【pythonnet详解】—— Python 和 .NET 互操作的库_pythonnet 详细使用-CSDN博客 Python中动态调用C#的dll动态链接库中方法_python 如何调用c# dll-CSDN博客 需求:Python调用并传List<float>类型参数给.Net 起初:直接 # 创建一个Python浮点数…...
媒体宣发套餐的概述及推广方法-华媒舍
在今天的数字化时代,对于产品和服务的宣传已经变得不可或缺。媒体宣发套餐作为一种高效的宣传方式,在帮助企业塑造品牌形象、扩大影响力方面扮演着重要角色。本文将揭秘媒体宣发套餐,为您呈现一条通往成功的路。 1. 媒体宣发套餐的概述 媒体…...
Windows和Linux C++判断磁盘空间是否充足
基本是由百度Ai写代码生成的,记录一下。实现此功能需要调用系统的API函数。 对于Windows,可调用函数GetDiskFreeSpaceEx,使用该函数需要包含头文件windows.h。该函数的原型: 它的四个参数: lpDirectoryName࿰…...
数据访问层如何提取数据到其他层,其他类中
当然可以,以下是一些具体的例子,展示了如何将数据库访问逻辑封装在一个单独的类中,并在其他类中使用这个类来获取数据。 数据库访问类(DatabaseAccess.java): java复制代码 import java.sql.*; import ja…...
【JS】AI总结:JavaScript中常用的判空方法
在JavaScript中,判空是一个常见的操作,因为变量可能未定义、未初始化或包含特定的空值。以下是JavaScript中常用的判空方法: 使用if语句直接判断: 如果变量是null、undefined、0、NaN、空字符串(""ÿ…...
Rust单元测试、集成测试
单元测试、集成测试 在了解了如何在 Rust 中写测试用例后,本章节我们将学习如何实现单元测试、集成测试,其实它们用到的技术还是上一章节中的测试技术,只不过对如何组织测试代码提出了新的要求。 单元测试 单元测试目标是测试某一个代码单…...
vue全局方法plugins/utils
一、在src目录下创建一个plugins文件夹 test.ts文件存放创建的方法,index.ts用于接收所有自定义方法进行统一处理 二、编写自定义方法 // test.ts文件 export default {handleTest(val1: number, val2: number) {// 只是一个求和的方法return val1 val2;}, };三…...
高阶算法班从入门到精通之路
课程介绍 本课程旨在帮助学员深入理解算法与数据结构的核心概念,从而掌握高级算法设计与分析技能。每集课程内容精心设计,涵盖了常用数据结构、经典算法及其应用场景等方面的深度讲解,同时通过大量实例演练,帮助学员提升解决实际…...
C++ 左值右值
文章目录 概述左值右值右值引用左值和右值的互换 小结 概述 左值和右值属于2中不同的表达式类型;它们在表达式中扮演不同的角色,特别是在赋值操作和函数参数传递中。 左值 定义:左值是指那些在内存中有确定位置的表达式,可以出…...
[数据集][目标检测]水面垃圾水面漂浮物检测数据集VOC+YOLO格式3749张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):3749 标注数量(xml文件个数):3749 标注数量(txt文件个数):3749 标注…...
[深度学习] 卷积神经网络CNN
卷积神经网络(Convolutional Neural Network, CNN)是一种专门用于处理数据具有类似网格结构的神经网络,最常用于图像数据处理。 一、CNN的详细过程: 1. 输入层 输入层接收原始数据,例如一张图像,它可以被…...
区别QPushButton和QToolButton
在刚开始学习Qt时,可能很难理解QPushButton和QToolButton之间的区别。 QToolButton通常用于QToolBar中,常常只显示图标,而不显示文本。那么,它们的主要区别是什么?什么时候应该使用QPushButton,什么时候应该使用QToolButton? 了解这一点很重要,这样我们才能选择最合适…...
【Python】已解决:TypeError: Object of type JpegImageFile is not JSON serializable
文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决:TypeError: Object of type JpegImageFile is not JSON serializable 一、分析问题背景 在进行Python编程时,特别是处理图像数据和JSON序列化时&…...
vscode连接SSH
1、安装Remote-SSH插件 2、点击左下角,选择SSH 3、点击连接到主机后,添加新的SSH主机,示例ssh 用户ip 4、点击服务器,输入密码登录服务器 5、可在远程资源管理器选项卡中查看 6、可以在ssh设置中打开ssh配置文件 config中的文件…...
第T3周:天气识别
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 一、前期工作 本文将采用CNN实现多云、下雨、晴、日出四种天气状态的识别。较上篇文章,本文为了增加模型的泛化能力,新增了Dropout层并…...
【echarts】拖拽滑块dataZoom-slider自定义样式,简单适配移动端
电脑端 移动端 代码片段 dataZoom: [{type: inside,start: 0,end: 100},{type: slider,backgroundColor: #F2F5F9,fillerColor: #BFCCE3,height: 13, // 设置slider的高度为15start: 0,end: 100,right: 60,left: 60,bottom: 15,handleIcon:path://M30.9,53.2C16.8,53.2,5.3,41.…...
为什么我感觉 C 语言在 Linux 下执行效率比 Windows 快得多?
在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「Linux的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!Windows的终端或者叫控制台…...
golang template模板 template: xxx.html is an incomplete or empty template 解决方法
当我们在使用go语言中的template渲染多个模板文件时,如果我们使用的模板文件没有使用 ParseFiles方法进行解析就直接在模板里面使用 template进行嵌套的话就会出现 template: xxx.html is an incomplete or empty template 的异常。 解决方法: 在我们使…...
[数据集][目标检测]金属架螺栓螺丝有无检测数据集VOC+YOLO格式857张3类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):857 标注数量(xml文件个数):857 标注数量(txt文件个数):857 标注类别…...
那么大的一个车卖24.9万?一起来看24款大众途昂
记得大众途昂刚上市的时候,所有看到这台车的人都会由衷感叹——“这车可真大”,那时的途昂还算是大众旗下偏高端的SUV,售价还要30多万起步。而如今,途昂还是那么大,但地位已不比当年,而且起售价格已经来到了24.9万。随着近年来汽车价格战的愈演愈烈,相比前几年,我们手持…...
售4.99万元起,外观简约动感,新款奇瑞瑞虎3x惠民版实车亮相!
近日,奇瑞旗下小型SUV——新款奇瑞瑞虎3x惠民版实车亮相!共推出了3款车型,售价4.99万元起,外观简约动感,产品力如何呢?解析奉上!首先来看动力部分,新车搭载的是1.5升自然吸气发动机,最大功率85千瓦,峰值扭矩143牛米,匹配的是5速手动变速箱和CVT无级变速箱。再来看颜…...
老款不停售?全新大众帕萨特有望今年内上市车长超5米
据国内媒体报道,上汽大众旗下的全新一代帕萨特车型有望于今年下半年上市,新车可能会被命名为帕萨特PRO,在外形方面会有比较大的幅度的变动,尺寸也有所增加。不过新车上市之后,现款帕萨特可能并不会停售,而是两代同堂销售。这意味着帕萨特PRO的定位应该会比现款帕萨特更高…...
快解析动态域名解析,实现外网访问内网数据库
今天跟大家分享一下如何借助快解析动态域名解析,在两种特定网络环境下,实现外网访问内网mysql数据库。 第1种网络环境:路由器分配的是动态公网IP,且有路由器登录管理权限。如何实现外网访问内网mysql数据库? 针对这种…...
【Numpy】NumPy基础入门:创建和管理多维数组
NumPy基础入门:创建和管理多维数组 简介 NumPy(Numerical Python的简称)是Python语言的一个基础科学计算库,广泛应用于数据分析、机器学习、科学计算和工程领域。NumPy的核心是其强大的N维数组对象ndarray,它为Pytho…...
突然宣布:将关停!曾用户过亿
ICQ官宣将于6月26日正式关闭,这也表明其上线运营近28年后,即将成为历史。ICQ宣布停止运营。1996年,三个以色列人开发了一款划时代的聊天软件“ICQ”,意思是“I SEEK YOU(我找你)”,其正式推出时间为当年11月。1998年底,ICQ被美国在线以4.07亿美元收购,此时其用户数超过…...