Sin descripción
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

rabbitmq_factory.go 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // factory/rabbitmq_factory.go
  2. package rabbitmq
  3. import (
  4. "fmt"
  5. "sync"
  6. "git.x2erp.com/qdy/go-base/config"
  7. amqp "github.com/streadway/amqp"
  8. )
  9. // RabbitMQFactory RabbitMQ工厂
  10. type RabbitMQFactory struct {
  11. mu sync.RWMutex
  12. clients map[string]*amqp.Channel
  13. conn *amqp.Connection
  14. config config.RabbitMQConfig
  15. }
  16. // NewRabbitMQFactory 创建RabbitMQ工厂
  17. func NewRabbitMQFactory() (*RabbitMQFactory, error) {
  18. cfg := config.GetConfig()
  19. if err := config.GetInitError(); err != nil {
  20. return nil, fmt.Errorf("failed to load config: %v", err)
  21. }
  22. rabbitConfig := cfg.GetRabbitMQ()
  23. if rabbitConfig.Host == "" || rabbitConfig.Port == 0 {
  24. return nil, fmt.Errorf("rabbitmq configuration is incomplete")
  25. }
  26. // 构建连接URL
  27. url := fmt.Sprintf("amqp://%s:%s@%s:%d/%s",
  28. rabbitConfig.Username,
  29. rabbitConfig.Password,
  30. rabbitConfig.Host,
  31. rabbitConfig.Port,
  32. rabbitConfig.Vhost)
  33. // 建立连接
  34. conn, err := amqp.Dial(url)
  35. if err != nil {
  36. return nil, fmt.Errorf("failed to connect to rabbitmq: %v", err)
  37. }
  38. return &RabbitMQFactory{
  39. conn: conn,
  40. config: rabbitConfig,
  41. clients: make(map[string]*amqp.Channel),
  42. }, nil
  43. }
  44. // CreateChannel 创建消息通道
  45. func (f *RabbitMQFactory) CreateChannel(name string) (*amqp.Channel, error) {
  46. f.mu.Lock()
  47. defer f.mu.Unlock()
  48. // 如果已存在,直接返回
  49. if channel, ok := f.clients[name]; ok && channel != nil {
  50. return channel, nil
  51. }
  52. // 创建新通道
  53. channel, err := f.conn.Channel()
  54. if err != nil {
  55. return nil, fmt.Errorf("failed to create channel '%s': %v", name, err)
  56. }
  57. // 设置QoS(可选)
  58. if f.config.PrefetchCount > 0 {
  59. err = channel.Qos(
  60. f.config.PrefetchCount,
  61. f.config.PrefetchSize,
  62. f.config.Global,
  63. )
  64. if err != nil {
  65. channel.Close()
  66. return nil, fmt.Errorf("failed to set qos for channel '%s': %v", name, err)
  67. }
  68. }
  69. f.clients[name] = channel
  70. return channel, nil
  71. }
  72. // GetChannel 获取已创建的通道
  73. func (f *RabbitMQFactory) GetChannel(name string) (*amqp.Channel, error) {
  74. f.mu.RLock()
  75. defer f.mu.RUnlock()
  76. channel, ok := f.clients[name]
  77. if !ok || channel == nil {
  78. return nil, fmt.Errorf("channel '%s' not found", name)
  79. }
  80. return channel, nil
  81. }
  82. // CloseChannel 关闭指定通道
  83. func (f *RabbitMQFactory) CloseChannel(name string) error {
  84. f.mu.Lock()
  85. defer f.mu.Unlock()
  86. channel, ok := f.clients[name]
  87. if ok && channel != nil {
  88. if err := channel.Close(); err != nil {
  89. return fmt.Errorf("failed to close channel '%s': %v", name, err)
  90. }
  91. delete(f.clients, name)
  92. }
  93. return nil
  94. }
  95. // AddExchange 添加交换机
  96. func (f *RabbitMQFactory) AddExchange(channelName, exchange, exchangeType string, durable bool) error {
  97. channel, err := f.GetChannel(channelName)
  98. if err != nil {
  99. return err
  100. }
  101. return channel.ExchangeDeclare(
  102. exchange,
  103. exchangeType, // "direct", "fanout", "topic", "headers"
  104. durable, // durable
  105. false, // auto-deleted
  106. false, // internal
  107. false, // no-wait
  108. nil, // arguments
  109. )
  110. }
  111. // AddQueue 添加队列
  112. func (f *RabbitMQFactory) AddQueue(channelName, queue string, durable, exclusive, autoDelete bool) error {
  113. channel, err := f.GetChannel(channelName)
  114. if err != nil {
  115. return err
  116. }
  117. _, err = channel.QueueDeclare(
  118. queue,
  119. durable, // durable
  120. autoDelete, // delete when unused
  121. exclusive, // exclusive
  122. false, // no-wait
  123. nil, // arguments
  124. )
  125. return err
  126. }
  127. // BindQueue 绑定队列到交换机
  128. func (f *RabbitMQFactory) BindQueue(channelName, queue, exchange, routingKey string) error {
  129. channel, err := f.GetChannel(channelName)
  130. if err != nil {
  131. return err
  132. }
  133. return channel.QueueBind(
  134. queue,
  135. routingKey,
  136. exchange,
  137. false, // no-wait
  138. nil, // arguments
  139. )
  140. }
  141. // Close 关闭所有连接
  142. func (f *RabbitMQFactory) Close() error {
  143. f.mu.Lock()
  144. defer f.mu.Unlock()
  145. // 关闭所有通道
  146. var errs []error
  147. for name, channel := range f.clients {
  148. if channel != nil {
  149. if err := channel.Close(); err != nil {
  150. errs = append(errs, fmt.Errorf("close channel '%s' error: %v", name, err))
  151. }
  152. }
  153. }
  154. f.clients = make(map[string]*amqp.Channel)
  155. // 关闭连接
  156. if f.conn != nil {
  157. if err := f.conn.Close(); err != nil {
  158. errs = append(errs, fmt.Errorf("close connection error: %v", err))
  159. }
  160. }
  161. if len(errs) > 0 {
  162. return fmt.Errorf("errors closing rabbitmq: %v", errs)
  163. }
  164. return nil
  165. }