elasticsearch之记录es7.17升级8.17 springboot2.7.0 程序改造坑
es7.17升级8.x问题目录
- 一、硬件安装
- 1-1. centos7 服务器上,删除elasticsearch7.17,安装es8.17
- 二、 程序改造
- 2-1. Java API Client 8.17.5
- 2-2. 依赖引入
- 2-3. 配置文件
- 2-4. Java 配置类
- 三、根据 Elasticsearch 集群信息(版本 8.17.2), Java 客户端开发的注意事项和完整集成建议:
- 3-1. 环境兼容性验证
- 1. 客户端版本匹配
- 2. 安全认证配置
- 3-2. 核心 API 升级指南
- 2. 搜索请求构建
- 3. 批量操作优化
- 3-3. 关键差异处理(7.x → 8.x)
- 3-4. 安全加固建议
- 1. HTTPS 加密传输
- 2. API 密钥认证
- 3-5. 性能调优参数
- 3-6. 故障排查命令
- 3-7. 迁移验证清单
- 问题一
- 问题二 健康检查的ip:port 不对
- 问题原因分析
- 解决方案
一、硬件安装
1-1. centos7 服务器上,删除elasticsearch7.17,安装es8.17
todo
21.18服务器
二、 程序改造
2-1. Java API Client 8.17.5
-
是 Elasticsearch 官方新一代客户端(专为 Elasticsearch 8.x 设计,支持所有新特性(如角色权限管理、安全增强等)。
-
长期维护:官方明确表示未来所有功能迭代和 bug 修复将集中在 Java API Client,而 RestHighLevelClient 已逐步被弃用
2-2. 依赖引入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId><version>2.7.0</version><exclusions><!-- 排除旧版本ES客户端 --><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId></exclusion><exclusion><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId></exclusion><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId></exclusion></exclusions></dependency><!-- 显式添加 spring-data-elasticsearch 并排除其内部的 rest-client --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-elasticsearch</artifactId><version>4.4.6</version><exclusions><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId></exclusion></exclusions></dependency><!-- 改用新版API Elasticsearch 8.xx Java API Client --><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.17.5</version> <!-- 兼容 Spring Boot 2.7.x 的最新稳定版 --><exclusions><exclusion><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>8.15.3</version> <!-- 配套的 REST 客户端 --></dependency><!-- 作用:实现与 Elasticsearch 集群的 HTTP 通信(基于 Java 11+ 的 HttpClient)。必要性:必须与 elasticsearch-java 搭配使用,否则无法初始化 ElasticsearchClient 实例。--><!-- 必须的 JSON 处理库 --><dependency><groupId>jakarta.json</groupId><artifactId>jakarta.json-api</artifactId><version>2.1.1</version></dependency><dependency><groupId>org.glassfish</groupId><artifactId>jakarta.json</artifactId><version>2.0.1</version></dependency>
2-3. 配置文件
2-3-1. 主配置 application.yml
# 日志配置
log_path:/data/logs/personnel-manager/backendlogging:level:com.ltkj: debugorg.springframework: warnorg.elasticsearch: infoorg.apache.http: INFOconfig: classpath:logback-spring.xml
2-3-2. 子配置 application-dev.yml
minio:endpoint: http//:192.168.21.3:33306access-key: ltkj.personnelsecret-key: ltkj.personnel.combucketName: wanglurl: ${minio.endpoint}/${minio.bucket}/#elasticsearch 配置:
elasticsearch:address: 192.168.21.3:19200,192.168.21.18:19200 #如果是集群,用逗号隔开connect-timeout: 3000 #连接超时时间socket-timeout: 30000 #连接超时时间connection-request-timeout: 1000max-connect-num: 200max-connect-per-route: 200shards: 2replicas: 1username: elasticpassword: elastic.commanagement:health:elasticsearch:enabled: true # 可选:禁用健康检查
2-4. Java 配置类
/** Copyright (c) 2025. ltkj.com 石家庄文旅投数智科技有限公司 All rights reserved.*/
package com.ltkj.configuration;import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import com.ltkj.configuration.properties.ElasticSearchProperties;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.Node;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.net.ssl.SSLContext;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;@Configuration
public class ElasticSearchConfig {/*** Java API Client 8.17.5* 是 Elasticsearch 官方新一代客户端(专为 Elasticsearch 8.x 设计,支持所有新特性(如角色权限管理、安全增强等)。* 长期维护:官方明确表示未来所有功能迭代和 bug 修复将集中在 Java API Client,而 RestHighLevelClient 已逐步被弃用。*/private static final Logger logger = LoggerFactory.getLogger(ElasticSearchConfig.class);@Beanpublic RestClient restClient(ElasticSearchProperties elasticProperties) {// 1. 解析地址(支持完整URI格式)List<HttpHost> hostList = parseHosts(elasticProperties.getAddress());logger.info("初始化Elasticsearch 开始>>>>>> 节点列表: {}", hostList); // 关键日志// 2. 构建 RestClientBuilderRestClientBuilder builder = RestClient.builder(hostList.toArray(new HttpHost[0])).setFailureListener(new LoggingFailureListener());// 3. 配置超时参数(新版API推荐方式)configureTimeouts(builder, elasticProperties);// 4. 配置连接池和认证configureConnections(builder, elasticProperties);return builder.build();}@Bean(name = "elasticsearchClient")@ConditionalOnMissingBeanpublic ElasticsearchClient client(RestClient restClient) {// 依赖于前面的 1、2、3、4 步骤// 5. 创建 Transport 和 ClientElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());logger.info("ElasticsearchClient initializing ......");ElasticsearchClient elasticsearchClient = new ElasticsearchClient(transport);logger.info("ElasticsearchClient initialized with nodes: {}", restClient.getNodes());return elasticsearchClient;}/*** 解析地址(支持带协议的完整格式)* 输入示例:http://192.168.21.3:19200,https://192.168.21.18:19200*/private List<HttpHost> parseHosts(String addressStr) {return Arrays.stream(addressStr.split(",")).map(addr -> {try {// 自动补全协议头if (!addr.startsWith("http://") && !addr.startsWith("https://")) {addr = "http://" + addr; // 默认HTTP}URI uri = URI.create(addr);return new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());} catch (IllegalArgumentException e) {throw new IllegalArgumentException("Invalid Elasticsearch address format: " + addr);}}).collect(Collectors.toList());}/*** 配置超时参数(适配新API)*/private void configureTimeouts(RestClientBuilder builder, ElasticSearchProperties props) {builder.setRequestConfigCallback(requestConfigBuilder ->requestConfigBuilder.setConnectTimeout(props.getConnectTimeOut()).setSocketTimeout(props.getSocketTimeOut()).setConnectionRequestTimeout(props.getConnectionRequestTimeOut()));}/*** 配置连接池和认证(同步客户端)*/private void configureConnections(RestClientBuilder builder, ElasticSearchProperties props) {final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(props.getUsername(), props.getPassword()));// 使用异步客户端配置builder.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {@Overridepublic HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {// 连接池配置httpClientBuilder.setMaxConnTotal(props.getMaxConnectNum()).setMaxConnPerRoute(props.getMaxConnectPerRoute()).setDefaultCredentialsProvider(credentialsProvider);// 启用HTTPS时配置SSLif ("https".equalsIgnoreCase(props.getScheme())) {configureSSL(httpClientBuilder);}return httpClientBuilder;}});}/*** 配置SSL(异步客户端)*/private void configureSSL(HttpAsyncClientBuilder httpClientBuilder) {try {SSLContext sslContext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true) // 信任所有证书(生产环境需替换).build();httpClientBuilder.setSSLContext(sslContext).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);} catch (Exception e) {throw new RuntimeException("SSL配置失败", e);}}/*** 节点故障监听器(记录黑名单事件)*/private static class LoggingFailureListener extends RestClient.FailureListener {@Overridepublic void onFailure(Node node) {logger.warn("Node [{}] added to blacklist", node.getHost());}}}
三、根据 Elasticsearch 集群信息(版本 8.17.2), Java 客户端开发的注意事项和完整集成建议:
3-1. 环境兼容性验证
1. 客户端版本匹配
确保使用的 Java API Client 版本与 Elasticsearch 服务端版本一致:
<!-- pom.xml -->
<dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.17.2</version> <!-- 必须与ES服务端版本一致 -->
</dependency>
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.17.1</version> <!-- 推荐使用官方认证版本 -->
</dependency>
2. 安全认证配置
由于你的集群启用了基础认证(-u elastic:elastic.com),客户端需配置安全凭证:
RestClient restClient = RestClient.builder(new HttpHost("192.168.21.18", 19200)).setDefaultHeaders(new Header[]{new BasicHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString("elastic:elastic.com".getBytes()))}).build();ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
3-2. 核心 API 升级指南
java
// Index 文档(自动序列化POJO)
IndexResponse response = client.index(i -> i.index("products").id(product.getId()).document(product)
);// 根据ID查询
Product product = client.get(g -> g.index("products").id("123"),Product.class
).source();// 删除文档
DeleteResponse response = client.delete(d -> d.index("products").id("123")
);
2. 搜索请求构建
SearchResponse<Product> response = client.search(s -> s.index("products").query(q -> q.bool(b -> b.must(m -> m.match(t -> t.field("name").query("手机"))).filter(f -> f.range(r -> r.field("price").gte(JsonData.of(1000))))).highlight(h -> h.fields("name", f -> f.preTags("<em>").postTags("</em>"))).from(0).size(10),Product.class
);
3. 批量操作优化
BulkRequest.Builder bulkBuilder = new BulkRequest.Builder();
products.forEach(p -> bulkBuilder.operations(op -> op.index(idx -> idx.index("products").id(p.getId()).document(p)))
);BulkResponse response = client.bulk(bulkBuilder.build());
response.items().forEach(item -> {if (item.error() != null) {log.error("操作失败: {}", item.error().reason());}
});
3-3. 关键差异处理(7.x → 8.x)
功能点 | 7.x 实现方式 | 8.x 正确实现方式 |
---|---|---|
查询构建 | QueryBuilders.matchQuery() | Query.of(q -> q.match(m -> m.field(...))) |
分页参数 | .setFrom() / .setSize() | .from() / .size() 链式调用 |
高亮配置 | HighlightBuilder | .highlight(h -> h.fields(...)) |
聚合分析 | AggregationBuilders | .aggregations("agg_name", a -> a.terms(...))) |
异步操作 | client.prepareIndex().execute() | client.indexAsync(...) + CompletableFuture |
3-4. 安全加固建议
1. HTTPS 加密传输
RestClient.builder(new HttpHost("192.168.21.18", 19200, "https")).setHttpClientConfigCallback(hc -> hc.setSSLContext(sslContext) // 配置SSL上下文.setDefaultCredentialsProvider(credentialsProvider));
2. API 密钥认证
Header apiKeyHeader = new BasicHeader("Authorization", "ApiKey " + Base64.getEncoder().encodeToString("api_key_id:api_key_secret".getBytes()));RestClient restClient = RestClient.builder(...).setDefaultHeaders(new Header[]{apiKeyHeader}).build();
3-5. 性能调优参数
// 查询超时设置
SearchRequest request = SearchRequest.of(s -> s.timeout(t -> t.time("30s"))
);// 批量操作优化
BulkRequest bulkRequest = BulkRequest.of(b -> b.refresh(Refresh.WaitFor) // 刷新策略.requireAlias(true) // 强制通过别名写入.timeout(t -> t.time("1m"))
);
3-6. 故障排查命令
- 集群健康检查
curl -u elastic:elastic.com http://192.168.21.18:19200/_cluster/health?pretty
- 索引状态分析
curl -u elastic:elastic.com http://192.168.21.18:19200/_cat/indices?v
- 慢查询日志
# elasticsearch.yml
index.search.slowlog.threshold.query.warn: 10s
index.search.slowlog.threshold.fetch.debug: 500ms
3-7. 迁移验证清单
- 客户端版本与ES服务端版本严格一致(8.17.2)
- 所有 TransportClient 代码已替换为 Java API Client
- 查询DSL已升级到类型安全构建器
- 安全认证(Basic Auth/API Key)已正确配置
- 日志系统已适配新响应格式(如错误日志记录 item.error().reason())
- 性能测试通过(对比7.x版本QPS、Latency等指标)
问题一
问题二 健康检查的ip:port 不对
上面 2-3 中,我的配置文件为:
elasticsearch:address: 192.168.21.3:19200,192.168.21.18:19200 #如果是集群,用逗号隔开connect-timeout: 3000 #连接超时时间socket-timeout: 30000 #连接超时时间connection-request-timeout: 1000max-connect-num: 200max-connect-per-route: 200shards: 2replicas: 1username: elasticpassword: elastic.com
为什么会报错如下:
2025-05-15 17:40:45.968 [RMI TCP Connection(2)-192.168.68.19] DEBUG org.elasticsearch.client.RestClient - added [[host=http://localhost:9200]] to blacklist
java.net.ConnectException: Connection refused: no further informationat java.base/sun.nio.ch.Net.pollConnect(Native Method)at java.base/sun.nio.ch.Net.pollConnectNow(Net.java:672)at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:946)at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvent(DefaultConnectingIOReactor.java:174)at org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor.processEvents(DefaultConnectingIOReactor.java:148)at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor.execute(AbstractMultiworkerIOReactor.java:351)at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.execute(PoolingNHttpClientConnectionManager.java:221)at org.apache.http.impl.nio.client.CloseableHttpAsyncClientBase$1.run(CloseableHttpAsyncClientBase.java:64)at java.base/java.lang.Thread.run(Thread.java:833)
2025-05-19 09:40:56.212 [elasticsearch-rest-client-1-thread-1] DEBUG o.a.h.i.n.c.InternalHttpAsyncClient - [exchange: 1] connection request failed
2025-05-19 09:40:56.214 [RMI TCP Connection(2)-192.168.68.19] DEBUG org.elasticsearch.client.RestClient - request [GET http://localhost:9200/_cluster/health/] failed
java.util.concurrent.ExecutionException: java.net.ConnectException: Connection refused: no further informationat org.apache.http.concurrent.BasicFuture.getResult(BasicFuture.java:71)at org.apache.http.concurrent.BasicFuture.get(BasicFuture.java:84)at org.apache.http.impl.nio.client.FutureWrapper.get(FutureWrapper.java:70)at org.elasticsearch.client.RestClient.performRequest(RestClient.java:300)at org.elasticsearch.client.RestClient.performRequest(RestClient.java:292)at org.springframework.boot.actuate.elasticsearch.ElasticsearchRestClientHealthIndicator.doHealthCheck(ElasticsearchRestClientHealthIndicator.java:60)at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82)at org.springframework.boot.actuate.health.HealthIndicator.getHealth(HealthIndicator.java:37)at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:77)at org.springframework.boot.actuate.health.HealthEndpoint.getHealth(HealthEndpoint.java:40)at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:130)at org.springframework.boot.actuate.health.HealthEndpointSupport.getAggregateContribution(HealthEndpointSupport.java:141)at org.springframework.boot.actuate.health.HealthEndpointSupport.getContribution(HealthEndpointSupport.java:126)at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:95)at org.springframework.boot.actuate.health.HealthEndpointSupport.getHealth(HealthEndpointSupport.java:66)at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:71)at org.springframework.boot.actuate.health.HealthEndpoint.health(HealthEndpoint.java:61)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:568)at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282)at org.springframework.boot.actuate.endpoint.invoke.reflect.ReflectiveOperationInvoker.invoke(ReflectiveOperationInvoker.java:74)at org.springframework.boot.actuate.endpoint.annotation.AbstractDiscoveredOperation.invoke(AbstractDiscoveredOperation.java:60)at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:122)at org.springframework.boot.actuate.endpoint.jmx.EndpointMBean.invoke(EndpointMBean.java:97)at java.management/com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:814)at java.management/com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:802)at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1472)at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1310)at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1405)at java.management.rmi/javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:829)at java.base/jdk.internal.reflect.GeneratedMethodAccessor56.invoke(Unknown Source)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:568)at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.net.ConnectException: Connection refused: no further information
问题原因分析
从错误日志可以看出,健康检查仍然尝试连接 localhost:9200,而非您配置的 192.168.21.3:19200。这是因为 Spring Boot Actuator 的 Elasticsearch 健康检查默认使用独立的客户端配置,而非您自定义的 ElasticsearchClient。以下是完整解决方案:
解决方案
- 禁用默认健康检查(可选)
在 application.yml 中关闭 Elasticsearch 默认健康检查:
management:health:elasticsearch:enabled: false
- 自定义健康检查(推荐)
创建自定义健康检查配置类,强制使用您的客户端配置:
CustomElasticsearchHealthIndicator.java
@Component
public class CustomElasticsearchHealthIndicator extends AbstractHealthIndicator {private final ElasticsearchClient client;public CustomElasticsearchHealthIndicator(ElasticsearchClient client) {this.client = client;}@Overrideprotected void doHealthCheck(Health.Builder builder) throws Exception {try {InfoResponse info = client.info();builder.up().withDetail("cluster_name", info.clusterName()).withDetail("version", info.version().number());} catch (IOException e) {builder.down(e);}}
}
相关文章:
elasticsearch之记录es7.17升级8.17 springboot2.7.0 程序改造坑
es7.17升级8.x问题目录 一、硬件安装1-1. centos7 服务器上,删除elasticsearch7.17,安装es8.17 二、 程序改造2-1. Java API Client 8.17.52-2. 依赖引入2-3. 配置文件2-4. Java 配置类 三、根据 Elasticsearch 集群信息(版本 8.17.2…...
SpringBoot+ELK 搭建日志监控平台
ELK 简介 ELK(Elasticsearch, Logstash, Kibana)是一个目前主流的开源日志监控平台。由三个主要组件组成的: Elasticsearch: 是一个开源的分布式搜索和分析引擎,可以用于全文检索、结构化检索和分析,它构建…...
家庭数字生态构建实战:基于飞牛fnOS的智能家居数据中台搭建全流程解析
文章目录 前言1. VMware安装飞牛云(fnOS)1.1 打开VMware创建虚拟机1.3 初始化系统 2. 安装Cpolar工具3. 配置远程访问地址4. 远程访问飞牛云NAS5. 固定远程访问地址 前言 在数字生活时代,数据管理正成为每个家庭的刚需。今天要向大家重点推荐…...
博客系统功能测试
博客系统网址:http://8.137.19.140:9090/blog_list.html 主要测试内容 功能测试、界面测试、性能测试、易用性测试、安全测试、兼容性测试、弱网测试、安装卸载测试、压力测试… 测试方法及目的 利用selenium和python编写测试脚本,对博客系统进行的相关…...
抽奖相关功能测试思路
1. 抽奖系统功能测试用例设计(登录 每日3次 中奖40% 道具兑换码) ✅ 功能点分析 必须登录后才能抽奖每天最多抽奖3次抽奖有 40% 概率中奖中奖返回兑换码 ✅ 测试用例设计 编号 用例描述 前置条件 操作 预期结果 TC01 未登录时抽奖 未登录 …...
paddle ocr本地化部署进行文字识别
一、Paddle 简介 1. 基本概念 Paddle(全称 PaddlePaddle,飞桨)是百度开发的 开源深度学习平台,也是中国首个自主研发、功能丰富、技术领先的工业级深度学习平台。它覆盖了深度学习从数据准备、模型训练、模型部署到预测的全流程…...
在CentOS系统上部署GitLabRunner并配置CICD自动项目集成!
在CentOS系统上部署GitLabRunner并配置CICD自动项目集成 在CentOS系统上部署GitLab Runner并配置CI/CD自动项目集成GitLab CI/CD是一个强大的持续集成和持续部署工具,能够显著提高开发团队的效率。 本文将详细介绍如何在CentOS系统上部署GitLab Runner,…...
python学习day2(未写完,明天继续补充)
今天主要学习了变量的数据类型,以及如何使用格式化符号进行输出。 一、认识数据类型 在python里为了应对不同的业务需求,也把数据分为不同的类型。 代码如下: """ 1、按类型将不同的变量存储在不同的类型数据 2、验证这些…...
深度强化学习框架DI-engine
深度强化学习框架DI-engine 一、DI-engine概述:决策智能的通用引擎 DI-engine是由OpenDILab开源的决策智能引擎,基于PyTorch和JAX构建,旨在为强化学习(RL)、模仿学习(IL)、离线学习等场景提供…...
gitlab迁移
需求:需要将A服务器上的 gitlab 迁移到B服务器上,均使用docker 部署 一、备份数据 进入到A服务器的 gitlab 的容器中,运行gitlab-rake gitlab:backup:create 该命令会在 /var/opt/gitlab/backups/ 目录下创建一个xxx_gitlab_backup.tar 压缩…...
UEFI Spec 学习笔记---33 - Human Interface Infrastructure Overview---33.2.6 Strings
33.2.6 Strings UEFI 环境中的 string 是使用 UCS-2 格式定义,每个字符由 16bit 数据表示。对于用户界面,strings 也是一种可以安装到 HIIdatabase 的一种数据。 为了本土化,每个 string 通过一个唯一标识符来识别,而每一个标识…...
如何确保低空经济中的数据安全?
低空经济涉及大量敏感数据,如无人机的飞行轨迹、拍摄的地理图像和视频等。为确保这些数据的安全,可从以下几方面着手: 加强数据加密 传输加密 :采用 SSL/TLS 等加密协议,对数据在传输过程中进行加密,防止…...
在linux平台下利用mingw64编译windows程序
背景 笔者平时都是基于linux平台开发C代码,已经熟悉使用CMake这一套工具上一次开发windows应用程序还要追溯到10多年前,彼时还是使用微软的visual studio这个IDE,这个IDE确实也很强大,但也确实很笨重,当时用起来也很不…...
虚幻引擎5-Unreal Engine笔记之什么时候新建GameMode,什么时候新建关卡?
虚幻引擎5-Unreal Engine笔记之什么时候新建GameMode,什么时候新建关卡? code review! 参考笔记: 1.虚幻引擎5-Unreal Engine笔记之GameMode、关卡(Level) 和 关卡蓝图(Level Blueprint)的关系 2.虚幻引擎…...
[IMX] 04.定时器 - Timer
目录 1.周期中断定时器 - EPIT 1.1.工作模式 1.2.配置寄存器 - EPIT_CR 1.3.状态寄存器 - EPIT_SR 1.4.加载寄存器 - EPIT_LR 1.5.比较寄存器 - EPIT_CMPR 1.6.计数寄存器 - EPIT_CNR 2.通用定时器 - GPT 2.1. 时钟源 2.2.模块结构 2.3.工作模式 2.4.配置寄存器 - …...
前端 vue + element-ui 框架从 0 - 1 搭建
1. 安装node 地址: Node.js — 在任何地方运行 JavaScript 2. 安装 vue 2.1 执行安装命令 npm uninstall -g vue-cli npm install -g vue/cli 安装最新的vue3版本 2.2 使用vue 脚手架 搭建项目 vue create project_name 2.2.1 注意 项目名称不能包…...
【IDEA】删除/替换文件中所有包含某个字符串的行
目录 前言 正则表达式 示例 使用方法 前言 在日常开发中,频繁地删除无用代码或清理空行是不可避免的操作。许多开发者希望找到一种高效的方式,避免手动选中代码再删除的繁琐过程。 使用正则表达式是处理字符串的一个非常有效的方法。 正则表达式 …...
算法刷题(Java与Python)2.数组、列表
目录 Java的数组 数组介绍 注意事项 Python的列表 列表介绍 Python 的列表和 Java 的 ArrayList 一样吗? 例题1 代码分析 Java代码 Python代码 对比代码 例题2 代码分析 Java代码 Python代码 对比代码 例题三 Java代码 Python代码 代码对比 Jav…...
uniapp打包H5,输入网址空白情况
由于客户预算有限,最近写了两个uniapp打包成H5的案例,总结下面注意事项 1. 发行–网站-PCWeb或手机H5按钮,输入名称,网址 点击【发行】,生成文件 把这个给后端,就可以了 为什么空白呢 最重要一点…...
JavaScript 中使用 Elasticsearch 的正确方式,第一部分
作者:来自 Elastic Jeffrey Rengifo 讲解如何用 JavaScript 创建一个可用于生产环境的 Elasticsearch 后端。 想获得 Elastic 认证?看看下一期 Elasticsearch 工程师培训什么时候开始吧! Elasticsearch 拥有大量新功能,能帮助你…...
每日一道leetcode(增加版)
901. 股票价格跨度 - 力扣(LeetCode) 题目 设计一个算法收集某些股票的每日报价,并返回该股票当日价格的 跨度 。 当日股票价格的 跨度 被定义为股票价格小于或等于今天价格的最大连续日数(从今天开始往回数,包括今…...
排序复习/下(C语言版)
目录 1.快速排序(hoare法) 单趟: 整体: 代码优化: 编辑三数取中代码: 小区间优化代码: hoare法疑问解答: 2.快速排序(挖坑法) 3.快速排序&#x…...
Vue百日学习计划Day33-35天详细计划-Gemini版
总目标: 在 Day 33-35 理解 Vue 组件从创建到销毁的完整生命周期,熟练掌握 Composition API 中主要的生命周期钩子,并知道在不同阶段执行哪些操作。 所需资源: Vue 3 官方文档 (生命周期钩子): https://cn.vuejs.org/guide/essentials/lifecycle.html你…...
Apidog MCP服务器,连接API规范和AI编码助手的桥梁
#作者:曹付江 文章目录 1.了解 MCP2.什么是 Apidog MCP 服务器?3.Apidog MCP 服务器如何工作4.利用人工智能改变开发工作流程5.设置 Apidog MCP 服务器: 分步指南5.高级功能和提示5.1 使用 OpenAPI 规范5.2.多个项目配置5.3.安全最佳实践5.4…...
统计客户端使用情况,使用es存储数据,实现去重以及计数
这篇文件的重点在tshark、filebeat、和logstash。 需求:统计客户使用的客户端版本 实现工具:tshark 1.10.14,filebeat 8.17.0,logstash 8.17.0,elasticsearch 8.17.0,kibana 8.17.0 总体设计:…...
Git基础面试题
git的rm命令与系统的rm命令有什么区别 git rm 和系统的 rm (在 Windows 上是 del) 命令都用于删除文件,但它们在 Git 仓库的上下文中作用有所不同: 系统 rm (或 del) 命令: 作用: 直接从文件系统中删除文件。Git 的感知ÿ…...
conda 的常用命令
好的,下面为你介绍conda的常用命令: 环境管理 # 创建新环境 conda create -n env_name python3.8# 激活环境 conda activate env_name# 查看所有环境 conda env list# 复制环境 conda create -n new_env --clone old_env# 删除环境 conda remove -n en…...
PLC双人舞:profinet转ethernet ip网关奏响施耐德与AB的协奏曲
PLC双人舞:ethernet ip转profinet网关奏响施耐德与AB的协奏曲 案例分析:施耐德PLC与AB PLC的互联互通 在现代工业自动化中,设备之间的互联互通至关重要。本案例旨在展示如何通过北京倍讯科技的EtherNet/IP转Modbus网关,将施耐德P…...
百度OCR:证件识别
目录 一、编写目的 二、准备工作 2.1 OCR密钥 三、代码实现 3.1 配置文件 3.2 请求接收封装 3.3 请求响应封装 3.4 服务类参数初始化 3.5 服务类实现 3.6 解析结果 3.7 定义Web接口 四 测试效果 五、总结 欢迎来到盹猫🐱的博客 本篇文章主要介绍了 [百…...
纯前端实现图文识别 OCR
Tesseract.js Tesseract.js 是一个基于 Google Tesseract OCR 引擎的 JavaScript 库,利用 WebAssembly 技术将的 OCR 引擎带到了浏览器中。它完全运行在客户端,无需依赖服务器,适合处理中小型图片的文字识别。 基本使用 以下示例展示了如何…...
2025.05.01【Barplot】柱状图的多样性绘制
Custom color A few examples showing how to custom barplot color. Horizontal barchart It makes sense to make your barchart horizontal: group labels are now much easier to read 文章目录 Custom colorHorizontal barchart 探索Barplot的奥秘Barplot基础什么是Barp…...
在资源受限环境下,移动端如何实现流畅动画?如何在内存、CPU、GPU、网络等多种限制条件下,依然保持动画高帧率、低延迟、不卡顿?
在日常生活中,移动设备已经成为不可或缺的工具。从社交、购物到游戏、教育,几乎所有的应用场景都依赖于移动终端的计算和显示能力。然而,随着用户体验的不断提升需求,动画成为了界面交互中不可忽视的一环。动画不仅提升了视觉吸引…...
HJ10 字符个数统计【牛客网】
文章目录 零、原题链接一、题目描述二、测试用例三、解题思路四、参考代码 零、原题链接 HJ10 字符个数统计 一、题目描述 二、测试用例 三、解题思路 基本思路: 建立字符串的散列表,然后统计不同字符个数具体思路: 遍历字符串的字…...
关键点检测算法-RTMPose
一、网络框架(top-down模式) 二、各部分内容 1、骨干网络 对于网络而言,CXPset太大,可以换成starnet 2、一个卷积层 7x7的卷积核对性能提升最大 3、一个全连接层 将一维关键点表示扩展到由超参数控制的所需维度。 4、一个用…...
云原生安全:错误策略S3存储桶ACL设置为Everyone:FullControl
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 ——从基础到实践的深度解析 1. 基础概念 S3存储桶与ACL Amazon S3(Simple Storage Service)是AWS提供的对象存储服务,支持存储和检索任意规模的数据。ACL(访问控制列表…...
Axure疑难杂症:垂直菜单展开与收回(4大核心问题与专家级解决方案)
亲爱的小伙伴,在您浏览之前,烦请关注一下,在此深表感谢!如有帮助请订阅专栏! Axure产品经理精品视频课已登录CSDN可点击学习https://edu.csdn.net/course/detail/40420 课程主题:垂直菜单展开与收回 主要内容:超长菜单实现、展开与收回bug解释、Axure9版本限制等问题解…...
图漾相机错误码解析(待补充)
文章目录 1.相机错误码汇总2.常见报错码2.1 -1001报错2.1.1 没有找到相机2.1.2 SDK没有进行初始化 2.2 -1005报错2.2.1 跨网段打开相机2.2.2 旧版本SDK在软触发失败后提示的报错2.2.3 相机初始化上电时报错2.2.4 USB相机被占用 2.3 -1009报错2.3.1 相机本身不支持改属性 2.4 -1…...
SpringBoot 中文转拼音 Pinyin4j库 拼音转换 单据管理 客户管理
介绍 在客户管理系统中部分客户的名字会有生僻字为了沟通时候不叫错客户的名称,因此决定将客户名称的拼音一起返回给前端,也可以直接交给前端去处理。这里介绍后端的做法 Pinyin4j 是一个用于将汉字转换为拼音的 Java 库。在需要对中文文本进行拼音转换…...
使用 Whisper 生成视频字幕:从提取音频到批量处理
生成视频字幕是许多视频处理任务的核心需求。本文将指导你使用 OpenAI 的 Whisper 模型为视频文件(如电视剧《Normal People》或电影《花样年华》)生成字幕(SRT 格式)。我们将从提取音频开始,逐步实现字幕生成…...
Kotlin Compose Button 实现长按监听并实现动画效果
想要实现长按按钮开始录音,松开发送的功能。发现 Button 这个控件如果去监听这些按下,松开,长按等事件,发现是不会触发的,究其原因是 Button 已经提前消耗了这些事件所以导致,这些监听无法被触发。因此为了…...
SQL练习——(15/81)
目录 1.计算次日留存率 2.多条件查询 方法1:子查询 方法2:窗口函数实现 3.条件查询——自连接相关 1.计算次日留存率 550. 游戏玩法分析 IV - 力扣(LeetCode) 错误查询1:(没有考虑从首次登录日期开始…...
数据中心 智慧机房解决方案
该文档介绍数据中心智慧机房解决方案,涵盖模块化数据中心(机柜式、微模块),具备低成本快速部署、标准化建设等特点;监控管理系统(DCIM)可实现设施、资产、容量、能效管理;节能解决方案含精密空调节能控制柜,节能率高达 30%;还有7X24 小时云值守运维服务。方案亮点包括…...
网络-MOXA设备基本操作
修改本机IP和网络设备同网段,输入设备IP地址进入登录界面,交换机没有密码,路由器密码为moxa 修改设备IP地址 交换机 路由器 环网 启用Turbo Ring协议:在设备的网络管理界面中,找到环网配置选项,启用Turb…...
Docker构建 Dify 应用定时任务助手
概述 Dify 定时任务管理工具是一个基于 GitHub Actions 的自动化解决方案,用于实现 Dify Workflow 的定时执行和状态监控。无需再为缺乏定时任务支持而感到困扰,本工具可以帮助设置自动执行任务并获取实时通知,优化你的工作效率。 注意&…...
前端测试策略:单元测试到 E2E 测试
引言 在现代前端开发中,测试已成为确保应用质量和可靠性的关键环节。随着前端应用复杂度的不断提高,仅依靠手动测试已经远远不够。一个全面的前端测试策略应该包含多个层次的测试,从最小粒度的单元测试到模拟真实用户行为的端到端(E2E)测试。…...
Web漏洞扫描服务的特点与优势:守护数字时代的安全防线
在数字化浪潮中,Web应用程序的安全性已成为企业业务连续性和用户信任的核心要素。随着网络攻击手段的不断升级,Web漏洞扫描服务作为一种主动防御工具,逐渐成为企业安全体系的标配。本文将从特点与优势两方面,解析其价值与应用场景…...
大中型水闸安全监测系统解决方案
一、系统概述 水闸是重要的水利基础设施,具有防洪、挡潮、排涝、灌溉、供水、生态、航运和水力发电等综合功能,在国家水网构建、支撑经济社会高质量发展等方面具有十分重要的作用。我国水闸工程面广量大,据2021年统计数据,我国已建…...
紫光同创FPGA实现AD9238数据采集转UDP网络传输,分享PDS工程源码和技术支持和QT上位机
目录 1、前言工程概述免责声明 2、相关方案推荐我已有的所有工程源码总目录----方便你快速找到自己喜欢的项目紫光同创FPGA相关方案推荐我这里已有的以太网方案本方案在Xilinx系列FPGA的应用方案 3、设计思路框架工程设计原理框图AD输入源AD9238数据采集AD9238数据缓存控制模块…...
ffmpeg 把一个视频复制3次
1. 起因, 目的: 前面我写过,使用 python 把一个视频复制3次但是速度太慢了,我想试试看能否改进。而且我想换一种新的视频处理思路,并试试看速度如何。 2. 先看效果 效果就是能行,而且速度也快。 3. 过程: 代码 1…...
仿腾讯会议——添加音频
1、实现开启或关闭音频 2、 定义信号 3、实现开始暂停音频 4、实现信号槽连接 5、回收资源 6、初始化音频视频 7、 完成为每个人创建播放音频的对象 8、发送音频 使用的是对象ba,这样跨线程不会立刻回收,如果使用引用,跨线程会被直接回收掉&a…...