package com.xly.milvus.config; import io.milvus.v2.client.ConnectConfig; import io.milvus.v2.client.MilvusClientV2; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.retry.annotation.EnableRetry; import org.springframework.retry.support.RetryTemplate; @Slf4j @Configuration @EnableRetry public class MilvusConfig { @Value("${milvus.host:localhost}") private String host; @Value("${milvus.port:19530}") private Integer port; @Value("${milvus.database:default}") private String database; @Value("${milvus.username:}") private String username; @Value("${milvus.password:}") private String password; @Value("${milvus.connect-timeout:10000}") private Long connectTimeout; @Value("${milvus.rpc-deadline:10000}") private Long rpcDeadline; @Value("${milvus.keep-alive-time:300000}") private Long keepAliveTime; @Value("${milvus.keep-alive-timeout:5000}") private Long keepAliveTimeout; @Value("${milvus.secure:false}") private Boolean secure; @Value("${milvus.validate-on-startup:true}") private boolean validateOnStartup; @Value("${milvus.fail-on-connect-error:false}") private boolean failOnConnectError; @Value("${milvus.enable-precheck:true}") private boolean enablePrecheck; @Bean(destroyMethod = "close") public MilvusClientV2 milvusClient() { try { String uri = String.format("http://%s:%d", host, port); // 构建连接配置 ConnectConfig.ConnectConfigBuilder configBuilder = ConnectConfig.builder() .uri(uri) .dbName("default") .connectTimeoutMs(connectTimeout) .rpcDeadlineMs(rpcDeadline) .keepAliveTimeMs(keepAliveTime) .keepAliveTimeoutMs(keepAliveTimeout) .keepAliveWithoutCalls(true) .secure(secure) .enablePrecheck(enablePrecheck); // 添加认证信息(如果有) if (username != null && !username.isEmpty()) { configBuilder.username(username); if (password != null) { configBuilder.password(password); } } ConnectConfig connectConfig = configBuilder.build(); // 创建客户端 MilvusClientV2 client = new MilvusClientV2(connectConfig); // 检查xlyerp数据库是否存在,如果不存在则创建 var databases = client.listDatabases(); if (!databases.getDatabaseNames().contains(database)) { log.info("数据库 xlyerp 不存在,正在创建..."); client.createDatabase( io.milvus.v2.service.database.request.CreateDatabaseReq.builder() .databaseName(database) .build() ); log.info("数据库 xlyerp 创建成功"); } // 切换到xlyerp数据库 client.useDatabase (database); log.info("切换到数据库: {}",database); // 启动验证 if (validateOnStartup) { validateConnection(client); } return client; } catch (Exception e) { log.error("创建Milvus客户端时发生异常: {}", e.getMessage(), e); throw new RuntimeException("无法创建Milvus客户端", e); } } /** * 验证Milvus连接 - 基于源码中可用的方法 */ private void validateConnection(MilvusClientV2 client) { try { // 方法1: 检查服务器版本(源码中存在getServerVersion()) String serverVersion = client.getServerVersion(); // 方法2: 列出数据库(源码中存在listDatabases()) var databases = client.listDatabases(); // 方法3: 检查健康状态(源码中存在checkHealth()) var health = client.checkHealth(); System.out.println("✅ Milvus连接成功"); System.out.println(" - 服务器版本: " + serverVersion); System.out.println(" - 数据库: " + databases); System.out.println(" - 健康状态: " + health); // 验证指定数据库是否存在 if (database != null && !database.isEmpty()) { boolean dbExists = databases.getDatabaseNames().contains(database); if (!dbExists && !"default".equals(database)) { System.err.println("⚠️ 警告: 指定数据库 '" + database + "' 不存在"); } } } catch (Exception e) { String errorMsg = String.format("❌ Milvus连接失败: %s:%d - %s",host, port, e.getMessage()); if (failOnConnectError) { throw new IllegalStateException(errorMsg, e); } else { System.err.println(errorMsg); System.err.println(" ⚠️ 应用将继续启动,但Milvus功能可能不可用"); } } } /** * 配置重试模板(可选) */ @Bean public RetryTemplate milvusRetryTemplate() { return RetryTemplate.builder() .maxAttempts(3) .exponentialBackoff(1000, 2, 10000) .retryOn(Exception.class) .build(); } }