Elasticsearch 8.9 服务端接收创建索引和查询索引信息源码

  • 一、创建索引
    • 1、接收创建索引的RestCreateIndexAction
    • 2、Master执行创建索引的类TransportCreateIndexAction
    • 3、创建一个任务(创建索引的),放入一个队列
    • 4、执行创建索引时会先搜索模版
    • 5、创建索引的build,更新集群状态
      • (1) initializeEmpty初始化索引的分片,副本等
      • (2) 添加索引信息到indicesRouting
      • (3) 创建一个新的集群状态返回
  • 二、查询索引信息
    • 1 接收查询索引信息的RestCreateIndexAction
    • 2、实际查询的TransportGetIndexAction.java的doMasterOperation方法
      • (1)查询的索引信息都是从集群状态中ImmutableOpenMap<String, IndexMetadata>得到的

至于下面创建索引和查询索引信息的入口如何找到的,可以Elasticsearch 8.9启动时构建接收Rest请求的hander过程源码

一、创建索引

1、接收创建索引的RestCreateIndexAction

public class RestCreateIndexAction extends BaseRestHandler {@Overridepublic List<Route> routes() {return List.of(new Route(PUT, "/{index}"));}@Overridepublic RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {CreateIndexRequest createIndexRequest;//下面是区分es7和es8,创建索引的结构有一点区别,但是不用细究if (request.getRestApiVersion() == RestApiVersion.V_7) {createIndexRequest = prepareRequestV7(request);} else {createIndexRequest = prepareRequest(request);}//这个会通知让master执行创建索引操作return channel -> client.admin().indices().create(createIndexRequest, new RestToXContentListener<>(channel));}
}    

channel -> client.admin().indices().create(createIndexRequest, new RestToXContentListener<>(channel))至于这个如何通知master执行的,可以看一下Elasticsearch 8.9 Master节点处理请求源码

2、Master执行创建索引的类TransportCreateIndexAction

@Overrideprotected void masterOperation(Task task,final CreateIndexRequest request,final ClusterState state,final ActionListener<CreateIndexResponse> listener) {createIndexService.createIndex(updateRequest,listener.map(response -> new CreateIndexResponse(response.isAcknowledged(), response.isShardsAcknowledged(), indexName)));}
    / *在集群状态下创建索引,并等待指定数量的分片副本变为活动状态(如 {@link CreateIndexClusterStateUpdateRequestwaitForActiveShards()} 中指定),然后再在侦听器上发送响应。* 如果索引创建已成功应用于集群状态,则 {@link ShardsAcknowledgedResponseisAcknowledged()} 将返回 true* 否则它将返回 false,并且不会等待启动的分片({@link ShardsAcknowledgedResponseisShardsAcknowledged()} 也将为 false)。* 如果集群状态下的索引创建成功,并且在超时之前启动了必要的分片副本,则 {@link ShardsAcknowledgedResponseisShardsAcknowledged()} 将返回 true* 否则如果操作超时,则返回 false*/public void createIndex(final CreateIndexClusterStateUpdateRequest request, final ActionListener<ShardsAcknowledgedResponse> listener) {logger.trace("createIndex[{}]", request);onlyCreateIndex(request, listener.delegateFailureAndWrap((delegate, response) -> {//如果确认创建索引,则等待活动分片的数量满足要求。if (response.isAcknowledged()) {//省略代码//等待索引的分片活跃ActiveShardsObserver.waitForActiveShards(clusterService,new String[] { request.index() },request.waitForActiveShards(),request.ackTimeout(),delegate.map(shardsAcknowledged -> {//省略代码return ShardsAcknowledgedResponse.of(true, shardsAcknowledged);}));} else {//如果超时等待分片启动,记录日志。//最后返回一个ShardsAcknowledgedResponse对象,表示索引创建没有成功。logger.trace("index creation not acknowledged for [{}]", request);delegate.onResponse(ShardsAcknowledgedResponse.NOT_ACKNOWLEDGED);}}));}

3、创建一个任务(创建索引的),放入一个队列

 private void onlyCreateIndex(final CreateIndexClusterStateUpdateRequest request, final ActionListener<AcknowledgedResponse> listener) {//省略代码//调用submitUnbatchedTask方法提交一个任务。该任务是一个AckedClusterStateUpdateTask对象,该对象继承自ClusterStateUpdateTask类,用于执行集群状态更新任务。submitUnbatchedTask("create-index [" + request.index() + "], cause [" + request.cause() + "]",new AckedClusterStateUpdateTask(Priority.URGENT, request, delegate.clusterStateUpdate()) {//在execute方法中,会调用applyCreateIndexRequest方法来处理创建索引的请求。@Overridepublic ClusterState execute(ClusterState currentState) throws Exception {return applyCreateIndexRequest(currentState, request, false, null, delegate.reroute());}//省略代码});}
private void submitUnbatchedTask(@SuppressWarnings("SameParameterValue") String source, ClusterStateUpdateTask task) {clusterService.submitUnbatchedStateUpdateTask(source, task);}
 @Deprecated@SuppressForbidden(reason = "this method is itself forbidden")public void submitUnbatchedStateUpdateTask(String source, ClusterStateUpdateTask updateTask) {masterService.submitUnbatchedStateUpdateTask(source, updateTask);}
@Deprecatedpublic void submitUnbatchedStateUpdateTask(String source, ClusterStateUpdateTask updateTask) {createTaskQueue("unbatched", updateTask.priority(), unbatchedExecutor).submitTask(source, updateTask, updateTask.timeout());}

createTaskQueue返回的队列再执行submitTask方法

 public <T extends ClusterStateTaskListener> MasterServiceTaskQueue<T> createTaskQueue(String name,Priority priority,ClusterStateTaskExecutor<T> executor) {return new BatchingTaskQueue<>(name,this::executeAndPublishBatch,insertionIndexSupplier,queuesByPriority.get(priority),executor,threadPool);}
 @Overridepublic void submitTask(String source, T task, @Nullable TimeValue timeout) {final var executed = new AtomicBoolean(false);final Scheduler.Cancellable timeoutCancellable;if (timeout != null && timeout.millis() > 0) {timeoutCancellable = threadPool.schedule(new TaskTimeoutHandler(timeout, source, executed, task),timeout,ThreadPool.Names.GENERIC);} else {timeoutCancellable = null;}queue.add(new Entry<>(source,task,insertionIndexSupplier.getAsLong(),threadPool.relativeTimeInMillis(),executed,threadPool.getThreadContext().newRestorableContext(true),timeoutCancellable));if (queueSize.getAndIncrement() == 0) {perPriorityQueue.execute(processor);}}

4、执行创建索引时会先搜索模版

public ClusterState applyCreateIndexRequest(ClusterState currentState,CreateIndexClusterStateUpdateRequest request,boolean silent,BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer,ActionListener<Void> rerouteListener) throws Exception {//对请求的设置进行规范化和验证。//省略代码//并尝试匹配v2模板final String v2Template = MetadataIndexTemplateService.findV2Template(currentState.metadata(),name,isHiddenFromRequest != null && isHiddenFromRequest);//如果找到了v2模板,则使用该模板和请求指定的设置创建索引。if (v2Template != null) {return applyCreateIndexRequestWithV2Template(currentState,request,silent,v2Template,metadataTransformer,rerouteListener);} else {          //没有找到v2模板,则检查v1模板,如果没有找到任何模板,则使用请求指定的索引设置创建索引。final List<IndexTemplateMetadata> v1Templates = MetadataIndexTemplateService.findV1Templates(currentState.metadata(),request.index(),isHiddenFromRequest);//如果v1Templates不存在,则根据请求指定的索引设置创建索引(下面的v1Templates的size为0)return applyCreateIndexRequestWithV1Templates(currentState,request,silent,v1Templates,metadataTransformer,rerouteListener);}}

这里是因为模版版本的不同,因为模版不一样,所以需要把请求中的索引信息和模版中的索引信息合并一下,最后调用applyCreateIndexWithTemporaryService创建索引

 private ClusterState applyCreateIndexRequestWithV2Template(final ClusterState currentState,final CreateIndexClusterStateUpdateRequest request,final boolean silent,final String templateName,final BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer,final ActionListener<Void> rerouteListener) throws Exception {//创建索引return applyCreateIndexWithTemporaryService(currentState,request,silent,null,tmpImd,mappings,indexService -> resolveAndValidateAliases(request.index(),// data stream aliases are created separately in MetadataCreateDataStreamService::createDataStreamisDataStream ? Set.of() : request.aliases(),isDataStream ? List.of() : MetadataIndexTemplateService.resolveAliases(currentState.metadata(), templateName),currentState.metadata(),xContentRegistry,// the context is used ony for validation so it's fine to pass fake values for the shard id and the current timestampindexService.newSearchExecutionContext(0, 0, null, () -> 0L, null, emptyMap()),IndexService.dateMathExpressionResolverAt(request.getNameResolvedAt()),systemIndices::isSystemName),Collections.singletonList(templateName),metadataTransformer,rerouteListener);}
  private ClusterState applyCreateIndexRequestWithV1Templates(final ClusterState currentState,final CreateIndexClusterStateUpdateRequest request,final boolean silent,final List<IndexTemplateMetadata> templates,final BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer,final ActionListener<Void> rerouteListener) throws Exception {//应用临时服务创建索引(applyCreateIndexWithTemporaryService),包括当前状态(currentState)、请求(request)、是否静默(silent)、临时索引元数据(tmpImd)、索引映射(mappings)、解析和验证别名等。return applyCreateIndexWithTemporaryService(currentState,request,silent,null,tmpImd,mappings == null ? List.of() : List.of(mappings),indexService -> resolveAndValidateAliases(request.index(),request.aliases(),MetadataIndexTemplateService.resolveAliases(templates),currentState.metadata(),// the context is only used for validation so it's fine to pass fake values for the// shard id and the current timestampxContentRegistry,indexService.newSearchExecutionContext(0, 0, null, () -> 0L, null, emptyMap()),IndexService.dateMathExpressionResolverAt(request.getNameResolvedAt()),systemIndices::isSystemName),templates.stream().map(IndexTemplateMetadata::getName).collect(toList()),metadataTransformer,rerouteListener);
}

5、创建索引的build,更新集群状态

 private ClusterState applyCreateIndexWithTemporaryService(final ClusterState currentState,final CreateIndexClusterStateUpdateRequest request,final boolean silent,final IndexMetadata sourceMetadata,final IndexMetadata temporaryIndexMeta,final List<CompressedXContent> mappings,final Function<IndexService, List<AliasMetadata>> aliasSupplier,final List<String> templatesApplied,final BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer,final ActionListener<Void> rerouteListener) throws Exception {//省略代码//创建索引并返回更新后的集群状态,在创建索引时,会考虑一些参数,如阻塞状态、索引元数据、分配策略等ClusterState updated = clusterStateCreateIndex(currentState,request.blocks(),indexMetadata,metadataTransformer,allocationService.getShardRoutingRoleStrategy());//省略代码   return updated;
}
 /*** 应用提供的块将索引创建为群集状态。最终群集状态将包含基于活动节点的更新路由表。*/static ClusterState clusterStateCreateIndex(ClusterState currentState, //集群状态Set<ClusterBlock> clusterBlocks, //集群阻塞IndexMetadata indexMetadata, //索引元数据BiConsumer<Metadata.Builder, IndexMetadata> metadataTransformer, //元数据转换器ShardRoutingRoleStrategy shardRoutingRoleStrategy //分片路由角色策略) {//是否存在元数据转换器来创建新的元数据对象final Metadata newMetadata;if (metadataTransformer != null) {//如果存在元数据转换器,则使用转换器将索引元数据应用到当前的元数据上,生成新的元数据对象;Metadata.Builder builder = Metadata.builder(currentState.metadata()).put(indexMetadata, false);metadataTransformer.accept(builder, indexMetadata);newMetadata = builder.build();} else {//否则,直接将索引元数据添加到当前的元数据中newMetadata = currentState.metadata().withAddedIndex(indexMetadata);}//索引名称和集群阻塞创建集群阻塞构建器,并更新阻塞信息String indexName = indexMetadata.getIndex().getName();ClusterBlocks.Builder blocks = createClusterBlocksBuilder(currentState, indexName, clusterBlocks);blocks.updateBlocks(indexMetadata);//使用新的元数据对象和更新后的集群阻塞信息构建一个更新后的集群状态对象ClusterState updatedState = ClusterState.builder(currentState).blocks(blocks).metadata(newMetadata).build();//根据分片路由角色策略和更新后的集群状态的路由表构建器,将索引添加为新的索引,RoutingTable.Builder routingTableBuilder = RoutingTable.builder(shardRoutingRoleStrategy, updatedState.routingTable()).addAsNew(updatedState.metadata().index(indexName));//并返回更新后的集群状态对象return ClusterState.builder(updatedState).routingTable(routingTableBuilder.build()).build();}

注意上面的.addAsNew(updatedState.metadata().index(indexName))

//向构建器中添加一个新的索引元数据,其中initializeAsNew会初始化索引,初始化分片和副本信息public Builder addAsNew(IndexMetadata indexMetadata) {//检查索引的状态是否为"OPEN"if (indexMetadata.getState() == IndexMetadata.State.OPEN) {//创建一个新的IndexRoutingTable.Builder对象,并使用给定的索引元数据进行初始化。然后将该对象添加到构建器中,并返回构建器本身org.elasticsearch.cluster.routing.IndexRoutingTable.Builder indexRoutingBuilder = new org.elasticsearch.cluster.routing.IndexRoutingTable.Builder(shardRoutingRoleStrategy,indexMetadata.getIndex()).initializeAsNew(indexMetadata);//添加索引add(indexRoutingBuilder);}return this;}

其中initializeAsNew初始化这个索引,包括索引在集群上的分片,节点等

(1) initializeEmpty初始化索引的分片,副本等

  public Builder initializeAsNew(IndexMetadata indexMetadata) {return initializeEmpty(indexMetadata, new UnassignedInfo(UnassignedInfo.Reason.INDEX_CREATED, null), null);}
 private Builder initializeEmpty(IndexMetadata indexMetadata,//索引元数据UnassignedInfo unassignedInfo,//未分配信息@Nullable IndexRoutingTable previousIndexRoutingTable //之前的索引路由表作为参数。) {assert indexMetadata.getIndex().equals(index);assert previousIndexRoutingTable == null || previousIndexRoutingTable.size() == indexMetadata.getNumberOfShards();//如果已经存在分片(shards),则抛出异常,表示无法初始化具有新分片的索引if (shards != null) {throw new IllegalStateException("trying to initialize an index with fresh shards, but already has shards created");}//根据索引元数据的分片数量,创建一个索引分片路由表数组shards = new IndexShardRoutingTable.Builder[indexMetadata.getNumberOfShards()];//遍历要分配的分片for (int shardNumber = 0; shardNumber < indexMetadata.getNumberOfShards(); shardNumber++) {//根据索引和分片编号创建一个分片ID,并获取之前的节点信息ShardId shardId = new ShardId(index, shardNumber);final var previousNodes = getPreviousNodes(previousIndexRoutingTable, shardNumber);//确定主分片的恢复源(RecoverySource)类型final RecoverySource primaryRecoverySource;if (indexMetadata.inSyncAllocationIds(shardNumber).isEmpty() == false) {// we have previous valid copies for this shard. use them for recoveryprimaryRecoverySource = ExistingStoreRecoverySource.INSTANCE;} else if (indexMetadata.getResizeSourceIndex() != null) {// this is a new index but the initial shards should merged from another indexprimaryRecoverySource = LocalShardsRecoverySource.INSTANCE;} else {// a freshly created index with no restrictionprimaryRecoverySource = EmptyStoreRecoverySource.INSTANCE;}//使用索引分片路由表构建器(IndexShardRoutingTable.Builder)创建主分片和副本分片的路由信息,并添加到索引分片路由表中IndexShardRoutingTable.Builder indexShardRoutingBuilder = IndexShardRoutingTable.builder(shardId);for (int i = 0; i <= indexMetadata.getNumberOfReplicas(); i++) {boolean primary = i == 0;indexShardRoutingBuilder.addShard(ShardRouting.newUnassigned(shardId,primary,primary ? primaryRecoverySource : PeerRecoverySource.INSTANCE,withLastAllocatedNodeId(unassignedInfo, previousNodes, i),shardRoutingRoleStrategy.newEmptyRole(i)));}//构建好的索引分片路由表数组赋值给shardsshards[shardNumber] = indexShardRoutingBuilder;}return this;}

(2) 添加索引信息到indicesRouting

 public Builder add(IndexRoutingTable.Builder indexRoutingTableBuilder) {add(indexRoutingTableBuilder.build());return this;
}
 private ImmutableOpenMap.Builder<String, IndexRoutingTable> indicesRouting;
public Builder add(IndexRoutingTable indexRoutingTable) {if (indicesRouting == null) {throw new IllegalStateException("once build is called the builder cannot be reused");}indicesRouting.put(indexRoutingTable.getIndex().getName(), indexRoutingTable);return this;
}

(3) 创建一个新的集群状态返回

ClusterState.builder(updatedState).routingTable(routingTableBuilder.build()).build()

routingTable的实现

 		public Builder routingTable(RoutingTable routingTable) {this.routingTable = routingTable;return this;}

routingTableBuilder.build()的实现

		public RoutingTable build() {if (indicesRouting == null) {throw new IllegalStateException("once build is called the builder cannot be reused");}RoutingTable table = new RoutingTable(version, indicesRouting.build());indicesRouting = null;return table;}

最后一个build()

	public ClusterState build() {if (UNKNOWN_UUID.equals(uuid)) {uuid = UUIDs.randomBase64UUID();}final RoutingNodes routingNodes;//是否可以重用之前状态的路由节点(routingNodes),如果条件满足,则将之前状态的路由节点赋值给routingNodes;否则,将routingNodes设为null。if (previous != null && routingTable.indicesRouting() == previous.routingTable.indicesRouting() && nodes == previous.nodes) {// routing table contents and nodes haven't changed so we can try to reuse the previous state's routing nodes which are// expensive to computeroutingNodes = previous.routingNodes;} else {routingNodes = null;}return new ClusterState(clusterName,version,uuid,metadata,routingTable,nodes,transportVersions,blocks,customs.build(),fromDiff,routingNodes);}

二、查询索引信息

1 接收查询索引信息的RestCreateIndexAction

public class RestGetIndicesAction extends BaseRestHandler {@Overridepublic RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {// starting with 7.0 we don't include types by default in the response to GET requestsif (request.getRestApiVersion() == RestApiVersion.V_7&& request.hasParam(INCLUDE_TYPE_NAME_PARAMETER)&& request.method().equals(GET)) {deprecationLogger.compatibleCritical("get_indices_with_types", TYPES_DEPRECATION_MESSAGE);}String[] indices = Strings.splitStringByCommaToArray(request.param("index"));final GetIndexRequest getIndexRequest = new GetIndexRequest();getIndexRequest.indices(indices);getIndexRequest.indicesOptions(IndicesOptions.fromRequest(request, getIndexRequest.indicesOptions()));getIndexRequest.local(request.paramAsBoolean("local", getIndexRequest.local()));getIndexRequest.masterNodeTimeout(request.paramAsTime("master_timeout", getIndexRequest.masterNodeTimeout()));getIndexRequest.humanReadable(request.paramAsBoolean("human", false));getIndexRequest.includeDefaults(request.paramAsBoolean("include_defaults", false));getIndexRequest.features(GetIndexRequest.Feature.fromRequest(request));final var httpChannel = request.getHttpChannel();//这个是上面创建索引类似return channel -> new RestCancellableNodeClient(client, httpChannel).admin().indices().getIndex(getIndexRequest, new RestChunkedToXContentListener<>(channel));}
}

2、实际查询的TransportGetIndexAction.java的doMasterOperation方法

 @Overrideprotected void doMasterOperation(Task task,final org.elasticsearch.action.admin.indices.get.GetIndexRequest request,String[] concreteIndices,final ClusterState state,final ActionListener<GetIndexResponse> listener) {Map<String, MappingMetadata> mappingsResult = ImmutableOpenMap.of();Map<String, List<AliasMetadata>> aliasesResult = Map.of();Map<String, Settings> settings = Map.of();Map<String, Settings> defaultSettings = Map.of();Map<String, String> dataStreams = Map.copyOf(state.metadata().findDataStreams(concreteIndices).entrySet().stream().collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, v -> v.getValue().getName())));Feature[] features = request.features();boolean doneAliases = false;boolean doneMappings = false;boolean doneSettings = false;for (Feature feature : features) {checkCancellation(task);switch (feature) {case MAPPINGS:if (doneMappings == false) {mappingsResult = state.metadata().findMappings(concreteIndices, indicesService.getFieldFilter(), () -> checkCancellation(task));doneMappings = true;}break;case ALIASES:if (doneAliases == false) {aliasesResult = state.metadata().findAllAliases(concreteIndices);doneAliases = true;}break;case SETTINGS:if (doneSettings == false) {Map<String, Settings> settingsMapBuilder = new HashMap<>();Map<String, Settings> defaultSettingsMapBuilder = new HashMap<>();for (String index : concreteIndices) {checkCancellation(task);Settings indexSettings = state.metadata().index(index).getSettings();if (request.humanReadable()) {indexSettings = IndexMetadata.addHumanReadableSettings(indexSettings);}settingsMapBuilder.put(index, indexSettings);if (request.includeDefaults()) {Settings defaultIndexSettings = settingsFilter.filter(indexScopedSettings.diff(indexSettings, Settings.EMPTY));defaultSettingsMapBuilder.put(index, defaultIndexSettings);}}settings = Collections.unmodifiableMap(settingsMapBuilder);defaultSettings = Collections.unmodifiableMap(defaultSettingsMapBuilder);doneSettings = true;}break;default:throw new IllegalStateException("feature [" + feature + "] is not valid");}}listener.onResponse(new GetIndexResponse(concreteIndices, mappingsResult, aliasesResult, settings, defaultSettings, dataStreams));}

(1)查询的索引信息都是从集群状态中ImmutableOpenMap<String, IndexMetadata>得到的

    private final ImmutableOpenMap<String, IndexMetadata> indices;public Map<String, MappingMetadata> findMappings(String[] concreteIndices,Function<String, Predicate<String>> fieldFilter,Runnable onNextIndex) {assert Transports.assertNotTransportThread("decompressing mappings is too expensive for a transport thread");assert concreteIndices != null;if (concreteIndices.length == 0) {return ImmutableOpenMap.of();}ImmutableOpenMap.Builder<String, MappingMetadata> indexMapBuilder = ImmutableOpenMap.builder();Set<String> indicesKeys = indices.keySet();Stream.of(concreteIndices).filter(indicesKeys::contains).forEach(index -> {onNextIndex.run();//这里查询的是上面的ImmutableOpenMap<String, IndexMetadata> indices;IndexMetadata indexMetadata = indices.get(index);Predicate<String> fieldPredicate = fieldFilter.apply(index);indexMapBuilder.put(index, filterFields(indexMetadata.mapping(), fieldPredicate));});return indexMapBuilder.build();}
Settings indexSettings = state.metadata().index(index).getSettings();

state.metadata().index(index) 也是ImmutableOpenMap<String, IndexMetadata> indices

  public IndexMetadata index(String index) {return indices.get(index);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/135261.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI+BI行业数字化转型研讨会 - 总结精华回顾

带您一起观看研讨会精彩内容回顾&#xff01; || 导语 AIBI行业数字化转型研讨会—引领未来&#xff0c;智慧转型 德昂信息技术(北京)有限公司于2023年10月26日成功举办了AIBI行业数字化转型研讨会。此次盛会汇聚了产业精英、企业领袖以及技术专家&#xff0c;共同探讨在快速…

Python的编码规范:PEP 8介绍及基本遵循原则

文章目录 PEP 8简介基本遵循原则1. 缩进2. 行宽3. 空行4. 导入5. 空格6. 命名约定7. 表达式和语句中的空格8. 注释9. 编码声明10. 文档字符串PEP 8简介 PEP 8,或Python Enhancement Proposal 8,是一个官方文档,发布于2001年。它由Guido van Rossum,Python语言的创始人,以…

sed过滤线上日志,根据时间段查询

文章目录 语法: sed -n ‘/开始时间:/,/结束时间:/p’ 文件名 例1 sed -n /2023-11-08 11:30:*/,/2023-11-08 11:31:*/p server.log例2&#xff08;根据上面的继续过滤也行&#xff09; sed -n /2023-11-08 11:29:*/,/2023-11-08 11:31:*/p e-chatbot-server.log | grep appSav…

前端框架Vue学习 ——(二)Vue常用指令

文章目录 常用指令 常用指令 指令: HTML 标签上带有 “v-” 前缀的特殊属性&#xff0c;不同指令具有不同含义。例如: v-if, v-for… 常用指令&#xff1a; v-bind&#xff1a;为 HTML 标签绑定属性值&#xff0c;如设置 href&#xff0c;css 样式等 <a v-bind:href"…

Spark 新特性+核心回顾

Spark 新特性核心 本文来自 B站 黑马程序员 - Spark教程 &#xff1a;原地址 1. 掌握Spark的Shuffle流程 1.1 Spark Shuffle Map和Reduce 在Shuffle过程中&#xff0c;提供数据的称之为Map端&#xff08;Shuffle Write&#xff09;接收数据的称之为Reduce端&#xff08;Sh…

MybatisPlus之新增操作并返回主键ID

在应用mybatisplus持久层框架的项目中&#xff0c;经常遇到执行新增操作后需要获取主键ID的场景&#xff0c;下面将分析及测试过程记录分享出来。 1、MybatisPlus新增方法 持久层新增方法源码如下&#xff1a; public interface BaseMapper<T> extends Mapper<T> …

js处理赎金信

给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&…

自动控制原理--面试问答题

以下文中的&#xff0c;例如 s_1 为 s下角标1。面试加油&#xff01; 控制系统的三要素&#xff1a;稳准快。稳&#xff0c;系统最后不能震荡、发散&#xff0c;一定要收敛于某一个值&#xff1b;快&#xff0c;能够迅速达到系统的预设值&#xff1b;准&#xff0c;最后稳态值…

一台电脑生成两个ssh,绑定两个GitHub账号

背景 一般一台电脑账号生成一个ssh绑定一个GitHub&#xff0c;即一一对应的关系&#xff01;我之前有一个账号也配置了ssh&#xff0c;但是我想经营两个GitHub账号&#xff0c;当我用https url clone新账号的仓库时&#xff0c;直接超时。所以想起了配置ssh。于是有了今天这篇…

SQLite System.Data.SQLite和sqlite-net-pcl之间的区别

System.Data.SQLite System.Data.SQLite是一个.NET数据提供程序&#xff0c;用于操作SQLite数据库。它是在SQLite C语言库之上构建的&#xff0c;提供了以.NET方式访问SQLite数据库的功能。System.Data.SQLite提供了ADO.NET接口&#xff0c;可以与其他关系型数据库一样使用Com…

FreeRTOS总结

堆内存管理 有五种内存分配方式常用的为heap_4方式 任务管理 任务不能以任何方式实现函数返回&#xff0c;可以在任务的死循环外加上xTaskDelete( ) 创建任务&#xff1a;xTaskCreate( ) 任务堆栈的大小&#xff0c;空闲任务的最小是configMINIMAL_STACK_SIZE&#xff0c;其…

【自然语言处理】利用python创建简单的聊天系统

一&#xff0c;实现原理 代码设计了一个简单的客户端-服务器聊天应用程序&#xff0c;建立了两个脚本文件&#xff08;.py文件)&#xff0c;其中有一个客户端和一个服务器端。客户端和服务器之间通过网络连接进行通信&#xff0c;客户端发送消息&#xff0c;服务器端接收消息并…

git clone单个文件/文件夹、wget下载单文件

文章目录 1. 暂时没找到方法用git命令方便地clone单个文件/文件夹2. 通过wget手动下载单个文件 1. 暂时没找到方法用git命令方便地clone单个文件/文件夹 复杂&#xff0c;未测试 https://www.cnblogs.com/impw/p/15629514.html 2. 通过wget手动下载单个文件 在github/gitee网…

acwing 795前缀和

输入一个长度为 n&#xfffd; 的整数序列。 接下来再输入 m&#xfffd; 个询问&#xff0c;每个询问输入一对 l,r&#xfffd;,&#xfffd;。 对于每个询问&#xff0c;输出原序列中从第 l&#xfffd; 个数到第 r&#xfffd; 个数的和。 输入格式 第一行包含两个整数 …

django+drf+vue 简单系统搭建 (2) - drf 应用

按照本系统设置目的&#xff0c;是为了建立一些工具用来处理简单的文件。 1. 准备djangorestframework 关于drf的说明请参见&#xff1a;Django REST Framework教程 | 大江狗的博客 本系列直接使用drf的序列化等其他功能。 安装 conda install djangorestframework conda i…

VSCode使用插件Github Copilot进行AI编程

演示示例 函数封装 根据上下文 根据注释 详情请看GitHub Copilot 安装插件 在VS Code中安装插件 GitHub Copilot 登录账号 点击VS code左下角账户图标&#xff0c;点击【Sign in】&#xff0c;会自动在浏览器打开Github登录页&#xff0c;登录具有 Github Copilot 服务的…

数据结构 编程1年新手视角的平衡二叉树AVL从C与C++实现③

对应地&#xff0c;我们可以将insert函数中省略的操作补上 if(getBalance(node)2){ if(getBalance(node->left)1){ noderightRotate(node); //对应LL型 } else if(getBalance(node->left)-1{ node->left leftRotate(node->left); //对应LR型 noderightRotate(n…

微信 商家转账到零钱 二

本来想手写&#xff0c;但是有sdk 就没必要这么麻烦。 composer地址&#xff1a;wechatpay/wechatpay - Packagist 微信官网sdk,给的是github&#xff0c;打不开。 <?php require_once vendor/autoload.php; defined(ROOT_PATH) or define(ROOT_PATH, ./); use WeChatPa…

网工内推 | 上市公司,云平台运维,IP认证优先,13薪

01 上海新炬网络信息技术股份有限公司 招聘岗位&#xff1a;云平台运维工程师 职责描述&#xff1a; 1、负责云平台运维&#xff0c;包括例行巡检、版本发布、问题及故障处理、平台重保等&#xff0c;保障平台全年稳定运行&#xff1b; 2、参与制定运维标准规范与流程&#x…

混沌系统在图像加密中的应用(基于哈密顿能量函数的混沌系统构造1.1)

混沌系统在图像加密中的应用&#xff08;基于哈密顿能量函数的混沌系统构造1.1&#xff09; 前言一、基于广义哈密顿系统的一类混沌系统构造1.基本动力学特性分析2.数值分析 待续 前言 本文的主题是“基于哈密顿能量函数的混沌系统构造”&#xff0c;哈密顿能量函数是是全文研…