增加了队列消费端处理
This commit is contained in:
@@ -0,0 +1,284 @@
|
||||
package rabbitMq
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
amqp "github.com/rabbitmq/amqp091-go"
|
||||
"hepa-calc-api/config"
|
||||
"hepa-calc-api/global"
|
||||
"hepa-calc-api/utils"
|
||||
"log"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Client 客户端
|
||||
type Client struct {
|
||||
m *sync.Mutex
|
||||
queueName string
|
||||
logger *log.Logger
|
||||
connection *amqp.Connection
|
||||
channel *amqp.Channel
|
||||
done chan bool
|
||||
notifyConnClose chan *amqp.Error
|
||||
notifyChanClose chan *amqp.Error
|
||||
notifyConfirm chan amqp.Confirmation
|
||||
isReady bool
|
||||
}
|
||||
|
||||
// ConsumeS 消费端结构体
|
||||
type ConsumeS struct {
|
||||
QueueName string // 队列名称
|
||||
ExchangeName string // 交换机名称
|
||||
RoutingKey string // 路由键
|
||||
Handler func(amqp.Delivery) // 回调处理方法
|
||||
}
|
||||
|
||||
// PublishS 生产端结构体
|
||||
type PublishS struct {
|
||||
QueueName string // 队列名称
|
||||
ExchangeName string // 交换机名称
|
||||
RoutingKey string // 路由键
|
||||
Message interface{} // 消息内容
|
||||
Delay time.Duration // 延迟时间
|
||||
}
|
||||
|
||||
// NewRabbitMQClient 初始化客户端
|
||||
func NewRabbitMQClient() error {
|
||||
var err error
|
||||
m := config.C.Amqp
|
||||
|
||||
user := url.QueryEscape(m.User)
|
||||
password := url.QueryEscape(m.Password)
|
||||
|
||||
dsn := fmt.Sprintf("amqp://%s:%s@%s:%d/%s", user, password, m.Host, m.Port, m.Vhost)
|
||||
|
||||
// 连接到 RabbitMQ 服务器
|
||||
global.RabbitConn, err = amqp.Dial(dsn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 创建一个通道
|
||||
global.RabbitChannel, err = global.RabbitConn.Channel()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Publish 生产
|
||||
func Publish(queueName, exchangeName, routingKey string, message interface{}) error {
|
||||
err := global.RabbitChannel.ExchangeDeclare(
|
||||
exchangeName, // name
|
||||
"x-delayed-message", // type
|
||||
true, // durable
|
||||
false, // auto-deleted
|
||||
false, // internal
|
||||
false, // 阻塞处理
|
||||
amqp.Table{"x-delayed-type": "direct"}, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = global.RabbitChannel.QueueDeclare(
|
||||
queueName, // 队列名字
|
||||
true, // 消息是否持久化
|
||||
false, // 不使用的时候删除队列
|
||||
false, // 是否排他
|
||||
false, // 是否阻塞
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将队列绑定到延迟交换器
|
||||
err = global.RabbitChannel.QueueBind(
|
||||
queueName, // 队列名称
|
||||
routingKey, // 路由键
|
||||
exchangeName, // 交换器名称
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body, err := json.Marshal(message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = global.RabbitChannel.Publish(
|
||||
exchangeName, // exchange(交换机名字)
|
||||
routingKey, //
|
||||
false, // 是否为无法路由的消息进行返回处理
|
||||
false, // 是否对路由到无消费者队列的消息进行返回处理 RabbitMQ 3.0 废弃
|
||||
amqp.Publishing{
|
||||
ContentType: "text/plain",
|
||||
Body: body, // 消息内容
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PublishWithDelay 生产延迟消息
|
||||
func (p PublishS) PublishWithDelay() error {
|
||||
err := global.RabbitChannel.ExchangeDeclare(
|
||||
p.ExchangeName, // name
|
||||
"x-delayed-message", // type
|
||||
true, // durable
|
||||
false, // auto-deleted
|
||||
false, // internal
|
||||
false, // 阻塞处理
|
||||
amqp.Table{"x-delayed-type": "direct"}, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = global.RabbitChannel.QueueDeclare(
|
||||
p.QueueName, // 队列名字
|
||||
true, // 消息是否持久化
|
||||
false, // 不使用的时候删除队列
|
||||
false, // 是否排他
|
||||
false, // 是否阻塞
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将队列绑定到延迟交换器
|
||||
err = global.RabbitChannel.QueueBind(
|
||||
p.QueueName, // 队列名称
|
||||
p.RoutingKey, // 路由键
|
||||
p.ExchangeName, // 交换器名称
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
body, err := json.Marshal(p.Message)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = global.RabbitChannel.Publish(
|
||||
p.ExchangeName, // exchange
|
||||
p.RoutingKey, // routing key
|
||||
false, // 是否为无法路由的消息进行返回处理
|
||||
false, // 是否对路由到无消费者队列的消息进行返回处理 RabbitMQ 3.0 废弃
|
||||
amqp.Publishing{
|
||||
ContentType: "text/plain",
|
||||
Body: body,
|
||||
Headers: amqp.Table{"x-delay": int32(p.Delay / time.Millisecond)},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Consume 消费
|
||||
func (s ConsumeS) Consume() error {
|
||||
err := global.RabbitChannel.ExchangeDeclare(
|
||||
s.ExchangeName, // name
|
||||
"x-delayed-message", // type
|
||||
true, // durable
|
||||
false, // auto-deleted
|
||||
false, // internal
|
||||
false, // 阻塞处理
|
||||
amqp.Table{"x-delayed-type": "direct"}, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
queue, err := global.RabbitChannel.QueueDeclare(
|
||||
s.QueueName, // 队列名称
|
||||
true, // 是否持久化
|
||||
false, // 是否自动删除队列
|
||||
false, // 排他
|
||||
false, // 阻塞处理
|
||||
nil, // arguments
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 将队列绑定到延迟交换器
|
||||
err = global.RabbitChannel.QueueBind(
|
||||
s.QueueName, // 队列名称
|
||||
s.RoutingKey, // 路由键
|
||||
s.ExchangeName, // 交换器名称
|
||||
false,
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
msgs, err := global.RabbitChannel.Consume(
|
||||
queue.Name, // queue
|
||||
"", // 消费者标签
|
||||
false, // 是否自动确认
|
||||
false, // 是否独占
|
||||
false, // 是否无等待
|
||||
false, //其他参数
|
||||
nil, // 其他参数
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 消费消息
|
||||
go func() {
|
||||
for msg := range msgs {
|
||||
s.Handler(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close 关闭rabbitMq
|
||||
func Close() {
|
||||
if global.RabbitChannel != nil {
|
||||
err := global.RabbitChannel.Close()
|
||||
if err != nil {
|
||||
utils.LogJsonErr("关闭rabbitMq:", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if global.RabbitConn != nil {
|
||||
err := global.RabbitConn.Close()
|
||||
if err != nil {
|
||||
utils.LogJsonErr("关闭rabbitMq:", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HandleReconnect 处理重新连接
|
||||
func HandleReconnect() {
|
||||
for {
|
||||
notifyClose := make(chan *amqp.Error)
|
||||
global.RabbitConn.NotifyClose(notifyClose)
|
||||
err := <-notifyClose
|
||||
if err != nil {
|
||||
time.Sleep(30 * time.Second)
|
||||
_ = NewRabbitMQClient()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,10 @@ import (
|
||||
|
||||
// 创建客户端
|
||||
func createClient() (*core.Client, error) {
|
||||
mchId := config.C.Wechat.Pay1659662936.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1659662936.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1659662936.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := "extend/weChat/certs/" + config.C.Wechat.Pay1659662936.MchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
mchId := config.C.Wechat.Pay1281030301.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1281030301.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1281030301.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := config.C.Wechat.Pay1281030301.PrivateKey // 商户私钥文件地址
|
||||
|
||||
if mchId == "" {
|
||||
return nil, errors.New("商户号错误")
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDR4fiYRUjnLQA+
|
||||
TPMslDvQIIyZm4ajWFcSXg6yozhdi/O+vuRhwgyeGXsE4SpvuxkK4HPZaocrsjqe
|
||||
68Y46DyhudzXIBy50IF2UeN5ilj7ydq5TJbBOi1iOF1lgOUNK6DGiOQ+folVNKyN
|
||||
sjrsA3RHUKHF/JdOfcpSGzvV79FnmjSll/KsdxEc9LCiAa5t7GYA9Hx7AIDG4i8b
|
||||
03d5EJXvE8BGUZQItE6VIpHwyySTHtGQkPyI6lqMKt2Jlx0TFHu0GkTEmhuA2Z5C
|
||||
5gOqYWclQO+X2ORgulL9Q3mNcpfy9uBynI/CJDbSvVTkNfwYB0Ny1knu/+in7C6p
|
||||
IPJYfZpPAgMBAAECggEAWb5tJPcjSC5W10ziAiLUPJdeZ2Q4OupQOPtc/4eJV367
|
||||
V8maMC7gZE3y61A4bBQtjhgRkVrat5V7OW8JkFXFb0XhJ1+EyPNeGDDFureseuWC
|
||||
EA+uuqrcsw306a0mw+3uzlXEevByWquuSNx4E2katE/HDLiIHjjtZRReDomAGfLw
|
||||
vLNZ40RgdNSXmwpVRoHOZnvX+C2Hxh4fKsrxs1HRCjFsSpTxKwsK6/Kdudj4hsaO
|
||||
Z5glqf4qopPlQIIkToxOe5p7ukwo7vqaqogixx3jOjruOMpzxZ24wU5AxneLcOYr
|
||||
ZC1659Uwv96TsKpueakWw0lq3TXkv9Qs+wDNI+NC6QKBgQDx4hWXplLYPYwgGgxG
|
||||
L9Pk+If9aDS9wj78JUaYBXKR5atXmf/62ufahW4IEDfmMugC1bm9MoYC7CmHv1nk
|
||||
nxckB84B20NOSiaxbkOaJuMHDtnNeXCmL8Gvtb8fTni1AM/g6XEleEw1r40LNZAq
|
||||
kdyQ1+OUFhRQGOvAe1SRr1rdGwKBgQDeIcauwMPkc3Seh6Fb66FQ4Lgmt1GvvuiG
|
||||
UJiwgwPFbEaKKczBHBL6hlKoAFweFa2Qw2xJ0H8jwb8RnkkNcAKYUyMc2wi85+Ih
|
||||
d568pvXMdYl4DGeGdd/sXKf4dGDjcb2AHzNfDuklbCsAojtO3pLWOs5U/RSKe8ps
|
||||
hhWa8nPO3QKBgQCIxuKU3X1tP+hz4qbcLYFxscQcXIeuYiABrwZrQnFV5Pxtzex9
|
||||
Krn+zIK61oj1iAXATKD6Ro6XKnoVg/POHtQUEMHCNP2rUKzumj5p9eFdBV3OHgTA
|
||||
RLMOrARGLLZ/C9WBBiBwIsVdekaUdxZtrAuAcEQFYjLcVCtDrbnVo8YKzwKBgEsg
|
||||
V0cBMP+RwM5hBsTE45Er/3wwofLzeUb7+Tgxh1P887qEuphRO2X5ifkB7iXKpSIB
|
||||
xh0M5AMe4tU9mG1wBaCo9YYr2j+xmTxCbbBWM2mMEwtD/rtuIGabS7/u9FnYPQQZ
|
||||
CVHMBDRA6iZTuAVLp5PG3cPGuGzBw0uC6cm22E4NAoGAKrbg3nFPKtzBJZ8Z0iNH
|
||||
G2gNotmHXbd4+gs4e3Iz9xsEabm4wCoEibNojNdMkX8zX267ebgfvesGEobROjW9
|
||||
Intvh39xi3aQ2Q5gvXzKdY0lDzgVvQ7udmLQ4dCUyYnpLr7Yac0asRxLge2esCWV
|
||||
x2uW2YTiUW3zsbHN/N/vJ5I=
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -14,10 +14,10 @@ import (
|
||||
|
||||
// ParseNotify 回调通知的验签与解密
|
||||
func ParseNotify(c *gin.Context) (notifyReq *notify.Request, t *payments.Transaction, err error) {
|
||||
mchId := config.C.Wechat.Pay1659662936.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1659662936.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1659662936.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := "extend/weChat/certs/" + config.C.Wechat.Pay1659662936.MchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
mchId := config.C.Wechat.Pay1281030301.MchId // 商户号
|
||||
mchCertificateSerialNumber := config.C.Wechat.Pay1281030301.MchCertificateSerialNumber // 商户证书序列号
|
||||
v3ApiSecret := config.C.Wechat.Pay1281030301.V3ApiSecret // 商户APIv3密钥
|
||||
privateKeyPath := "extend/weChat/certs/" + config.C.Wechat.Pay1281030301.MchId + "/apiclient_key.pem" // 商户私钥文件地址
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath(privateKeyPath)
|
||||
|
||||
Reference in New Issue
Block a user