feat(core): 重构模型路由管理并更新 Nacos 配置- 移除 ModelProperties 类,使用数据库存储模型路由映射- 新增 ModelRouteMapping 实体类和 ModelRouteMappingRepository 接口 #40

Merged
gewuyou merged 1 commits from dev into test 2025-05-10 21:47:37 +08:00
7 changed files with 92 additions and 30 deletions

View File

@ -1,6 +1,5 @@
package org.jcnc.llmx.core.service.config package org.jcnc.llmx.core.service.config
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.client.loadbalancer.LoadBalanced import org.springframework.cloud.client.loadbalancer.LoadBalanced
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
@ -13,7 +12,6 @@ import org.springframework.web.reactive.function.client.WebClient
* @author gewuyou * @author gewuyou
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(ModelProperties::class)
open class AppConfiguration { open class AppConfiguration {
/** /**
* 创建一个配置了负载均衡的WebClient构建器 * 创建一个配置了负载均衡的WebClient构建器

View File

@ -1,21 +0,0 @@
package org.jcnc.llmx.core.service.config
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.cloud.context.config.annotation.RefreshScope
/**
*模型属性
*
* @since 2025-04-26 18:01:48
* @author gewuyou
*/
@ConfigurationProperties(prefix = "llmx.model-route")
@RefreshScope
open class ModelProperties {
/**
* 模型名前缀 -> 服务名映射
* 该映射表存储了模型名前缀与服务名的对应关系用于快速查找模型对应的服务
* openai -> llmhub-impl-openai
*/
var modelServiceMap: Map<String, String> = emptyMap()
}

View File

@ -0,0 +1,74 @@
package org.jcnc.llmx.core.service.domain.model
import jakarta.persistence.*
import org.hibernate.annotations.ColumnDefault
import java.time.OffsetDateTime
/**
* 表示模型与其路由信息之间的映射关系
* 该类用于定义模型与对应服务之间的关联
* 包括相关的描述信息和状态信息
*
* 使用注解来定义表名主键生成策略以及字段与数据库列的映射关系
*/
@Entity
@Table(name = "model_route_mapping", schema = "core")
open class ModelRouteMapping {
/**
* 映射关系的唯一标识符
* 使用序列生成器来自动生成ID
*/
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "model_route_mapping_id_gen")
@SequenceGenerator(
name = "model_route_mapping_id_gen",
sequenceName = "model_route_mapping_id_seq",
allocationSize = 1
)
@Column(name = "id", nullable = false)
open var id: Long? = null
/**
* 模型名称
* 用于标识与路由信息相关联的模型
*/
@Column(name = "model", nullable = false, length = 50)
open lateinit var model: String
/**
* 对应的服务名称
* 表示该模型所关联的具体服务实例
*/
@Column(name = "service_name", nullable = false, length = 50)
open lateinit var serviceName: String
/**
* 映射描述
* 提供有关映射的额外信息便于理解和维护
*/
@Column(name = "description", length = 150)
open var description: String? = null
/**
* 映射状态
* 表示当前映射是否启用默认情况下新映射是启用的
*/
@ColumnDefault("true")
@Column(name = "enabled")
open var enabled: Boolean=true
/**
* 创建时间
* 默认为创建新映射时的当前时间戳
*/
@ColumnDefault("CURRENT_TIMESTAMP")
@Column(name = "create_at", nullable = false)
open var createAt: OffsetDateTime? = null
/**
* 最后更新时间
* 记录映射信息的最后修改时间
*/
@Column(name = "update_at")
open var updateAt: OffsetDateTime? = null
}

View File

@ -2,7 +2,7 @@ package org.jcnc.llmx.core.service.manager
import com.gewuyou.forgeboot.core.extension.log import com.gewuyou.forgeboot.core.extension.log
import org.jcnc.llmx.core.service.config.ModelProperties import org.jcnc.llmx.core.service.repositories.ModelRouteMappingRepository
import org.springframework.stereotype.Component import org.springframework.stereotype.Component
/** /**
@ -16,7 +16,7 @@ import org.springframework.stereotype.Component
*/ */
@Component @Component
class ModelRouteManager( class ModelRouteManager(
private val modelProperties: ModelProperties private val modelRouteMappingRepository: ModelRouteMappingRepository,
) { ) {
/** /**
* 根据模型名查找对应服务 * 根据模型名查找对应服务
@ -29,10 +29,11 @@ class ModelRouteManager(
* @throws IllegalArgumentException 如果模型名不匹配任何已知前缀抛出此异常 * @throws IllegalArgumentException 如果模型名不匹配任何已知前缀抛出此异常
*/ */
fun resolveServiceName(model: String): String { fun resolveServiceName(model: String): String {
val modelServiceMap = modelProperties.modelServiceMap val modelServiceMap = modelRouteMappingRepository.findAllByEnabled(true)
.associate { it.model to it.serviceName }
log.info("modelServiceMap: $modelServiceMap") log.info("modelServiceMap: $modelServiceMap")
for ((prefix, serviceName) in modelServiceMap) { for ((model, serviceName) in modelServiceMap) {
if (model.startsWith(prefix)) { if (model.startsWith(model)) {
return serviceName return serviceName
} }
} }

View File

@ -0,0 +1,10 @@
package org.jcnc.llmx.core.service.repositories
import org.jcnc.llmx.core.service.domain.model.ModelRouteMapping
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.JpaSpecificationExecutor
interface ModelRouteMappingRepository : JpaRepository<ModelRouteMapping, Long>,
JpaSpecificationExecutor<ModelRouteMapping> {
fun findAllByEnabled(isEnabled: Boolean): List<ModelRouteMapping>
}

View File

@ -1,7 +1,7 @@
spring: spring:
cloud: cloud:
nacos: nacos:
ip: 192.168.1.8 ip: 127.0.0.1
username: nacos username: nacos
password: L4s6f9y3, password: L4s6f9y3,
server-addr: 49.235.96.75:8848 server-addr: 49.235.96.75:8848

View File

@ -1,7 +1,7 @@
spring: spring:
cloud: cloud:
nacos: nacos:
ip: 192.168.1.8 ip: 127.0.0.1
username: nacos username: nacos
password: L4s6f9y3, password: L4s6f9y3,
server-addr: 49.235.96.75:8848 server-addr: 49.235.96.75:8848