Elasticsearch:spring2.x集成elasticsearch8.x

news2025/6/9 13:43:47

相关安装就不介绍了直接代码集成

<!-- elasticsearch版本需要和你安装的版本一致 -->

<properties>
    <elasticsearch.version>8.11.1</elasticsearch.version>
    <jakarta-json.version>2.1.2</jakarta-json.version>
    <logstash.version>7.2</logstash.version>
    <jakarta-json-bind.version>3.0.0</jakarta-json-bind.version>
</properties>


<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${elasticsearch.version}</version>
    </dependency>

    <dependency>
        <groupId>co.elastic.clients</groupId>
        <artifactId>elasticsearch-java</artifactId>
        <version>${elasticsearch.version}</version>
        <exclusions>
            <exclusion>
                <artifactId>jakarta.json-api</artifactId>
                <groupId>jakarta.json</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>jakarta.json</groupId>
        <artifactId>jakarta.json-api</artifactId>
        <version>${jakarta-json.version}</version>
    </dependency>

    <dependency>
        <groupId>jakarta.json.bind</groupId>
        <artifactId>jakarta.json.bind-api</artifactId>
        <version>${jakarta-json-bind.version}</version>
    </dependency>

    <dependency>
        <groupId>net.logstash.logback</groupId>
        <artifactId>logstash-logback-encoder</artifactId>
        <version>${logstash.version}</version>
    </dependency>
</dependencies>
elasticsearch:
  # 集群配置(多个节点时使用,用逗号分隔)
  hosts: 127.0.0.1:9201,127.0.0.1:9202,127.0.0.1:9203
  
  # 认证信息
  username: kingxxxx
  password: xxxxx
  
  # API密钥(可选,与用户名/密码认证互斥)
  apikey:
  
  # 已注释的旧配置项(建议移除)
  host: 127.0.0.1
  port: 9200
package com.kingbal.config;

import cn.hutool.core.util.StrUtil;
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 lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponseInterceptor;
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.entity.ContentType;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StringUtils;

import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;

/**
 * <b>Function: </b> todo
 *
 * @program: ElasticSearchConfig
 * @Package: com.kingbal.config
 * @author: chocho
 * @date: 2025/06/04
 * @version: 1.0
 * @Copyright: 2025 www.kingbal.com Inc. All rights reserved.
 */
@Data
@Slf4j
@Configuration
@ConfigurationProperties(prefix = "gospel.elasticsearch")
public class ElasticSearchConfig {

    private String host;

    private int port;

    private String hosts;

    private String username;

    private String password;

    private String apikey;

    /**
     * 单节点没密码连接
     *
     * @return
     */
    @Bean
    @Primary
    public ElasticsearchClient client() {
        ElasticsearchTransport transport = null;
        // 不是集群时
        if (hosts.split(",").length == 1) {
            // 无账号、密码
            if (StrUtil.isEmpty(username) && StrUtil.isEmpty(password)) {
                RestClient client = RestClient.builder(new HttpHost(host, port, "http")).build();
                transport = new RestClientTransport(client, new JacksonJsonpMapper());
            } else {
                // 账号密码的配置
                final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
                credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
                // 自签证书的设置,并且还包含了账号密码
                RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
                        .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                        .setDefaultCredentialsProvider(credentialsProvider)
                        . addInterceptorLast(
                                (HttpResponseInterceptor)
                                        (response, context) ->
                                                response.addHeader("X-Elastic-Product", "Elasticsearch"));

                RestClient client = RestClient.builder(new HttpHost(host, port, "http"))
                        .setHttpClientConfigCallback(callback)
                        .build();
                transport = new RestClientTransport(client, new JacksonJsonpMapper());
            }
        } else {
            // 无账号、密码
            if (StrUtil.isEmpty(username) && StrUtil.isEmpty(password)) {
                transport = getElasticsearchTransport(toHttpHost());
            } else {
                transport = getElasticsearchTransport(username, password, toHttpHost());
            }
        }
        return new ElasticsearchClient(transport);
    }

    /**
     * ESes自签证书连接
     *
     * @return
     */
    @Bean
    public ElasticsearchClient clientByApiKey() {
        ElasticsearchTransport transport = null;
        if (StrUtil.isNotEmpty(apikey)) {
            transport = getElasticsearchTransport(apikey, toHttpHost());
        }
        return new ElasticsearchClient(transport);
    }


    private HttpHost[] toHttpHost() {
        if (!StringUtils.hasLength(hosts)) {
            throw new RuntimeException("invalid elasticsearch configuration");
        }
        String[] hostArray = hosts.split(",");
        HttpHost[] httpHosts = new HttpHost[hostArray.length];
        HttpHost httpHost;
        for (int i = 0; i < hostArray.length; i++) {
            String[] strings = hostArray[i].split(":");
            httpHost = new HttpHost(strings[0], Integer.parseInt(strings[1]), "http");
            httpHosts[i] = httpHost;
        }
        return httpHosts;
    }

    private static ElasticsearchTransport getElasticsearchTransport(String username, String password, HttpHost... hosts) {
        // 账号密码的配置
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));

        // 自签证书的设置,并且还包含了账号密码
        RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .setDefaultCredentialsProvider(credentialsProvider)
                .addInterceptorLast(
                        (HttpResponseInterceptor)
                                (response, context) ->
                                        response.addHeader("X-Elastic-Product", "Elasticsearch"))
                .addInterceptorLast((HttpResponseInterceptor) (response, context)
                        -> response.addHeader("X-Elastic-Product", "Elasticsearch"));
        // 用builder创建RestClient对象
        RestClient client = RestClient
                .builder(hosts)
                .setHttpClientConfigCallback(callback)
                .build();

        return new RestClientTransport(client, new JacksonJsonpMapper());
    }

    private static ElasticsearchTransport getElasticsearchTransport(HttpHost... hosts) {
        // 用builder创建RestClient对象
        RestClient client = RestClient
                .builder(hosts)
                .build();

        return new RestClientTransport(client, new JacksonJsonpMapper());
    }

    private static ElasticsearchTransport getElasticsearchTransport(String apiKey, HttpHost... hosts) {
        // 将ApiKey放入header中
        Header[] headers = new Header[]{new BasicHeader("Authorization", "ApiKey " + apiKey)};

        // es自签证书的设置
        RestClientBuilder.HttpClientConfigCallback callback = httpAsyncClientBuilder -> httpAsyncClientBuilder
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .addInterceptorLast(
                        (HttpResponseInterceptor)
                                (response, context) ->
                                        response.addHeader("X-Elastic-Product", "Elasticsearch"));
        // 用builder创建RestClient对象
        RestClient client = RestClient
                .builder(hosts)
                .setHttpClientConfigCallback(callback)
              //  .setDefaultHeaders(headers)
                .build();

        return new RestClientTransport(client, new JacksonJsonpMapper());
    }

}
package com.kingbal.common.util;

import co.elastic.clients.elasticsearch._types.Refresh;
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
import co.elastic.clients.elasticsearch.indices.GetIndexResponse;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import co.elastic.clients.elasticsearch._types.Result;
import com.gospel.config.ElasticSearchConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * <b>Function: </b> todo
 *
 * @program: ESUtils
 * @Package: com.kingbal.common.util
 * @author: chocho
 * @date: 2025/06/04
 * @version: 1.0
 * @Copyright: 2025 www.kingbal.com Inc. All rights reserved.
 */
@Slf4j
@Component
public class ESUtils<T> {

    @Autowired
    private ElasticSearchConfig config;

    /**
     * 增加index
     * @throws IOException
     */
    public void createIndex(String index) throws IOException {
        //写法比RestHighLevelClient更加简洁
        CreateIndexResponse indexResponse = config.client().indices().create(c -> c.index(index));
    }

    /**
     * 查询Index
     * @throws IOException
     */
    public GetIndexResponse queryIndex(String index) throws IOException {
        return config.client().indices().get(i -> i.index(index));
    }

    /**
     *  判断index是否存在
     * @return
     * @throws IOException
     */
    public boolean existsIndex(String index) throws IOException {
        BooleanResponse booleanResponse = config.client().indices().exists(e -> e.index(index));
        return booleanResponse.value();
    }

    /**
     * 删除index
     * @param index
     * @return
     * @throws IOException
     */
    public DeleteIndexResponse deleteIndex(String index) throws IOException {
        return config.client().indices().delete(d -> d.index(index));
    }

    /**
     * 插入数据
     */
    public void addDocument(String index, T t) throws IOException {
        try {
            // 确保索引存在
            this.existsIndex(index);
            IndexResponse response = config.client().index(i -> i
                    .index(index)
                    .document(t)
                    .refresh(Refresh.True)
            );

            if (isSuccessResponse(response.result())) {
                log.warn("Document added successfully. ID: {}" , response.id());
            } else {
                log.info("Failed to add document. Result: {}", response.result());
            }
        } catch (IOException e) {
            log.error("IO error while adding document", e);
        } catch (Exception e) {
            log.error("Unexpected error while adding document", e);
        }
    }

    /**
     * 批量插入Document
     */
    public BulkResponse addDocumentAll(String index, List<BulkOperation> bulkOperationArrayList) throws IOException {
        return config.client().bulk(b -> b.index(index).operations(bulkOperationArrayList));
    }

    /**
     * 更新Document
     * @throws IOException
     */
    public UpdateResponse<T> updateDocumentIndex(String index, String id, T t) throws IOException {
        return config.client().update(u -> u.index(index).id(id).doc(t), this.getDocumentClass());
    }

    /**
     * 判断Document是否存在
     * @throws IOException
     */
    public BooleanResponse existDocumentIndex(String index) throws IOException {
        return config.client().exists(e -> e.index(index).id("1"));
    }


    /**
     * 查询Document
     * @throws IOException
     */
    public GetResponse<T> getDocumentIndex(String index, String id) throws IOException {
        return config.client().get(g -> g.index(index).id(id), this.getDocumentClass());
    }

    /**
     * 分页查询[精确查找]
     * @param index
     * @param query
     * @param page
     * @param size
     * @return
     * @throws IOException
     */
    public SearchResponse<T> searchPage(String index, Map<String, Object> query, int page, int size) throws IOException {
        System.out.println("Elasticsearch 服务版本: " + config.client().info().version().number());
        return config.client().search(s -> s
                .index(index)
                .query(q -> q.matchAll(m -> m))
                .from((page - 1) * size)
                .size(size), this.getDocumentClass());
    }

    /**
     * 删除Document
     * @throws IOException
     */
    public DeleteResponse deleteDocumentIndex(String index, String id) throws IOException {
        return config.client().delete(d -> d.index(index).id(id).refresh(Refresh.True));
    }

    /**
     * 获取文档类型
     * 注意:由于Java泛型擦除,这里返回Object.class
     * 如果需要具体类型,建议通过构造函数传入Class对象
     */
    @SuppressWarnings("unchecked")
    private Class<T> getDocumentClass() {
        // 由于Java泛型擦除,这里只能返回Object.class
        // 实际使用中可以通过构造函数传入Class<T>参数
        return (Class<T>) Object.class;
    }

    /**
     * 判断响应结果是否成功
     */
    private boolean isSuccessResponse(Result result) {
        return result == Result.Created || result == Result.Updated;
    }

}
package com.kingbal.modules.es;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * <b>Function: </b> todo
 *
 * @program: User
 * @Package: com.kingbal.modules.es
 * @author: chocho
 * @date: 2025/06/04
 * @version: 1.0
 * @Copyright: 2025 www.kingbal.com Inc. All rights reserved.
 */
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class EsUser implements Serializable {

    private static final long serialVersionUID = -5139036572222038978L;

    public String userName;
    public int age;

    public EsUser() {}
    
}
package com.kingbal.modules.es;

import cn.hutool.core.collection.CollUtil;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.elasticsearch.core.search.Hit;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.gospel.common.util.ESUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <b>Function: </b> todo
 *
 * @program: TestEsTest
 * @Package: com.kingbal.modules.es
 * @author: chocho
 * @date: 2025/06/04
 * @version: 1.0
 * @Copyright: 2025 www.kingbal.com Inc. All rights reserved.
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class TestEsTest {

    @Autowired
    private ESUtils<EsUser> esUtil;

    @Test
    public void test() throws Exception{
        List<EsUser> userList = Lists.newArrayList();
        for (int i = 0; i < 12; i++){
            EsUser user = new EsUser();
            user.setUserName("aaa" + i);
            user.setAge(12 +i);
            userList.add(user);
        }
        String index = "test-all";
        if (CollUtil.isNotEmpty(userList)) {
            if (!esUtil.existsIndex(index)) {
                esUtil.createIndex(index);
            }
            List<BulkOperation> bulkOperationArrayList = new ArrayList<>();
            //遍历添加到bulk中
            for (EsUser obj : userList) {
                bulkOperationArrayList.add(BulkOperation.of(o -> o.index(i -> i.document(obj))));
            }
            BulkResponse bulkResponse = esUtil.addDocumentAll(index, bulkOperationArrayList);
            System.out.println("took:" + bulkResponse.took());
            System.out.println(bulkResponse.items());

            Map<String, Object> params = Maps.newHashMap();
            params.put("userName", "bb");

            EsUser esUser = new EsUser();
            esUser.setUserName("bbbb");
            esUser.setAge(2222);
            System.out.println("******************");
            esUtil.addDocument(index,  esUser);
            System.out.println("******************");
            SearchResponse<EsUser> getResponse = esUtil.searchPage(index, params, 1, 10);
            System.out.println(getResponse);
            assert getResponse.hits().total() != null;
            System.out.println("总数:" + getResponse.hits().total().value());
            if(getResponse.hits().total().value() > 0){
                getResponse.hits().hits().forEach(hit -> {
                    System.out.println(hit.index());
                    System.out.println(hit.id());
                    System.out.println(hit.source());
                });
            }

        }
    }

}

这样集成即完成,如果在启动的时候会去读取默认配置信息我们只需要在启动类中添加以下代码即可:

@SpringBootApplication(exclude = {  

org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration.class
})

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

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

相关文章

华为云Flexus+DeepSeek征文|华为云一键部署知识库搜索增强版Dify平台,构建智能聊天助手实战指南

目录 前言 1 架构描述 2 资源栈创建流程详解 2.1 选择部署模板 2.2 参数配置内容 2.3 资源栈设置选项 2.4 配置确认与执行方式 3 部署过程与控制台反馈 3.1 实时资源监控 3.2 资源详情与访问路径 3.3 模板与事件管理 4 知识库构建流程 4.1 数据导入操作 4.2 文本…

分形几何在医学可视化中的应用:从理论到Python实战

分形几何在医学可视化中的应用&#xff1a;从理论到Python实战 前言 分形几何作为描述自然界复杂结构的数学工具&#xff0c;正通过其自相似性和分数维度特性&#xff0c;革新医学影像分析领域。本文系统阐述分形几何在医学影像中的创新应用&#xff0c;涵盖从图像预处理、分…

ESP-Brookesia:融合 AI 大模型,全新一代 GUI 开发与管理平台

乐鑫信息科技 (688018.SH) 推出 ESP-Brookesia ——一款专为物联网设备打造、集成 AI 交互能力的 UI 开发与管理框架。 ESP-Brookesia 深度融合 AI 大模型技术&#xff0c;为智能屏显应用赋予语音识别、自然语言对话、拟人化反馈等能力&#xff0c;帮助开发者构建更智能、更具…

【MATLAB去噪算法】基于CEEMD联合小波阈值去噪算法(第三期)

02.去噪算法原理 1.引言 传统EMD方法存在模态混叠问题&#xff0c;即信号成分在不同IMF分量中出现碎片化分布。为改进这一问题&#xff0c;Huang等&#xff08;1999&#xff09;提出间歇性测试算法&#xff0c;但效果有限。Wu和Huang&#xff08;2009&#xff09;发展的集合经…

机器学习实战37-基于情感字典和机器学习的股市舆情分析可视化系统

文章目录 一、项目背景数字时代情感分析情况二、项目流程1.数据采集与预处理2.复合情感分析模型构建3.舆情分析可视化:三、机器学习算法原理1.支持向量机基础2.核函数与高维映射3.情感分类特征融合4.模型训练与优化四、实现代码五、系统特点与优势1.复合情感分析模型2.多维度可…

CAD多面体密堆积3D插件

插件介绍 CAD多面体密堆积3D插件可在AutoCAD内建立三维随机多面体密堆积模型。 插件内置物理动力学模拟算法&#xff0c;通过模拟重力、碰撞等现象&#xff0c;使多面体在虚拟环境中发生自然堆积&#xff0c;进而实现真实的堆积效果。多面体堆积模拟中存在的局部穿模问题可通…

LLMs 系列科普文(5)

在前文中&#xff0c;我们讲述了什么是基础模型&#xff0c;并重点以 LLaMA 3.1 基础模型为例&#xff0c;向大家演示了它可以做什么&#xff0c;有哪些问题或有趣的现象。 在进入新的主题内容之前&#xff0c;我们再次对 基础模型 做一些总结&#xff1a; 这是一个基于 toke…

HarmonyOS开发:显示图片功能详解

目录 前言 Image组件基础 1、Image组件概述 2、加载图片资源 3、存档图类型数据源 &#xff08;1&#xff09;本地资源 &#xff08;2&#xff09;网络资源 &#xff08;3&#xff09;Resource资源 &#xff08;4&#xff09;媒体库file://data/storage &#xff08;…

ORACLE 修改端口号之后无法启动?

Oracle数据库更改端口后出现监听器无法启动的问题确实较为常见&#xff0c;但并非必然发生。这一问题通常源于​​配置错误或环境冲突​​&#xff0c;而非端口修改本身。以下是系统性解决方案&#xff1a; &#x1f50d; ​​一、问题根源分析​​ ​​配置文件语法错误​​ 修…

Excel自动分列开票工具推荐

软件介绍 本文介绍一款基于Excel VBA开发的自动分列开票工具&#xff0c;可高效处理客户对账单并生成符合要求的发票清单。 软件功能概述 该工具能够将客户对账单按照订单号自动拆分为独立文件&#xff0c;并生成可直接导入发票清单系统的标准化格式。 软件特点 这是一款体…

Maven入门(够用)

1、Maven是什么&#xff1f; 这个问题非常不重要&#xff0c;或者说不应该上来就问maven是什么&#xff0c;而是直接学习maven怎么用能干什么&#xff0c;学完之后自然就知道了maven是个什么玩意儿&#xff0c;很多技术都是如此。 2、Maven下载 先准备Java环境&#xff0c;安…

自动化办公集成工具:一站式解决文档处理难题

1. 项目概述 在当今信息化时代,办公自动化已成为提升工作效率的关键。本文将详细介绍一款基于Python和PyQt5开发的「自动化办公集成工具」,该工具集成了多种常用的办公文档处理功能,包括批量格式转换、文本智能替换、表格数据清洗等,旨在为用户提供一站式的办公自动化解决方…

three.js 零基础到入门

three.js 零基础到入门 什么是 three.js为什么使用 three.js使用 Three.js1. 创建场景示例 2.创建相机3. 创建立方体并添加网格地面示例 5. 创建渲染器示例 6. 添加效果(移动/雾/相机跟随物体/背景)自动旋转示例效果 相机自动旋转示例 展示效果 实现由远到近的雾示例展示效果 T…

PublishSubject、ReplaySubject、BehaviorSubject、AsyncSubject的区别

python容易编辑&#xff0c;因此用pyrx代替rxjava3做演示会比较快捷。 pyrx安装命令&#xff1a; pip install rx 一、Subject&#xff08;相当于 RxJava 的 PublishSubject&#xff09; PublishSubject PublishSubject 将对观察者发送订阅后产生的元素&#xff0c;而在订阅前…

在Ubuntu22.04 系统中安装Docker详细教程

1.更新系统软件包 #确保您的系统软件包是最新的。这有助于避免安装过程中可能遇到的问题 sudo apt update sudo apt upgrade -y2.安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common -y3.替换软件源 echo "deb htt…

AUTOSAR实战教程--DoIP_01_配置项解释

配置项 解释 备注 DoIPChannelSARef 引用DoIP Tester的源地址&#xff0c;就是你在DoIP Tester这个Containter中配置的Tester实例。 DoIPChannelTARef 引用目标地址。就是你在DoIPTargetAddress这个Container中的配置。 DoIPPduRRxPduId 为该pdu设置一个ID用于DoIP…

机器人/智能车纯视觉巡线经典策略—滑动窗口+直方图法

作者&#xff1a;SkyXZ CSDN&#xff1a;SkyXZ&#xff5e;-CSDN博客 博客园&#xff1a;SkyXZ - 博客园 在机器人或智能车的自主导航任务中&#xff0c;视觉巡线是一项最为基础且关键的能力之一。通过摄像头实时获取道路图像&#xff0c;并基于图像信息判断行驶路径&#xff0…

503 Service Unavailable:服务器暂时无法处理请求,可能是超载或维护中如何处理?

处理 "503 Service Unavailable" 错误是服务器管理者面临的常见挑战之一。这种错误通常表示服务器暂时无法处理请求&#xff0c;可能是由于服务器超载、维护中或其他临时性问题导致的。在本文中&#xff0c;我将介绍如何处理 "503 Service Unavailable" 错…

虚拟机时间同步

一、常见同步方式 常见的虚拟机同步方式有给虚拟机配置ntp、或者用平台提供的agent对时与虚拟机所在的宿主机。第一种依赖网络、第二种依赖平台的agent这个三方工具。 二、利用ptp_kvm.ko来直接和宿主机同步时间 关键组件 ptp_kvm驱动、chrony。 PTP_KVM同步原理 |--------…

软件更新机制的测试要点与稳定性提升

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…