https://www.rabbitmq.com/tutorials/tutorial-one-go.html

Rabbitmq的任务分发机制

producer_task.go

package main

import (
"fmt"
"github.com/streadway/amqp"
"log"
"math/rand"
"os"
"strings"
"time"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-task"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main() {
bodyMsg := bodyFrom(os.Args)
//调用发布消息函数
publish(uri, exchangeName, queueName, bodyMsg)
log.Printf("published %dB OK", len(bodyMsg))
} func bodyFrom(args []string) string {
var s string
if (len(args) < ) || os.Args[] == "" {
s = "hello idoall.org"
} else {
s = strings.Join(args[:], " ")
}
return s
} //发布者的方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
//@body, 主体内容
func publish(amqpURI string, exchange string, queue string, body string) {
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("declared queue, publishing %dB body (%q)", len(body), body) // Producer只能发送到exchange,它是不能直接发送到queue的。
// 现在我们使用默认的exchange(名字是空字符)。这个默认的exchange允许我们发送给指定的queue。
// routing_key就是指定的queue名字。
tick := time.NewTicker(time.Millisecond * time.Duration(rand.Intn()))
for {
<-tick.C
err = channel.Publish(
exchange, // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
Headers: amqp.Table{},
ContentType: "text/plain",
ContentEncoding: "",
Body: []byte(body),
})
}
failOnError(err, "Failed to publish a message")
}
consumer_task.go

package main

import (
"bytes"
"fmt"
"github.com/streadway/amqp"
"log"
"time"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange nam
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-task"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main() {
//调用消息接收者
consumer(uri, exchangeName, queueName)
} //接收者方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
func consumer(amqpURI string, exchange string, queue string) {
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("Queue bound to Exchange, starting Consume")
//订阅消息
msgs, err := channel.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") //创建一个channel
forever := make(chan bool) //调用gorountine
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
//*
dot_count := bytes.Count(d.Body, []byte("."))
t := time.Duration(dot_count)
time.Sleep(t * time.Second)
//*/
log.Printf("Done")
}
}() log.Printf(" [*] Waiting for messages. To exit press CTRL+C") //没有写入数据,一直等待读,阻塞当前线程,目的是让线程不退出
<-forever
}

开了三个任务窗口接收,发现是并行接收的

Message acknowledgment 消息确认

producer_acknowledgments.go

package main

import (
"fmt"
"log"
"os"
"strings"
"github.com/streadway/amqp"
) /**
* use
* go run producer_acknowledgments.go First message. && go run producer_acknowledgments.go Second message.. && go run producer_acknowledgments.go Third message... && go run producer_acknowledgments.go Fourth message.... && go run producer_acknowledgments.go Fifth message.....
*/
const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-acknowledgments"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
bodyMsg := bodyFrom(os.Args)
//调用发布消息函数
publish(uri, exchangeName, queueName, bodyMsg)
log.Printf("published %dB OK", len(bodyMsg))
} func bodyFrom(args []string) string {
var s string
if (len(args) < ) || os.Args[] == "" {
s = "hello idoall.org"
} else {
s = strings.Join(args[:], " ")
}
return s
} //发布者的方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
//@body, 主体内容
func publish(amqpURI string, exchange string, queue string, body string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("declared queue, publishing %dB body (%q)", len(body), body) // Producer只能发送到exchange,它是不能直接发送到queue的。
// 现在我们使用默认的exchange(名字是空字符)。这个默认的exchange允许我们发送给指定的queue。
// routing_key就是指定的queue名字。
err = channel.Publish(
exchange, // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing {
Headers: amqp.Table{},
ContentType: "text/plain",
ContentEncoding: "",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
}
consumer_acknowledgments.go

package main

import (
"fmt"
"log"
"bytes"
"time"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange nam
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-acknowledgments"
)
/**
*
*/
//如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
//调用消息接收者
consumer(uri, exchangeName, queueName)
} //接收者方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
func consumer(amqpURI string, exchange string, queue string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
false, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("Queue bound to Exchange, starting Consume")
//订阅消息
msgs, err := channel.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") //创建一个channel
forever := make(chan bool) //调用gorountine
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
dot_count := bytes.Count(d.Body, []byte("."))
t := time.Duration(dot_count)
time.Sleep(t * time.Second)
log.Printf("Done")
d.Ack(false)
}
}() log.Printf(" [*] Waiting for messages. To exit press CTRL+C") //没有写入数据,一直等待读,阻塞当前线程,目的是让线程不退出
<-forever
}

Message durability消息持久化

producer_durability.go
package main import (
"fmt"
"log"
"os"
"strings"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-durability"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
bodyMsg := bodyFrom(os.Args)
//调用发布消息函数
publish(uri, exchangeName, queueName, bodyMsg)
log.Printf("published %dB OK", len(bodyMsg))
} func bodyFrom(args []string) string {
var s string
if (len(args) < ) || os.Args[] == "" {
s = "hello idoall.org"
} else {
s = strings.Join(args[:], " ")
}
return s
} //发布者的方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
//@body, 主体内容
func publish(amqpURI string, exchange string, queue string, body string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("declared queue, publishing %dB body (%q)", len(body), body) // Producer只能发送到exchange,它是不能直接发送到queue的。
// 现在我们使用默认的exchange(名字是空字符)。这个默认的exchange允许我们发送给指定的queue。
// routing_key就是指定的queue名字。
err = channel.Publish(
exchange, // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing {
Headers: amqp.Table{},
DeliveryMode: amqp.Persistent,
ContentType: "text/plain",
ContentEncoding: "",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
}
consumer_durability.go
package main import (
"fmt"
"log"
"bytes"
"time"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange nam
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-durability"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
//调用消息接收者
consumer(uri, exchangeName, queueName)
} //接收者方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
func consumer(amqpURI string, exchange string, queue string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("Queue bound to Exchange, starting Consume")
//订阅消息
msgs, err := channel.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") //创建一个channel
forever := make(chan bool) //调用gorountine
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
dot_count := bytes.Count(d.Body, []byte("."))
t := time.Duration(dot_count)
time.Sleep(t * time.Second)
log.Printf("Done")
d.Ack(false)
}
}() log.Printf(" [*] Waiting for messages. To exit press CTRL+C") //没有写入数据,一直等待读,阻塞当前线程,目的是让线程不退出
<-forever
}

Fair dispatch 公平分发

producer_fair_dispatch.go
package main

import (
"fmt"
"log"
"os"
"strings"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-fair_dispatch"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
bodyMsg := bodyFrom(os.Args)
//调用发布消息函数
publish(uri, exchangeName, queueName, bodyMsg)
log.Printf("published %dB OK", len(bodyMsg))
} func bodyFrom(args []string) string {
var s string
if (len(args) < 2) || os.Args[1] == "" {
s = "hello idoall.org"
} else {
s = strings.Join(args[1:], " ")
}
return s
} //发布者的方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
//@body, 主体内容
func publish(amqpURI string, exchange string, queue string, body string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") log.Printf("declared queue, publishing %dB body (%q)", len(body), body) // Producer只能发送到exchange,它是不能直接发送到queue的。
// 现在我们使用默认的exchange(名字是空字符)。这个默认的exchange允许我们发送给指定的queue。
// routing_key就是指定的queue名字。
err = channel.Publish(
exchange, // exchange
q.Name, // routing key
false, // mandatory
false, // immediate
amqp.Publishing {
Headers: amqp.Table{},
DeliveryMode: amqp.Persistent,
ContentType: "text/plain",
ContentEncoding: "",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
}
 
consumer_fair_dispatch.go
package main import (
"fmt"
"log"
"bytes"
"time"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange nam
exchangeName = ""
//Durable AMQP queue name
queueName = "test-idoall-queues-fair_dispatch"
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
//调用消息接收者
consumer(uri, exchangeName, queueName)
} //接收者方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@queue, queue的名称
func consumer(amqpURI string, exchange string, queue string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() log.Printf("got queue, declaring %q", queue) //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") //每次只取一条消息
err = channel.Qos(
, // prefetch count
, // prefetch size
false, // global
)
failOnError(err, "Failed to set QoS") log.Printf("Queue bound to Exchange, starting Consume")
//订阅消息
msgs, err := channel.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") //创建一个channel
forever := make(chan bool) //调用gorountine
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
dot_count := bytes.Count(d.Body, []byte("."))
t := time.Duration(dot_count)
time.Sleep(t * time.Second)
log.Printf("Done")
d.Ack(false)
}
}() log.Printf(" [*] Waiting for messages. To exit press CTRL+C") //没有写入数据,一直等待读,阻塞当前线程,目的是让线程不退出
<-forever
}

Exchanges & Bindings

producer_exchange_logs.go
package main import (
"fmt"
"log"
"os"
"strings"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = "test-idoall-exchange-logs"
//Exchange type - direct|fanout|topic|x-custom
exchangeType = "fanout"
//AMQP routing key
routingKey = ""
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
bodyMsg := bodyFrom(os.Args)
//调用发布消息函数
publish(uri, exchangeName, exchangeType, routingKey, bodyMsg)
log.Printf("published %dB OK", len(bodyMsg))
} func bodyFrom(args []string) string {
var s string
if (len(args) < ) || os.Args[] == "" {
s = "hello idoall.org"
} else {
s = strings.Join(args[:], " ")
}
return s
} //发布者的方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@exchangeType, exchangeType的类型direct|fanout|topic
//@routingKey, routingKey的名称
//@body, 主体内容
func publish(amqpURI string, exchange string, exchangeType string, routingKey string, body string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() //创建一个queue
log.Printf("got Channel, declaring %q Exchange (%q)", exchangeType, exchange)
err = channel.ExchangeDeclare(
exchange, // name
exchangeType, // type
true, // durable
false, // auto-deleted
false, // internal
false, // noWait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") // 发布消息
log.Printf("declared queue, publishing %dB body (%q)", len(body), body)
err = channel.Publish(
exchange, // exchange
routingKey, // routing key
false, // mandatory
false, // immediate
amqp.Publishing {
Headers: amqp.Table{},
ContentType: "text/plain",
ContentEncoding: "",
Body: []byte(body),
})
failOnError(err, "Failed to publish a message")
}

consumer_exchange_logs.go

package main

import (
"fmt"
"log"
"github.com/streadway/amqp"
) const (
//AMQP URI
uri = "amqp://guest:guest@localhost:5672/"
//Durable AMQP exchange name
exchangeName = "test-idoall-exchange-logs"
//Exchange type - direct|fanout|topic|x-custom
exchangeType = "fanout"
//AMQP binding key
bindingKey = ""
//Durable AMQP queue name
queueName = ""
) //如果存在错误,则输出
func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
panic(fmt.Sprintf("%s: %s", msg, err))
}
} func main(){
//调用消息接收者
consumer(uri, exchangeName, exchangeType, queueName, bindingKey)
} //接收者方法
//
//@amqpURI, amqp的地址
//@exchange, exchange的名称
//@exchangeType, exchangeType的类型direct|fanout|topic
//@queue, queue的名称
//@key , 绑定的key名称
func consumer(amqpURI string, exchange string, exchangeType string, queue string, key string){
//建立连接
log.Printf("dialing %q", amqpURI)
connection, err := amqp.Dial(amqpURI)
failOnError(err, "Failed to connect to RabbitMQ")
defer connection.Close() //创建一个Channel
log.Printf("got Connection, getting Channel")
channel, err := connection.Channel()
failOnError(err, "Failed to open a channel")
defer channel.Close() //创建一个exchange
log.Printf("got Channel, declaring Exchange (%q)", exchange)
err = channel.ExchangeDeclare(
exchange, // name of the exchange
exchangeType, // type
true, // durable
false, // delete when complete
false, // internal
false, // noWait
nil, // arguments
);
failOnError(err, "Exchange Declare:") //创建一个queue
q, err := channel.QueueDeclare(
queueName, // name
false, // durable
false, // delete when unused
true, // exclusive 当Consumer关闭连接时,这个queue要被deleted
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") //绑定到exchange
err = channel.QueueBind(
q.Name, // name of the queue
key, // bindingKey
exchange, // sourceExchange
false, // noWait
nil, // arguments
);
failOnError(err, "Failed to bind a queue") log.Printf("Queue bound to Exchange, starting Consume")
//订阅消息
msgs, err := channel.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") //创建一个channel
forever := make(chan bool) //调用gorountine
go func() {
for d := range msgs {
log.Printf(" [x] %s", d.Body)
}
}() log.Printf(" [*] Waiting for messages. To exit press CTRL+C") //没有写入数据,一直等待读,阻塞当前线程,目的是让线程不退出
<-forever
}

远程调用RPC

 rpc_server.go
package main import (
"fmt"
"log"
"strconv" "github.com/streadway/amqp"
) func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
} func fib(n int) int {
if n == {
return
} else if n == {
return
} else {
return fib(n-) + fib(n-)
}
} func main() {
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close() ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close() q, err := ch.QueueDeclare(
"rpc_queue", // name
false, // durable
false, // delete when usused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") err = ch.Qos(
, // prefetch count
, // prefetch size
false, // global
)
failOnError(err, "Failed to set QoS") msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") forever := make(chan bool) go func() {
for d := range msgs {
n, err := strconv.Atoi(string(d.Body))
failOnError(err, "Failed to convert body to integer") log.Printf(" [.] fib(%d)", n)
response := fib(n) err = ch.Publish(
"", // exchange
d.ReplyTo, // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
CorrelationId: d.CorrelationId,
Body: []byte(strconv.Itoa(response)),
})
failOnError(err, "Failed to publish a message") d.Ack(false)
}
}() log.Printf(" [*] Awaiting RPC requests")
<-forever
}
 rpc_client.go
package main import (
"fmt"
"log"
"math/rand"
"os"
"strconv"
"strings"
"time" "github.com/streadway/amqp"
) func failOnError(err error, msg string) {
if err != nil {
log.Fatalf("%s: %s", msg, err)
}
} func randomString(l int) string {
bytes := make([]byte, l)
for i := ; i < l; i++ {
bytes[i] = byte(randInt(, ))
}
return string(bytes)
} func randInt(min int, max int) int {
return min + rand.Intn(max-min)
} func fibonacciRPC(n int) (res int, err error) {
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
failOnError(err, "Failed to connect to RabbitMQ")
defer conn.Close() ch, err := conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close() q, err := ch.QueueDeclare(
"", // name
false, // durable
false, // delete when usused
true, // exclusive
false, // noWait
nil, // arguments
)
failOnError(err, "Failed to declare a queue") msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
true, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer") corrId := randomString() err = ch.Publish(
"", // exchange
"rpc_queue", // routing key
false, // mandatory
false, // immediate
amqp.Publishing{
ContentType: "text/plain",
CorrelationId: corrId,
ReplyTo: q.Name,
Body: []byte(strconv.Itoa(n)),
})
failOnError(err, "Failed to publish a message") for d := range msgs {
if corrId == d.CorrelationId {
res, err = strconv.Atoi(string(d.Body))
failOnError(err, "Failed to convert body to integer")
break
}
} return
} func main() {
rand.Seed(time.Now().UTC().UnixNano()) n := bodyFrom(os.Args) log.Printf(" [x] Requesting fib(%d)", n)
res, err := fibonacciRPC(n)
failOnError(err, "Failed to handle RPC request") log.Printf(" [.] Got %d", res)
} func bodyFrom(args []string) int {
var s string
if (len(args) < ) || os.Args[] == "" {
s = ""
} else {
s = strings.Join(args[:], " ")
}
n, err := strconv.Atoi(s)
failOnError(err, "Failed to convert arg to integer")
return n
}

golang rabbitmq 的学习的更多相关文章

  1. C#RabbitMQ基础学习笔记

    RabbitMQ基础学习笔记(C#代码示例) 一.定义: MQ是MessageQueue,消息队列的简称(是流行的开源消息队列系统,利用erlang语言开发).MQ是一种应用程序对应用程序的通信方法. ...

  2. Golang源码学习:调度逻辑(二)main goroutine的创建

    接上一篇继续分析一下runtime.newproc方法. 函数签名 newproc函数的签名为 newproc(siz int32, fn *funcval) siz是传入的参数大小(不是个数):fn ...

  3. golang rabbitmq实践(啰嗦)

    目录 rabbitmq ubuntu下的配置 go 实现rabbitmq的消息收发 1:背景简介 我是一个.net一线开发,今年6月份离开帝都来到魔都,后入职于莫江互联网在线教育公司.现刚刚转正,在这 ...

  4. Golang之sdl2学习之路(零) -- 环境工具准备

    学习Golang有一段时间了,从毫无头绪到四处乱撞,再到如今静下心来安心学习sdl2也有小半年了. 今晚重构之前的学习代码,发现如果不写该文,可能会在以后回顾这段时间写的代码上花费时间,故以此文做一点 ...

  5. Rabbitmq相关学习网址

    1.安装文档: http://www.cnblogs.com/shuzhenyu/p/9823324.html 2.RabbitMq的整理 exchange.route.queue关系 https:/ ...

  6. golang 容器的学习与实践

    golang 提供了几个简单的容器供我们使用,本文在介绍几种Golang 容器的基础上,实现一个基于Golang 容器的LRU算法. 容器介绍 Golang 容器位于 container 包下,提供了 ...

  7. RabbitMQ巩固学习一

    说起RabbitMQ大家第一时间应该想到的就是异步队列,关于异步队列的话题简直太多了,各位同学在园子里一搜便知.我第一次听异步队列这个名词感觉非常高大上

  8. RabbitMQ小白菜学习之在window下的安装配置

    RabbitMQ安装 首先需要下载RabbitMQ的平台环境Erlang OTP平台和RabbitMQ Server(windows版): OTP 19.1 Windows 64-bit Binary ...

  9. RabbitMQ 应用学习随笔

    1.安装 Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装RabbitMQ之前要先安装Erlang. erlang:http://www.erlang.org/download. ...

随机推荐

  1. echarts 如何设置热力图点的大小

    series: [{ name: 'AQI', type: 'heatmap', coordinateSystem: 'geo', blurSize: 10, pointSize: 10, // 设置 ...

  2. Python入门篇-内建函数

    Python入门篇-内建函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.常见的内建函数案例  1>.标识id 返回对象的唯一标识,CPython返回内存地址. #!/ ...

  3. 洛谷 P1816 忠诚题解

    题目描述 老管家是一个聪明能干的人.他为财主工作了整整10年,财主为了让自已账目更加清楚.要求管家每天记k次账,由于管家聪明能干,因而管家总是让财主十分满意.但是由于一些人的挑拨,财主还是对管家产生了 ...

  4. Codeforces C. Maximum Value(枚举二分)

    题目描述: Maximum Value time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. 将mysql从MyISAM更改为INNODB

    今天更新django中的表字段,由于mysql从5.1升级到5.7.以前的外键关联必须从MYISAM改新为INNODB才可以继续. 过程有点刺激,但还好,只要想清楚了过程,提前作好备份,就没啥大问题. ...

  6. synchronize——对象锁和类锁

    最近在研究Java 多线程的只是,经常能看到synchronize关键字,以前只是一眼带过,没有细究,今天趁这个机会,整理下 synchronize作为多线程关键字,是一种同步锁,它可以修饰以下几种对 ...

  7. 【Selenium-WebDriver实战篇】基于java的selenium之验证码识别内容

    ==================================================================================================== ...

  8. Spring源码窥探之:@Profile

    Spring为我们提供的多环境启动 1. 配置类,注入三个不同环境的数据源,并加上注解 /** * description: 以下准备了三套不同环境的数据源 * * @author 70KG * @d ...

  9. map_multimap

    #include<iostream> #include<string> #include<map> using namespace std; struct Self ...

  10. 性能:Receiver层面

    创建多个接收器 多个端口启动多个receiver在其他Executor,接收多个端口数据,在吞吐量上提高其性能.代码上: import org.apache.spark.storage.Storage ...