在rabbitmq的go api中,一个连接能否支持多个通道? 主程序包 进口( “fmt” “github.com/streadway/amqp” “时间” ) //每个连接都应该声明它们所期望的拓扑 func设置(url,队列字符串)(*amqp.Connection,*amqp.Channel,错误){ //设置连接 连接,错误:=amqp.Dial(url) 如果错误!=零{ 返回零,零,错误 } //在连接中构建通道 通道,错误:=连接通道() 如果错误!=零{ 返回零,零,错误 } //队列声明 if 2;,err:=ch.QueueDeclare(queue,false,true,false,false,nil);err!=nil{ 返回零,零,错误 } 返回控制,通道,无 } func main(){ //amqp网址 url:=”amqp://guest:guest@127.0.0.1:5672"; 对于i:=1;i

在rabbitmq的go api中,一个连接能否支持多个通道? 主程序包 进口( “fmt” “github.com/streadway/amqp” “时间” ) //每个连接都应该声明它们所期望的拓扑 func设置(url,队列字符串)(*amqp.Connection,*amqp.Channel,错误){ //设置连接 连接,错误:=amqp.Dial(url) 如果错误!=零{ 返回零,零,错误 } //在连接中构建通道 通道,错误:=连接通道() 如果错误!=零{ 返回零,零,错误 } //队列声明 if 2;,err:=ch.QueueDeclare(queue,false,true,false,false,nil);err!=nil{ 返回零,零,错误 } 返回控制,通道,无 } func main(){ //amqp网址 url:=”amqp://guest:guest@127.0.0.1:5672"; 对于i:=1;i,go,rabbitmq,amqp,Go,Rabbitmq,Amqp,查看,它似乎可以调用conn.Channel()任意次数,并且它会在同一连接上创建一个新的通信流 好的,我试过了,这里有一个工作示例…一个goroutine,一个连接,两个通道 我设置接收器,然后发送消息,然后从接收器通道读取 如果希望在一个goroutine中绑定多个队列,可以调用rec.Consume两次,然后跨队列进行选择 package main import ( "fmt" "github.com/streadway/amqp" "time" ) // Every connecti

查看,它似乎可以调用conn.Channel()任意次数,并且它会在同一连接上创建一个新的通信流

好的,我试过了,这里有一个工作示例…一个goroutine,一个连接,两个通道 我设置接收器,然后发送消息,然后从接收器通道读取

如果希望在一个goroutine中绑定多个队列,可以调用rec.Consume两次,然后跨队列进行选择

package main

import (
"fmt"
"github.com/streadway/amqp"
"time"
)

// Every connection should declare the topology they expect
func setup(url, queue string) (*amqp.Connection, *amqp.Channel, error) {
    //setup connection
    conn, err := amqp.Dial(url)
    if err != nil {
        return nil, nil, err
    }
    //build channel in the connection
    ch, err := conn.Channel()
        if err != nil {
        return nil, nil, err
    }
    //queue declare
    if _, err := ch.QueueDeclare(queue, false, true, false, false, nil); err != nil {
        return nil, nil, err
    }

    return conn, ch, nil
}

func main() {
    //amqp url
    url := "amqp://guest:guest@127.0.0.1:5672";
    for i := 1; i <= 2; i++ {
        fmt.Println("connect ", i)
        //two goroutine   
        go func() {
            //queue name
            queue := fmt.Sprintf("example.reconnect.%d", i)
            //setup channel in the tcp connection
            _, pub, err := setup(url, queue)
            if err != nil {
                fmt.Println("err publisher setup:", err)
                return
            }
            // Purge the queue from the publisher side to establish initial state
            if _, err := pub.QueuePurge(queue, false); err != nil {
                fmt.Println("err purge:", err)
                return
            }
            //publish msg
            if err := pub.Publish("", queue, false, false, amqp.Publishing{
                Body: []byte(fmt.Sprintf("%d", i)),
            }); err != nil {
                fmt.Println("err publish:", err)
                return
            }
            //keep running
            for{
                time.Sleep(time.Second * 20)
            }
        }()
    }
    //keep running
    for {
        time.Sleep(time.Second * 20)
    }
}

同一个goroutine中有一个连接。两个goroutine中有两个连接。我不知道为什么?@DavidBIt看起来连接和通道是线程安全的,你确定不能使用多个goroutine中的连接吗?(再说一次,我自己还没有尝试过)我想表达的是有多少goroutine调用了amqp.Dial()决定tcp连接的数量,我想知道的主要问题是为什么这样设计?您的示例只是主线程调用amqp.Dial(),因此有1个tcp连接。我的示例中有2个线程调用amqp.Dial(),所以有两个tcp连接。很抱歉,我没有清楚地表达我的问题?但您的示例显示通道可以共享一个连接。@DavidB
package main

import (
    "fmt"
    "github.com/streadway/amqp"
    "os"
)

func main() {
    conn, err := amqp.Dial("amqp://localhost")
    e(err)
    defer conn.Close()
    fmt.Println("Connected")
    rec, err := conn.Channel()
    e(err)

    fmt.Println("Setup receiver")
    rq, err := rec.QueueDeclare("go-test", false, false, false, false, nil)
    e(err)
    msgs, err := rec.Consume(rq.Name, "", true, false, false, false, nil)
    e(err)

    fmt.Println("Setup sender")
    send, err := conn.Channel()
    e(err)
    sq, err := send.QueueDeclare("go-test", false, false, false, false, nil)
    e(err)

    fmt.Println("Send message")
    err = send.Publish("", sq.Name, false, false, amqp.Publishing{
        ContentType: "text/plain",
        Body:        []byte("This is a test"),
    })
    e(err)

    msg := <-msgs
    fmt.Println("Received from:", rq, "msg:", string(msg.Body))
}

func e(err error) {
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}
$ go run rmq.go 
Connected
Setup receiver
Setup sender
Send message
Received from: {go-test 0 0} msg: This is a test