您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# Spring Boot 2.x整合Elasticsearch 7.x的全过程详解
## 一、前言
### 1.1 技术背景
Elasticsearch作为基于Lucene的分布式搜索引擎,以其**高性能、可扩展性**和**丰富的查询功能**成为大数据搜索领域的首选方案。Spring Boot作为Java生态中最流行的微服务框架,其**约定优于配置**的理念极大简化了企业级应用开发。
### 1.2 版本选择考量
- Spring Boot 2.3.x+ 官方开始支持ES 7.x客户端
- Elasticsearch 7.x 移除type概念,性能提升40%
- 注意JDK版本兼容性(ES7需要JDK11+)
## 二、环境准备
### 2.1 基础环境配置
```bash
# 开发环境要求
- JDK 11+
- Maven 3.6+
- Elasticsearch 7.9.2(测试版本)
<!-- pom.xml关键依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- 使用High Level REST Client -->
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.9.2</version>
</dependency>
</dependencies>
# application.yml
spring:
elasticsearch:
rest:
uris: http://localhost:9200
username: elastic
password: changeme
connection-timeout: 5000
read-timeout: 30000
@Configuration
public class ElasticsearchConfig {
@Value("${spring.elasticsearch.rest.uris}")
private String[] uris;
@Bean
public RestHighLevelClient client() {
ClientConfiguration config = ClientConfiguration.builder()
.connectedTo(uris)
.withConnectTimeout(Duration.ofSeconds(5))
.withSocketTimeout(Duration.ofSeconds(30))
.build();
return RestClients.create(config).rest();
}
}
@Document(indexName = "products", createIndex = false)
public class Product {
@Id
private String id;
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String name;
@Field(type = FieldType.Double)
private Double price;
@Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
private Date createTime;
}
PUT /products
{
"mappings": {
"properties": {
"name": {
"type": "text",
"analyzer": "ik_smart"
},
"price": {
"type": "scaled_float",
"scaling_factor": 100
}
}
}
}
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
List<Product> findByName(String name);
Page<Product> findByPriceBetween(Double min, Double max, Pageable pageable);
}
@Repository
public class ProductCustomRepositoryImpl implements ProductCustomRepository {
@Autowired
private RestHighLevelClient client;
public List<Product> complexQuery(String keyword, Date startDate) {
NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
queryBuilder.withQuery(QueryBuilders.boolQuery()
.must(QueryBuilders.matchQuery("name", keyword))
.filter(QueryBuilders.rangeQuery("createTime").gte(startDate)));
SearchHits<Product> hits = elasticsearchOperations.search(
queryBuilder.build(), Product.class);
// 结果处理...
}
}
@Async
public CompletableFuture<Page<Product>> asyncSearch(String query) {
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.queryStringQuery(query))
.build();
return CompletableFuture.completedFuture(
elasticsearchOperations.queryForPage(searchQuery, Product.class));
}
@Autowired
private ElasticsearchRestTemplate template;
public void bulkIndex(List<Product> products) {
BulkRequest bulkRequest = new BulkRequest();
products.forEach(p -> {
IndexRequest request = new IndexRequest("products")
.id(p.getId())
.source(BeanUtil.beanToMap(p));
bulkRequest.add(request);
});
client.bulk(bulkRequest, RequestOptions.DEFAULT);
}
@Bean
public RestClientBuilderCustomizer restClientBuilderCustomizer() {
return builder -> builder
.setHttpClientConfigCallback(httpClientBuilder -> {
httpClientBuilder.setMaxConnTotal(50);
httpClientBuilder.setMaxConnPerRoute(10);
return httpClientBuilder;
});
}
// 使用source filtering减少网络传输
SearchSourceBuilder sourceBuilder = new SearchSourceBuilder()
.fetchSource(new String[]{"name", "price"}, null);
// 启用查询缓存
QueryBuilder queryBuilder = QueryBuilders
.termQuery("category", "electronics")
.queryName("cached_query");
@ControllerAdvice
public class ElasticsearchExceptionHandler {
@ExceptionHandler(ElasticsearchStatusException.class)
public ResponseEntity<String> handleEsException(ElasticsearchStatusException e) {
return ResponseEntity.status(e.status().getStatus())
.body("ES服务异常: " + e.getDetailedMessage());
}
}
@Retryable(value = { ElasticsearchException.class },
maxAttempts = 3,
backoff = @Backoff(delay = 1000))
public void updateProduct(Product product) {
// 更新操作...
}
@SpringBootTest
@ExtendWith(SpringExtension.class)
public class ProductRepositoryTest {
@Autowired
private ProductRepository repository;
@Test
public void testIndexAndSearch() {
Product product = new Product();
product.setName("华为手机");
repository.save(product);
List<Product> result = repository.findByName("华为");
assertThat(result).hasSize(1);
}
}
@Test
public void benchmarkSearch() {
int threadCount = 50;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
LongAdder counter = new LongAdder();
IntStream.range(0, 1000).forEach(i -> {
executor.submit(() -> {
repository.search(new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.matchAllQuery()).build());
counter.increment();
});
});
// 输出QPS...
}
# 集成Prometheus监控
management:
endpoints:
web:
exposure:
include: prometheus,health,info
metrics:
export:
prometheus:
enabled: true
本文详细介绍了Spring Boot 2.x与Elasticsearch 7.x整合的全流程,涵盖从环境搭建到生产部署的完整知识体系。关键点包括: 1. 使用RestHighLevelClient替代TransportClient 2. 新版Spring Data Elasticsearch的API变化 3. 性能调优的二十个实用技巧
最佳实践建议:对于高并发场景,建议结合Spring Cache实现二级缓存,可降低ES集群压力30%以上。 “`
(注:实际文章内容会根据技术细节展开每个章节的详细说明,包含代码示例的完整实现、参数调优的具体数值分析、性能对比测试数据等,此处为保持简洁仅展示核心框架和关键代码片段)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。