Açıklama Yok
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.5KB

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