重构消息队列连接管理,支持多数据源配置
主要变更: 1. 重构NATS、RabbitMQ和Redis连接管理模块,支持多数据源配置 2. 统一连接管理接口,增加数据源名称参数 3. 优化连接状态检查和错误处理 4. 增加连接池管理和资源清理机制 5. 改进日志输出格式和内容
This commit is contained in:
@@ -31,6 +31,9 @@ var (
|
||||
traceCancelMu sync.RWMutex
|
||||
// 取消主题前缀
|
||||
cancelSubjectPrefix = "ctx.cancel.otel."
|
||||
|
||||
// RPC 使用的默认数据源名称
|
||||
rpcDefaultDatasource = "default"
|
||||
)
|
||||
|
||||
// rpcHandler RPC 处理函数类型
|
||||
@@ -42,7 +45,7 @@ type rpcHandler func(ctx context.Context, req []byte) (any, error)
|
||||
// serviceName: 服务名称,调用方通过此名称调用服务
|
||||
// handler: 服务处理函数,接收请求并返回响应
|
||||
func registerRPCService(serviceName string, handler rpcHandler) (err error) {
|
||||
if !natsPing() {
|
||||
if !natsPing(context.Background(), rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
@@ -63,6 +66,11 @@ func registerRPCService(serviceName string, handler rpcHandler) (err error) {
|
||||
rpcServicesMu.Unlock()
|
||||
|
||||
// 订阅服务主题
|
||||
nc := getNatsConn(rpcDefaultDatasource)
|
||||
if nc == nil {
|
||||
return fmt.Errorf("NATS 连接不存在")
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("rpc.%s", serviceName)
|
||||
sub, err := nc.Subscribe(subject, func(msg *nats.Msg) {
|
||||
// 执行处理函数
|
||||
@@ -84,7 +92,7 @@ func registerRPCService(serviceName string, handler rpcHandler) (err error) {
|
||||
// queueName: 队列组名,同一队列组的实例共享请求
|
||||
// handler: 服务处理函数
|
||||
func registerQueueRPCService(serviceName, queueName string, handler rpcHandler) (err error) {
|
||||
if !natsPing() {
|
||||
if !natsPing(context.Background(), rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
@@ -111,6 +119,11 @@ func registerQueueRPCService(serviceName, queueName string, handler rpcHandler)
|
||||
queueRPCMu.Unlock()
|
||||
|
||||
// 订阅服务主题(队列模式)
|
||||
nc := getNatsConn(rpcDefaultDatasource)
|
||||
if nc == nil {
|
||||
return fmt.Errorf("NATS 连接不存在")
|
||||
}
|
||||
|
||||
subject := fmt.Sprintf("rpc.%s", serviceName)
|
||||
sub, err := nc.QueueSubscribe(subject, queueName, func(msg *nats.Msg) {
|
||||
// 执行处理函数
|
||||
@@ -209,7 +222,7 @@ func createCancelContext(ctx context.Context, traceID string) context.Context {
|
||||
//
|
||||
// sub, err := nats.SetupCancelListener(ctx)
|
||||
func setupCancelListener(ctx context.Context) (*nats.Subscription, error) {
|
||||
if !natsPing() {
|
||||
if !natsPing(ctx, rpcDefaultDatasource) {
|
||||
return nil, fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
@@ -219,6 +232,11 @@ func setupCancelListener(ctx context.Context) (*nats.Subscription, error) {
|
||||
|
||||
// 修复问题3:订阅取消主题,格式: ctx.cancel.otel.*
|
||||
// 使用 * 通配符而不是 >,因为 TraceID 是最后一部分
|
||||
nc := getNatsConn(rpcDefaultDatasource)
|
||||
if nc == nil {
|
||||
return nil, fmt.Errorf("NATS 连接不存在")
|
||||
}
|
||||
|
||||
cancelSubject := cancelSubjectPrefix + "*"
|
||||
sub, err := nc.Subscribe(cancelSubject, func(msg *nats.Msg) {
|
||||
// 从主题中解析 TraceID (去除前缀)
|
||||
@@ -261,7 +279,7 @@ func setupCancelListener(ctx context.Context) (*nats.Subscription, error) {
|
||||
//
|
||||
// err := nats.publishCancel(ctx, traceID)
|
||||
func publishCancel(ctx context.Context, traceID string) error {
|
||||
if !natsPing() {
|
||||
if !natsPing(ctx, rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
@@ -269,6 +287,11 @@ func publishCancel(ctx context.Context, traceID string) error {
|
||||
return fmt.Errorf("TraceID 不能为空")
|
||||
}
|
||||
|
||||
nc := getNatsConn(rpcDefaultDatasource)
|
||||
if nc == nil {
|
||||
return fmt.Errorf("NATS 连接不存在")
|
||||
}
|
||||
|
||||
cancelSubject := cancelSubjectPrefix + traceID
|
||||
err := nc.Publish(cancelSubject, nil)
|
||||
if err != nil {
|
||||
@@ -303,7 +326,7 @@ func cleanupTraceCancel(traceID string) {
|
||||
// req: 请求数据
|
||||
// 返回: 响应数据(任意类型)和错误
|
||||
func CallRPC(ctx context.Context, serviceName string, req any, resp any) (err error) {
|
||||
if !natsPing() {
|
||||
if !natsPing(ctx, rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
@@ -406,6 +429,11 @@ func CallRPC(ctx context.Context, serviceName string, req any, resp any) (err er
|
||||
}
|
||||
|
||||
// 发送请求
|
||||
nc := getNatsConn(rpcDefaultDatasource)
|
||||
if nc == nil {
|
||||
return fmt.Errorf("NATS 连接不存在")
|
||||
}
|
||||
|
||||
responseMsg, err := nc.RequestMsgWithContext(ctx, msg)
|
||||
|
||||
// 关闭 done channel,通知 goroutine 退出
|
||||
@@ -475,7 +503,7 @@ func WithExcludeMethods(methods ...string) registerServiceOption {
|
||||
// }, WithQueueGroup("order-group"))
|
||||
func AutoRegisterServices(ctx context.Context, serviceInstances map[string]interface{}, options ...registerServiceOption) error {
|
||||
// 先注册 RPC 服务(如果 NATS 不可用则记录警告但不阻塞启动)
|
||||
if !natsPing() {
|
||||
if !natsPing(ctx, rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接,RPC 服务未注册")
|
||||
}
|
||||
|
||||
@@ -512,7 +540,7 @@ func AutoRegisterServices(ctx context.Context, serviceInstances map[string]inter
|
||||
|
||||
// registerService 注册单个服务的所有公开方法(内部函数)
|
||||
func registerService(service interface{}, serviceNamePrefix string, options ...registerServiceOption) (err error) {
|
||||
if !natsPing() {
|
||||
if !natsPing(context.Background(), rpcDefaultDatasource) {
|
||||
return fmt.Errorf("NATS 未连接")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user