Spring Boot + Spring Cloud 集成 Elasticsearch:从零搭建企业级搜索服务

Spring Boot + Spring Cloud 集成 Elasticsearch:从零搭建企业级搜索服务

引言

在微服务架构大行其道的今天,Elasticsearch 凭借其强大的全文检索、实时聚合和水平扩展能力,已经成为电商搜索、日志分析、数据可视化等场景的事实标准。而 Spring Boot 作为 Java 生态中主流的微服务开发框架,为 ES 的集成提供了开箱即用的自动配置支持。

本文将围绕 "如何写代码""如何部署" 两条主线,从版本选型、代码分层、API 调用、微服务整合,再到生产级部署与运维监控,形成完整的实践闭环。通过本文,你将掌握:

  • Spring Boot 中集成 ES 的完整代码结构(实体层 → Repository → Service → Controller)
  • 新旧客户端(Elasticsearch Java API Client vs High Level REST Client)的选型与迁移指南
  • 在 Spring Cloud 微服务架构中使用 ES 实现全文检索
  • 从单机 Docker 到生产级 Kubernetes 集群的部署方案
  • 搜索服务的高性能优化与数据同步策略

一、核心概念与前置准备

1.1 Elasticsearch 核心概念速览

在动手写代码之前,先快速回顾 ES 的几个核心概念:

概念 说明 代码层面对应
Index(索引) 存储文档的逻辑容器,类似关系库的 Database @Document(indexName = "xxx")
Document(文档) JSON 结构的可索引实体,类似关系库的 Row Java POJO 对象
Mapping(映射) 定义字段类型与分词规则 @Field(type = FieldType.Text, analyzer = "ik_max_word")
Node(节点) 一个 ES 实例,即一个 JVM 进程 配置文件 node.name
Cluster(集群) 多个节点组成的整体,提供高可用与水平扩展 cluster.name

1.2 环境准备

  • Java 11 或 17(推荐 JDK 17 + Spring Boot 3.x)
  • Docker 或已部署的 ES 集群
  • IDE 工具(IntelliJ IDEA / VS Code)
  • Postman 或 curl 用于接口测试

二、版本选型:第一步就要"对齐"

2.1 版本兼容性矩阵

这是最容易被忽视也最容易踩坑的环节。不同版本的 Spring Boot、Spring Data Elasticsearch 和 ES Server 之间存在严格的版本依赖关系。

Spring Boot Spring Data Elasticsearch ES Server 默认客户端类型
2.7.x 4.4.x 7.17.x RestHighLevelClient(旧版,将被逐步淘汰)
3.0.x ~ 3.2.x 5.1.x 8.7.x Java API Client
3.3+ 5.2+ 8.9+ Java API Client

2.2 特别提醒:RestHighLevelClient 已进入淘汰期

⚠️ 重要变化RestHighLevelClient 在 Elasticsearch 7.15 起被标记为 deprecated,在 8.x 中已不再支持。Spring Boot 3.0+ 和 Spring Data Elasticsearch 5.0+ 彻底移除了对它的依赖。

如果你的项目是新建服务或正在升级,必须使用新的 elasticsearch-java 客户端

在新版 ES 8.x + Spring Boot 3.x 场景下,RestHighLevelClient 已不再兼容。

2.3 本文选型参考

为了使示例代码既兼容当前主流实践、又面向未来,本文采用:

  • Spring Boot 3.1.x
  • Elasticsearch 8.8+
  • Spring Data Elasticsearch 5.1.x + Java API Client

三、Spring Boot 集成 ES:代码实战

3.1 引入 Maven 依赖

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.1.5</version>
</parent>

<dependencies>
    <!-- Spring Data Elasticsearch(自动引入 elasticsearch-java 客户端) -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    </dependency>

    <!-- Web 层支持 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Lombok(可选,简化 POJO) -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

⚠️ 注意 :Spring Boot 3.x 的 spring-boot-starter-data-elasticsearch 默认依赖于 elasticsearch-java 客户端,而非 RestHighLevelClient。手动混用旧版客户端将会引发 ClassNotFoundException

3.2 配置文件(application.yml)

yaml 复制代码
spring:
  elasticsearch:
    uris:
      - http://localhost:9200
    # 如果集群开启了安全认证
    # username: elastic
    # password: your_password
    # 连接配置(可选)
    connection-timeout: 5s
    socket-timeout: 30s

  data:
    elasticsearch:
      repositories:
        enabled: true

3.3 创建实体类:用注解定义映射

Elasticsearch 中的文档通过 @Document 注解定义,字段类型通过 @Field 注解声明。

java 复制代码
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@Document(indexName = "product")  // 索引名称
public class Product {

    @Id
    private String id;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String name;           // 商品名称,中文分词

    @Field(type = FieldType.Keyword)
    private String category;       // 分类,精确匹配

    @Field(type = FieldType.Double)
    private BigDecimal price;      // 价格

    @Field(type = FieldType.Integer)
    private Integer stock;         // 库存

    @Field(type = FieldType.Date)
    private LocalDateTime createTime;
}

关键注解说明

  • @Document(indexName = "product"):指定索引名称(等同关系库中的 Database)
  • @Field(type = FieldType.Text, analyzer = "ik_max_word"):声明 text 类型字段,使用 IK 中文分词器进行最大粒度切分
  • @Field(type = FieldType.Keyword):keyword 类型用于精确匹配、聚合排序
  • @Id:标记文档的唯一 ID,对应 ES 中的 _id 字段

3.4 Repository 层:继承接口即可拥有 CRUD

java 复制代码
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

    // 根据 category 精确匹配(自动解析)
    List<Product> findByCategory(String category);

    // 商品名称包含关键词 + 分页
    Page<Product> findByNameContaining(String keyword, Pageable pageable);

    // 价格区间查询
    List<Product> findByPriceBetween(BigDecimal min, BigDecimal max);
}

Spring Data Elasticsearch 的 ElasticsearchRepository 接口已经实现了基础的 CRUD 方法(save、findById、delete、findAll、count 等),直接继承即可使用。

如果需要更复杂的查询,可以用 方法命名规则

  • findByFieldContaining → 相当于 SQL 中的 LIKE '%value%'
  • findByFieldStartingWithLIKE 'value%'
  • findByFieldBetween → 范围查询
  • findByFieldIn(Collection)IN 查询

Spring Boot 支持通过 ElasticsearchOperations 工具类实现更底层的灵活操作,这在需要构建复杂原生 DSL 时非常实用。

3.5 Service 层:业务逻辑封装

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Optional;

@Service
public class ProductSearchService {

    @Autowired
    private ProductRepository productRepository;

    // 索引单条文档
    public Product indexProduct(Product product) {
        return productRepository.save(product);
    }

    // 批量索引
    public Iterable<Product> indexProducts(List<Product> products) {
        return productRepository.saveAll(products);
    }

    // 根据 ID 检索
    public Optional<Product> getProductById(String id) {
        return productRepository.findById(id);
    }

    // 关键词全文搜索(分页)
    public Page<Product> searchByKeyword(String keyword, int page, int size) {
        return productRepository.findByNameContaining(keyword, PageRequest.of(page, size));
    }

    // 分类筛选
    public List<Product> searchByCategory(String category) {
        return productRepository.findByCategory(category);
    }

    // 删除文档
    public void deleteProduct(String id) {
        productRepository.deleteById(id);
    }
}

3.6 Controller 层:RESTful API 暴露

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/search")
public class SearchController {

    @Autowired
    private ProductSearchService searchService;

    @PostMapping("/index")
    public ResponseEntity<Product> indexProduct(@RequestBody Product product) {
        return ResponseEntity.ok(searchService.indexProduct(product));
    }

    @GetMapping("/product/{id}")
    public ResponseEntity<Product> getProduct(@PathVariable String id) {
        return searchService.getProductById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }

    @GetMapping("/keyword")
    public ResponseEntity<Page<Product>> searchByKeyword(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size) {
        return ResponseEntity.ok(searchService.searchByKeyword(keyword, page, size));
    }

    @GetMapping("/category/{category}")
    public ResponseEntity<List<Product>> searchByCategory(@PathVariable String category) {
        return ResponseEntity.ok(searchService.searchByCategory(category));
    }
}

3.7 完整代码结构总览

Elasticsearch
Spring Boot 应用
product 实体类

@Document
ProductRepository

继承ElasticsearchRepository
ProductSearchService

业务逻辑封装
SearchController

RESTful API暴露
客户端请求
索引: product
文档: JSON 数据

四、高阶查询:构建复杂搜索逻辑

4.1 使用 QueryBuilders 构建 DSL 查询

当方法命名规则无法满足复杂查询需求时,可以直接使用 ElasticsearchOperations 配合 NativeSearchQueryBuilder 构建原生 DSL 查询。

java 复制代码
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import co.elastic.clients.elasticsearch._types.query_dsl.QueryBuilders;

@Service
public class AdvancedSearchService {

    @Autowired
    private ElasticsearchOperations elasticsearchOperations;

    // 多字段 + 多条件组合查询
    public List<Product> advancedSearch(String keyword, Double minPrice, Double maxPrice, String category) {
        // 构建 bool 查询
        var boolQuery = QueryBuilders.bool();

        // must:全文匹配分词
        if (keyword != null && !keyword.isEmpty()) {
            boolQuery.must(QueryBuilders.match(m -> m
                .field("name")
                .query(keyword)
            ));
        }

        // filter:过滤条件,不计分,可缓存
        if (minPrice != null || maxPrice != null) {
            var rangeBuilder = QueryBuilders.range(r -> r.field("price"));
            if (minPrice != null) rangeBuilder.gte(minPrice);
            if (maxPrice != null) rangeBuilder.lte(maxPrice);
            boolQuery.filter(rangeBuilder.build());
        }

        if (category != null && !category.isEmpty()) {
            boolQuery.filter(QueryBuilders.term(t -> t.field("category").value(category)));
        }

        // 构建并执行查询
        NativeQuery query = NativeQuery.builder()
            .withQuery(q -> q.bool(boolQuery.build()))
            .withPageable(PageRequest.of(0, 20))
            .build();

        SearchHits<Product> hits = elasticsearchOperations.search(query, Product.class);
        return hits.stream().map(SearchHit::getContent).toList();
    }
}

4.2 分页 + 高亮(Highlight)实现

搜索结果高亮是搜索体验的重要组成部分。使用 ElasticsearchOperations 配合高亮设置,可以呈现匹配词的前后文。

网上能找到的教程大多没有把分页和高亮一起适配,而 ElasticsearchOperations 恰好支持两者无缝结合,不需要额外写一整套 JSON 解析代码来处理混搭高亮数据的复杂对象。

java 复制代码
public SearchResult<Product> searchWithHighlight(String keyword, int page, int size) {
    // 高亮配置
    var highlight = new Highlight.Builder()
        .fields("name", hf -> hf
            .preTags("<em>")
            .postTags("</em>")
            .fragmentSize(50)
            .numberOfFragments(1)
        )
        .build();

    NativeQuery query = NativeQuery.builder()
        .withQuery(q -> q.match(m -> m.field("name").query(keyword)))
        .withHighlight(highlight)
        .withPageable(PageRequest.of(page, size))
        .build();

    SearchHits<Product> searchHits = elasticsearchOperations.search(query, Product.class);
    
    // 合并高亮内容到结果中(可根据业务定制)
    Map<String, List<String>> highlightedFields = new HashMap<>();
    for (SearchHit<Product> hit : searchHits) {
        if (hit.getHighlightFields() != null) {
            highlightedFields.put(hit.getId(), hit.getHighlightFields().get("name"));
        }
    }
    
    return new SearchResult<>(searchHits.getSearchHits().stream()
        .map(SearchHit::getContent).collect(Collectors.toList()),
        searchHits.getTotalHits(), highlightedFields);
}

五、微服务架构中的 Elasticsearch

在 Spring Cloud 微服务体系中,Elasticsearch 通常作为独立的中间件服务被其他业务微服务调用,而非直接嵌入在某个业务服务内部。

5.1 典型微服务架构图

中间件
搜索中台
业务微服务
API网关
数据变更
消费写入
Spring Cloud Gateway
订单服务
用户服务
商品服务
搜索API服务
Elasticsearch集群
Redis缓存
Kafka消息队列

5.2 微服务隔离原则:独立搜索服务

在微服务架构中,建议将 Elasticsearch 的操作封装成一个独立的搜索服务search-service),其他微服务(如订单、商品、用户)通过 Feign 远程调用 或 REST API 访问该服务,而不是让每个微服务直接连接 ES。

独立搜索服务的优势

  • 统一 ES 版本管理,避免各服务使用不同的客户端版本和连接池配置
  • 索引结构变更只需更新搜索服务,无需修改所有微服务
  • 便于集中维护分片策略、副本数和查询优化逻辑

项目结构示例(微服务模式下):

复制代码
cloud-platform/
├── search-service/          # 独立搜索服务(集成 ES)
│   ├── src/main/java/...
│   └── pom.xml
├── product-service/         # 商品服务
├── order-service/           # 订单服务
└── user-service/            # 用户服务

5.3 数据同步策略:MySQL + ES 双写

微服务架构中最常见的业务模式是:MySQL 作为主数据库,Elasticsearch 作为搜索引擎。两者之间的数据同步有三种主流方案:

同步方式 适用场景 优点 缺点
应用层双写 简单业务,数据量可控 实现简单,实时性高 业务代码侵入,可能造成数据不一致
Canal 监听 binlog 中大规模,要求强一致性 无业务侵入,同步延迟毫秒级 需要额外部署 Canal+MQ 组件
消息队列异步通知 分布式微服务场景 解耦性好,削峰填谷 需要引入 MQ,有一定的消息延迟

应用层双写示例(在商品服务中):

java 复制代码
@Service
public class ProductService {
    @Autowired
    private ProductMapper productMapper;      // MySQL

    @Autowired
    private SearchFeignClient searchClient;   // Feign 调用搜索服务

    @Transactional
    public void createProduct(Product product) {
        // 1. 写入 MySQL
        productMapper.insert(product);
        // 2. 通过 Feign 调用搜索服务索引数据(ES 索引)
        searchClient.indexProduct(product);
    }
}

Canal + Kafka 同步架构
binlog
生产消息
消费消息
MySQL
Canal Server
Kafka Topic
搜索API服务
Elasticsearch

使用 Canal 监听 MySQL binlog,将数据变更投递到 Kafka,搜索服务作为消费者进行索引更新,可实现毫秒级的近实时同步。


六、Elasticsearch 部署:从本地到生产

6.1 本地开发部署(Docker Compose 单节点)

最简单的方式是用 Docker 拉起一个单节点 ES,用于开发和测试。

docker-compose.yml

yaml 复制代码
version: '3.8'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2
    container_name: es-dev
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - es_data:/usr/share/elasticsearch/data

  kibana:
    image: docker.elastic.co/kibana/kibana:8.8.2
    container_name: kibana
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://es-dev:9200
    depends_on:
      - elasticsearch

volumes:
  es_data:

启动命令:

bash 复制代码
docker-compose up -d
# 验证 ES 是否正常
curl http://localhost:9200

6.2 生产环境集群部署

生产级 ES 集群需要考虑高可用、数据安全和性能监控三大核心要素。以下是一个典型的 3 节点集群配置:

集群架构与配置要求

节点角色 数量 硬件建议 核心配置
主节点(Master Eligible) ≥3 8C/16GB/SSD node.master: true node.data: false
数据节点(Data Node) 按需扩展 16C/32GB+SSD node.data: true node.master: false
协调节点(Coordinating Only) ≥2 8C/16GB node.master: false node.data: false

Docker Compose 生产环境配置示例(3 节点集群 + SSL/TLS):

yaml 复制代码
version: '3.8'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-prod-cluster
      - discovery.seed_hosts=es01,es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms16g -Xmx16g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - "9200:9200"
    networks:
      - elastic

  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-prod-cluster
      - discovery.seed_hosts=es01,es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms16g -Xmx16g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic

  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.2
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-prod-cluster
      - discovery.seed_hosts=es01,es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms16g -Xmx16g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

volumes:
  data01:
  data02:
  data03:

networks:
  elastic:

JVM 堆内存应设置为物理内存的 50%,且不超过 32 GB(以避免指针压缩失效)。文件系统缓存应预留至少 50% 的空闲内存。

6.3 Kubernetes 部署(适用于大规模容器化)

对于 Kubernetes 生产环境,使用 ECK(Elastic Cloud on Kubernetes) 是官方推荐的最佳方式。ECK 提供了 CRD(Custom Resource Definition),可简化 ES 集群的编排与管理。

bash 复制代码
# 安装 ECK 操作符
kubectl create -f https://download.elastic.co/downloads/eck/2.10.0/crds.yaml
kubectl apply -f https://download.elastic.co/downloads/eck/2.10.0/operator.yaml

# 创建 ES 集群
cat <<EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 8.8.2
  nodeSets:
  - name: default
    count: 3
    config:
      node.store.allow_mmap: false
    volumeClaimTemplates:
    - metadata:
        name: elasticsearch-data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 50Gi
EOF

七、生产环境优化与最佳实践

7.1 索引优化

  • 批量写入 :使用 saveAll() 或 Bulk API 批量提交,每批 1000-5000 条,间隔 5-10 秒。
  • 调整刷新间隔 :允许数据延迟时,调高 refresh_interval(如 30s)以提升写入吞吐量。
  • 禁用不需要的功能 :若不需要精确计数,设 track_total_hits: false

7.2 查询与高并发优化

  • 使用过滤器缓存:倒排索引本身已对 term 查询做了大量优化;对于高频的过滤查询,建议在应用层嵌入缓存逻辑。
  • 合理设置副本数:副本可提升读吞吐,但会增加写入负载。对于核心业务建议至少 1 个副本。
  • 外挂热点缓存(Redis):高频查询结果可缓存在 Redis 中,减少 ES 查询压力。
java 复制代码
// Redis 缓存示例
public List<Product> search(String keyword, int page, int size) {
    String cacheKey = "search:" + keyword + ":" + page + ":" + size;
    List<Product> cached = redisTemplate.opsForValue().get(cacheKey);
    if (cached != null) {
        return cached;
    }
    Page<Product> result = productRepository.findByNameContaining(keyword, PageRequest.of(page, size));
    redisTemplate.opsForValue().set(cacheKey, result.getContent(), Duration.ofMinutes(5));
    return result.getContent();
}

7.3 集群运维与监控

  • 关键监控指标:JVM 堆内存使用率、分片健康状态、查询延迟 P50/P99、节点 CPU/负载
  • 工具栈 :Kibana 监控 + Prometheus/Grafana(通过 elasticsearch_exporter
  • 日常操作 :定期执行 _forcemerge 减少 Segment 数量;监控慢查询日志(index.search.slowlog.threshold.query

八、总结:代码 ⇄ 部署全链路回顾

阶段 核心任务 关键产出
版本选型 对齐 SB 版本与 ES 版本 依赖配置、客户端选型
代码开发 实体 + Repository + Service + Controller 可运行的搜索 API 服务
微服务整合 独立搜索服务 + Feign 调用 + 数据同步 高内聚松耦合的微服务架构
本地部署 Docker Compose 单节点 开发/测试环境可用服务
生产部署 集群 + SSL + 监控 + 持久化 高可用、可观测的生产环境
持续优化 索引调优、缓存策略、慢查询分析 高性能、稳定性

本文从 Spring Boot 集成 ES 的代码层面出发,逐步延伸到微服务架构设计、数据同步策略和生产级部署方案,形成了一个完整的工程化闭环。在实际业务中,建议:

  1. 新建项目优先选择 ES 8.x + Spring Boot 3.x + Java API Client,避免踩坑老旧客户端的兼容性问题。
  2. 在微服务架构中,将 ES 操作封装为独立搜索服务,通过 Feign 对外提供能力。
  3. 生产环境使用 Docker Compose 多节点集群Kubernetes + ECK 部署,并做好监控告警。

相关推荐
半部论语2 小时前
CentOS7 + pyenv 安装 Python 3.11 完整指南)
大数据·elasticsearch·python3.11
sing~~2 小时前
SpringCloud的了解和使用
后端·spring·spring cloud
流觞 无依2 小时前
Spring Boot 未授权访问漏洞排查与修复指南
java·spring boot·后端
Java开发的小李2 小时前
SpringBoot 高流量高并发 基础全面讲解
java·spring boot·后端·性能优化
fan_music2 小时前
git使用教程
大数据·elasticsearch·搜索引擎
慕容卡卡3 小时前
Claude 使用神器(web页面)--CloudCLI UI
java·开发语言·前端·人工智能·ui·spring cloud
极创信息3 小时前
信创领域五种主流CPU架构(X86 / ARM / RISC-V / MIPS / LoongArch)
java·arm开发·数据库·spring boot·mysql·软件工程·risc-v
空中海3 小时前
Spring Cloud第三篇:通信篇 — OpenFeign 与负载均衡
spring·spring cloud·负载均衡
Elastic 中国社区官方博客3 小时前
通过受管控的控制平面加速商品陈列优化
大数据·数据库·人工智能·elasticsearch·搜索引擎·平面·ai