本文我将使用 Go 语言在 RabbitMQ 上发布和接收消息。

Go 的标准库本身并没有 RabbitMQ 的原生绑定,但是有一个第三方库确能够支持 RabbitMQ,它的源码在 https://github.com/streadway/amqp ,其文档在 https://pkg.go.dev/github.com/streadway/amqp

发布消息到 RabbitMQ

建立一个 Go 的项目,并使用 go mod init 进行初始化:

mod init<br />
go: creating new go.mod: module demo<br />
main .go

使用 go get -u github.com/streadway/amqp 命令来安装这个库:

get —u github . com/streadway/amqp<br />
go: downloading github . com/streadway/amqp vl.e.e<br />
go: github . com/streadway/amqp upgrade vl.e.e

获取 Queue

代码如下:

x<br />
ma ln.go<br />
-GO main.go > getQueue<br />
1<br />
2<br />
3<br />
4<br />
5<br />
6<br />
7<br />
8<br />
9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
21<br />
22<br />
23<br />
24<br />
25<br />
26<br />
27<br />
28<br />
29<br />
30<br />
31<br />
32<br />
33<br />
package main<br />
import (<br />
" fmt "<br />
"log"<br />
" github.com/streadway/amqp"<br />
func main() { }<br />
func failOnError(err<br />
error,<br />
if<br />
err<br />
log. Fatalf("%s: %s",<br />
string) {<br />
msg<br />
err, msg)<br />
panic(fmt.Sprintf( "%s: ,<br />
err, msg))<br />
func getQueue() (*amqp.Connection, *amqp.Channel, *amqp.Queue) {<br />
amqp. Dial( " amqp : //guestölocalhost : 5672 " )<br />
conn, err<br />
failOnError(err,<br />
"Failed to connect to RabbitMQ")<br />
conn. Channel()<br />
ch, err<br />
failOnError(err,<br />
"Failed to open a channel")<br />
ch . hello " ,<br />
q, err<br />
false,<br />
false,<br />
false,<br />
false,<br />
nil)<br />
failOnError(err,<br />
"Failed to declare a queue")<br />
conn, ch,<br />
return
  1. 首先导入需要的包,主要是 streadway/amqp

  2. 第 12 行,编写处理错误的函数 failOnError

  3. 第 19 行,编写可以获得 AMQP Connection、Channel、Queue 的帮助函数 getQueue()

我们知道我们需要将消息发布到 Exchange 上面,但是如果使用默认 Exchange 的话,就可以使用一个捷径:我们可以将消息直接发送到 Queue 的名称上(但实际并不是直接发送到 Queue 上面)。

  1. getQueue() 函数不用任何参数,它返回三个对象:

    1. *amqp.Connection 表示应用和 RabbitMQ 之间的网络连接

    2. *amqp.Channel 位于 Connection 之上,它提供了用于双方通信的通道。通过把 Connection 和 Channel 分开,客户应用中就可以在同一个 Connection 上拥有多个 Channel 用来通信,这样就减少了对资源的需求。

    3. *amqp.Queue 也就是队列

  2. 第 20 行,使用 amqp 的 Dial 函数可以返回一个 Connection,Dial 函数的参数是 RabbitMQ 的 URL,URL 里面需要包含用户凭证。

  3. 第 22 行,通过调用 Connection 对象上的 Channel 方法,创建一个 Channel

  4. 第 24 行,通过调用 Channel 对象上的 QueueDeclare 方法,返回一个 Queue。注意:这个 Queue 不一定是被创建的,如果不存在指定名称的 Queue,那么 RabbitMQ 就会创建一个;如果存在指定名称的 Queue,但是和指定的配置不同,那么 RabbitMQ 就会拒绝这个请求,并抛出错误。

  5. QueueDeclare 方法参数:

    1. 第一个参数是 Queue 的名称:我们就写死一个 hello

    2. 第二个参数是 durable bool,表示是否将添加到 Queue 的消息存储在硬盘上。如果这个参数值为 true,那么 RabbitMQ 服务器重启之后消息依然会存在。但是它会导致处理消息的能力明显下降。这里我把它设为 false。

    3. 第三个参数 autoDelete bool,它会告诉 RabbitMQ 如果消息没有消费者应该怎么做:

      1. true:消息就会从 Queue 中删除

      2. false:将消息保留直到某个消费者前来获取该消息。这里我把它设为 false

    4. 第四个参数 exclusive bool,它允许我们把这个 Queue 设置为只能从请求它的那个 Connection 上进行访问。

      1. 如果它为 true,但想创建一个来自其它 Connection 的同名 Queue,那么就会报错

      2. 如果它是 false,那么想创建一个来自其它 Connection 的同名 Queue 的结果就是:两个 Connection 都连接到同一个 Queue,两个 Connection 会共享它。这里我把它设为 false

    5. 第五个参数 noWait bool,

      1. 如果为 true,这个 Queue 就被认为已经在服务器上存在了,将它返回即可,如果它不存在,那么就会报错

      2. 所以这里设置为 false,因为我要创建的 Queue 在服务器上不存在。

    6. 第六个参数 args amqp.Table,这个参数用于某些特定场景,例如声明一些要被这个 Queue 匹配的 Headers,如果这个 Queue 被绑定到 Header Exchange 的话。这里我传的是 nil。

  6. 如果第 24 行的 QueueDeclare 方法调用成功,那么就会得到一个绑定到 Default Exchange 的 Queue。

  7. 注意:Default Exchange 的类型是 Direct,也就是说任何没有路由 Key(和 Queue 的名称相同,在这里就是 hello)的消息传进来,将会被直接通过 exchange 送往输出的 Queue。

  8. 第 31 行,将 3 个对象返回即可,注意 q 我们返回的是指针

发布消息

10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
21<br />
22<br />
23<br />
24<br />
25<br />
26<br />
27<br />
28<br />
29<br />
30<br />
31<br />
32<br />
33<br />
func main() {<br />
for {<br />
server()<br />
func server()<br />
getQueue( )<br />
conn, ch, q<br />
conn. Close()<br />
defer<br />
ch . Close()<br />
defer<br />
amqp. Publishing{<br />
msg<br />
"text/plain" ,<br />
Content Type:<br />
Body :<br />
ch . Publish(<br />
q. Name ,<br />
false,<br />
false,<br />
msg)<br />
[]byte( "Hello RabbitMQ"),
  1. 16 行,编写了一个 server 函数

  2. 17 行,通过 getQueue 来获得 Connection,Channel 和 Queue

  3. 18,19 行,按顺序 defer 关闭 Connection 和 Channel

  4. 21 行,创建一个消息 amqp.Publishing 结构体,很多参数都是可选的,这里我设置两个:

    1. ContentType 会指明消息的类型。RabbitMQ 会把数据变成字节流来传输,所以它其实并不关心消息的类型。但是如果你往同一个 Queue 发送不同类型的消息,那么还是设置一下这个字段比较好,便于区分消息的类型。

    2. Body 可能是该结构体中最重要的字段:它的类型是 Byte Slice,里面包含着要传送的数据。

  5. 第 26 行,将消息发布到消息代理上。这里我们使用 Channel 上的 Publish 方法,其参数有:

    1. 第一个参数 Exchange:“”表示使用 Default Exchange,它没有名称

    2. 第二个参数是路由 Key:本例中,需要把它设置为 Queue 的名称

    3. 第三、四各参数 mandatory bool,immediate bool:用于发生者需要确认消息是否被传递成功,以及什么时候传递成功的。

    4. 第五个参数就是消息本身:也就是 msg

  6. 在 main 函数中调用 server 函数。这里循环调用是为了看看 RabbitMQ 的性能,你可以只调用一次。

运行程序

运行 go run . 命令:

C: go run .

打开管理控制台:

Connections<br />
Overview<br />
v Totals<br />
Queued messages last minute<br />
10.0 k<br />
7.5k<br />
5.0 k<br />
2.5 k<br />
0.0 k<br />
Message rates<br />
300 Is<br />
200 Is<br />
100 Is<br />
last minute<br />
RabbitMQ 3.8.11<br />
Channels<br />
Exchanges: 8<br />
Erlang 22.3<br />
Exchanges<br />
Queues: 10<br />
Queues<br />
Ready<br />
Unacked<br />
Total<br />
Publish<br />
Publisher<br />
confirm<br />
Deliver<br />
(manual<br />
ack)<br />
Admin<br />
. 9,636<br />
• 9,636<br />
• 2101s<br />
0.00/s<br />
• 0.00/s<br />
Deliver<br />
(auto ack)<br />
Consumer<br />
Redelivered<br />
Memory ?<br />
137 Mia<br />
13 Gig high watæ-rrMk<br />
• 0.00/s<br />
• 0.00/s<br />
• 0.00/s<br />
Disk space<br />
62 GiB<br />
48 Mia low<br />
Get<br />
(manual<br />
ack)<br />
Get (auto<br />
ack)<br />
Get<br />
(empty)<br />
• 0.00/s<br />
• 0.00/s<br />
• 0.00/s<br />
disc<br />
Unroutable<br />
(return)<br />
Unroutable<br />
(drop)<br />
Disk read<br />
Disk write<br />
• 0.00/s<br />
0.00/s<br />
. 0.00/s<br />
• 0.00/s<br />
Global counts ?<br />
Connections: O<br />
Nodes<br />
Name<br />
Channels: O<br />
Consumers: O<br />
File descriptors<br />
Socket descriptors<br />
58893 available<br />
Erlang processes<br />
1048576 a<br />
Uptime<br />
10d Oh<br />
I nfo<br />
basic<br />
rss<br />
Reset stats<br />
This node<br />
rabbit@DESKTOP-NMTR5KP<br />
65336<br />
Churn statistics<br />
All nodes

可以看到目前有 8 个 Exchange,10 个 Queue,有 9636 个消息

切换到 Exchange 画面:

Overview<br />
Connections<br />
Channels<br />
Exchanges<br />
D Regex ?<br />
Queues<br />
Admin<br />
Exchanges<br />
All exchanges (8)<br />
Pagination<br />
Page 1<br />
Name<br />
of 1<br />
- Filter:<br />
Type<br />
direct<br />
fanout<br />
direct<br />
fanout<br />
headers<br />
headers<br />
topic<br />
topic<br />
Features<br />
Message rate in Message ra ut<br />
(AMQP default)<br />
SensorDiscoverv<br />
amq.direct<br />
amq.fanout<br />
amq.headers<br />
amq.match<br />
amq.rabbitmq.trace<br />
amq.topic<br />
215/s<br />
0.00/s<br />
0.00/s<br />
215/s<br />
0.00/s<br />
Add a new exchange

可以看到 Default Exchange 的消息速率。

切换到 Queues 画面:

Overview<br />
Queues<br />
Connections<br />
Channels<br />
Exchanges<br />
D Regex ?<br />
Queues<br />
Admin<br />
All queues (10)<br />
Pagination<br />
Page 1<br />
Overview<br />
Name<br />
SensorList<br />
of 1<br />
- Filter:<br />
Message rates<br />
incoming deliver / get<br />
Type<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
classic<br />
Features<br />
amq.gen—ZetkP61eFdklOsxGgdasw<br />
amq.gen-3svxjPR-ed94XPEmTTNQZg<br />
amq.gen-AMvrYwyt1 VxL6LQ91cbN6g<br />
amq.gen-fzyopkh14TJhYvNRvnG78Q<br />
amq.gen-hyqzs7 K9SEW9WOz3LcIaUw<br />
amq.gen-zJ8h6tps7fQ_LJ4ejOKD6LQ<br />
Sta te<br />
idle<br />
idle<br />
idle<br />
idle<br />
idle<br />
idle<br />
idle<br />
idle<br />
idle<br />
Messages<br />
Ready<br />
Unacked<br />
50,595<br />
Total<br />
50 595<br />
hello<br />
sensor<br />
Add a new queue<br />
HTTP API server Docs<br />
Tutorials<br />
Community Support<br />
Community Slack<br />
Commercial Support<br />
o.oo,'s<br />
0.00/s<br />
0.00/s<br />
198/s<br />
0.0 /s<br />
Plugins<br />
0.00/s<br />
0.00/s<br />
0.00/s<br />
0.00/s<br />
GitHub<br />
ack<br />
o.oo,'s<br />
0.00/s<br />
0.00/s<br />
0.00/s<br />
Changelog

可以看到 hello 这个 Queue 的运行信息。

打开 hello Queue

Overview<br />
Connections<br />
RabbitMQ 3.8.11<br />
Channels<br />
Erlang 22.3<br />
Exchanges<br />
Queue hello<br />
Overview<br />
Queued messages last minute<br />
75 k<br />
25k<br />
Message rates last minute ?<br />
300 Is<br />
200 Is<br />
100 Is<br />
Details<br />
Features<br />
Policy<br />
Operator policy<br />
Effective policy definition<br />
Consumers<br />
. no consumers<br />
Bindings<br />
From<br />
Ready<br />
Unacked<br />
Total<br />
Publish<br />
runmng<br />
Admin<br />
. 69,004<br />
• 69,004<br />
• 1261s<br />
Messages<br />
Message body bytes<br />
Process memory<br />
State<br />
Consumers<br />
Consumer utilisation ?<br />
Routing key Arguments<br />
7<br />
Total<br />
69,004<br />
943 kiB<br />
54 MiB<br />
Ready<br />
69,004<br />
943 kiB<br />
Unacked<br />
In memory<br />
69,004<br />
943 kiB<br />
Persistent<br />
Transient, Paged Out<br />
(Default exchange binding)<br />
This queue

可以看到 hello Queue 的运行信息。

移动到下面,

点击 Get Messages 按钮

RabbitMQ 3.8.11 Erlang 22.3<br />
Overview<br />
Connections<br />
Channels<br />
Exchanges<br />
Admin<br />
Get messages<br />
Warning: getting messages from a queue is a destructive action.<br />
Ack Mode:<br />
Encoding:<br />
Messages:<br />
Nack message requeue true v<br />
Auto string / base64 v<br />
Get Message(s)<br />
Message 1<br />
The server reported 80252 messages remaining.<br />
Exchange<br />
Routing Key<br />
Redelivered<br />
Properties<br />
Payload<br />
14 bytes<br />
(AMQP default)<br />
hello<br />
content_type: text/plain<br />
Hello RabbitMQ<br />
Move messages<br />
To move messages, the shovel plugin must be enabled, try:<br />
S rabbiting-plugins enable rabbitmq_shovel<br />
Delete

就可以看到 Queue 里面的消息。

接收消息

从 RabbitMQ 接收消息与向 RabbitMQ 发布消息很类似。 接收消息仍然需要 Connection,Channel,Queue,但是交互方式略有不同。

我将之前的程序代码更新一下,以便可以在同一个 Queue 里同时发送和接收消息:

9<br />
10<br />
11<br />
12<br />
13<br />
14<br />
15<br />
16<br />
17<br />
18<br />
19<br />
20<br />
21<br />
22<br />
23<br />
24<br />
25<br />
26<br />
27<br />
28<br />
29<br />
30<br />
31<br />
32<br />
33<br />
34<br />
35<br />
36<br />
func main() {<br />
go client()<br />
go server()<br />
var a string<br />
fmt.Scanln(8a)<br />
func client() {<br />
— getQueue()<br />
conn, ch, q<br />
conn.Close()<br />
defer<br />
ch . Close()<br />
defer<br />
msgs, err<br />
q. Name ,<br />
true,<br />
false,<br />
false,<br />
false,<br />
nil)<br />
— ch. Consume(<br />
// queue string<br />
// consumer string<br />
// autoAck bool<br />
// exclusive bool<br />
// noLocdl bool<br />
// noWait bool<br />
// args amqp. Table<br />
failOnError(err,<br />
"Failed to register a consumer")<br />
msgs {<br />
for msg<br />
range<br />
log. Printf( "Receive message:<br />
%s\n" ,<br />
msg. Body)
  1. 首先在 18 行建立 client 函数,用于处理接收消息的逻辑

  2. 19 行,通过 getQueue() 获得 Connection,Channel,Queue

  3. 23 行,调用 Channel 上的 Consume 方法。这个方法返回一个 Go 的 Channel,每从服务器接收到消息,就可以通过这个 Go Channel 获得。

  4. Consume 方法的参数:

    1. 第一个参数是接收消息的 queue 的名称,注意接收消息不需要关心 exchange,exchange 只有在发布消息时才用到。

    2. 第二个参数 consumer string,它会唯一的识别出 Queue 对应的 Connection。它被 RabbitMQ 内部使用,来确定谁正在监听这个 Queue。当 Direct Exchange 的多个客户端都从同一个 Queue 接收消息的时候,这个就很重要了。RabbitMQ 会把消息分发到各个客户端,粗略的看作是一种负载均衡。它对于想要取消连接的客户端也很重要,这就可以让 RabbitMQ 知道以后不要再向这个接收者发送消息了。这里我们传进一个“”,让 RabbitMQ 为我们赋一个值,因为我们没有追踪的需求。

    3. 第三个参数 autoAck bool,表示是否想在成功接收消息后自动确认。这个值通常设置为 true,从而让服务器可以立即将这个消息移除,以便节省资源。但是如果接收的消息需要做其它可能失败的动作,例如存储到数据库,那么可能最好将它设置为 false,然后手动进行确认。

    4. 第四个参数 exclusive bool,它可以确认这个客户端是这个 Queue 的唯一消费者。如果它设为 true,而其它客户端已经注册了,或稍后有其它 Queue 将要监听这个 Queue,就会发生错误。这里设为 false。

    5. 第五个参数 noLocal bool,防止 RabbitMQ 发送消息给与发送者处于同一个 Connection 的客户端。这里设为 false。

    6. 第六个参数 noWait bool,如果为 true,就不会等待服务器确认请求,而会立即进行传送。这里设为 false。

    7. 第七个参数 args amqp.Table,对于 Queue 或 Server 有特定语义的参数可以放在这里。此例中,我放的是 nil。

  5. 第 33 行,使用 for 循环来处理 msgs 这个 Go Channel,来接收消息。这里在接收消息后,我只简单的将其打印。

  6. 第 11、12 行,分别使用 goroutine 来运行 client 和 server,注意目前必须把 client 放在前面。

  7. 第 15 行的目的就是让这两个 goroutine 保持存活。

运行

我把 server 函数做了调整,让其持续不断的发布消息:

38<br />
39<br />
40<br />
41<br />
42<br />
43<br />
44<br />
45<br />
46<br />
47<br />
48<br />
49<br />
50<br />
51<br />
52<br />
53<br />
54<br />
55<br />
56<br />
func server() {<br />
getQueue( )<br />
conn, ch, q<br />
conn. Close()<br />
defer<br />
ch . Close()<br />
defer<br />
msg<br />
for<br />
amqp. Publishing{<br />
"text/plain" ,<br />
Content Type:<br />
Body :<br />
ch . Publish(<br />
q. Name ,<br />
false,<br />
false,<br />
msg)<br />
[]byte( "Hello RabbitMQ"),

然后使用 go run . 运行以后,你将看到终端里不断在刷新这样的消息:

2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
2921/93/24<br />
Go src- go run .<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
22:26.<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
• 91<br />
x<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
Receive<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
message :<br />
messaqe :<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
Hello<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMQ<br />
RabbitMO

通过管理控制台,我们可以看到发布和接收消息的速率:

Connections<br />
Overview<br />
v Totals<br />
Queued messages last minute<br />
Message rates last minute ?<br />
30 k/s<br />
20 Vs<br />
10<br />
Global counts ?<br />
Channels<br />
Exchanges<br />
Queues<br />
Ready<br />
Unacked<br />
Total<br />
Publish<br />
Publisher<br />
confirm<br />
Deliver<br />
(manual<br />
ack)<br />
Admin<br />
. 712<br />
• 712<br />
. 21,343/s<br />
0.00/s<br />
• 0.00/s<br />
Deliver<br />
(auto ack)<br />
Consumer<br />
Redelivered<br />
• 21,343/s<br />
• 0.00/s<br />
• 0.00/s
Overview<br />
Connections<br />
Channels<br />
Exchanges<br />
D Regex ?<br />
Queues<br />
Admin<br />
Exchanges<br />
All exchanges (8)<br />
Pagination<br />
Page 1<br />
Name<br />
of 1<br />
- Filter:<br />
Type<br />
direct<br />
fanout<br />
direct<br />
fanout<br />
headers<br />
headers<br />
topic<br />
topic<br />
Features<br />
Message rate in Message rate out<br />
(AMQP default)<br />
SensorDiscoverv<br />
amq.direct<br />
amq.fanout<br />
amq.headers<br />
amq.match<br />
amq.rabbitmq.trace<br />
amq.topic<br />
20,939/s<br />
0.00/s<br />
0.00/s<br />
20,956/s<br />
0.00/s
 
 
 

RabbitMQ 入门 (Go) - 2. 发布和接收消息的更多相关文章

  1. RabbitMQ 入门系列:6、保障消息:不丢失:发送方、Rabbit存储端、接收方。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  2. RabbitMQ 入门系列:7、保障消息不重复消费:产生消息的唯一ID。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  3. RabbitMQ入门-路由-有选择的接受消息

    比如一个日志系统,之前的处理方式呢,是各种类型(info,error,warning)的消息都发给订阅者,可是实际情况上不一定都需要.可能A需要error,其他的都不需要.那么就引入了今天的处理方式- ...

  4. RabbitMQ 入门系列:3、基础编码:官方SDK的引用、链接创建、单例改造、发送消息、接收消息。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  5. RabbitMQ 入门系列:8、扩展内容:接收信息时:可否根据RoutingKey过滤监听信息,答案是不能。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  6. RabbitMQ 入门 (Go) - 4. 使用 Fanout Exchange 做服务发现(上)

    到目前为止,我们项目的结果大致如下: 传感器生成的模拟数据(包含传感器名称.数据.时间戳)是通过传感器在运行时动态创建的 Queue 来发送的.这些 Queue 很难直接被发现. 为了解决这个问题,我 ...

  7. RabbitMQ 入门系列:2、基础含义理解:链接、通道、队列、交换机

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  8. RabbitMQ 入门系列:3、基础含义:持久化、排它性、自动删除、强制性、路由键。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

  9. RabbitMQ 入门系列:5、基础编码:交换机的进阶介绍及编码方式。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...

随机推荐

  1. Web 前端页面性能监控指标

    Web 前端页面性能监控指标 性能监控 / 性能指标 / 性能优化 白屏时间计算 FCP 白屏时间:从浏览器输入地址并回车后到页面开始有内容的时间: 首屏时间计算 FMP 首屏时间:从浏览器输入地址并 ...

  2. 让你像黑客一样写代码(not really)

    让你像黑客一样写代码(not really) http://poznan.tvp.pl 这是一个波兰的视频网站. poznan 波兹南(波兰城市 视屏链接 http://video.sina.com. ...

  3. setTimeout 实现原理, 机制

    setTimeout 实现原理, 机制 JS 执行机制说起 浏览器(或者说 JS 引擎)执行 JS 的机制是基于事件循环. 由于 JS 是单线程,所以同一时间只能执行一个任务,其他任务就得排队,后续任 ...

  4. Objective C & Swift & iOS & App

    Objective C & Swift & iOS & App https://www.runoob.com/ios/ios-objective-c.html https:// ...

  5. Flutter 学习路径

    Flutter 学习路径 docs https://flutter.dev/docs https://flutter.dev/community/china https://flutter-io.cn ...

  6. qt 获取窗口句柄的线程id和进程id GetWindowThreadProcessId

    int lpdwProcessId; int id = GetWindowThreadProcessId((HWND)0x707d6, (LPDWORD)&lpdwProcessId); qD ...

  7. ts 使用 keyof typeof

    传递参数 const cats = { "Coding Cat": "https://media.giphy.com/media/JIX9t2j0ZTN9S/giphy. ...

  8. MarkDown编辑器基础使用教程

    教程原创链接 MarkDown 段落和换行 一个 Markdown 段落是由一个或多个连续的文本行组成,它的前后要有一个以上的空行(空行的定义是显示上看起来像是空的,便会被视为空行.比方说,若某一行只 ...

  9. banner自用图床

    放些常用的图做图床,也不在别的平台用.

  10. MFC多文档程序启动无子窗口的实现

    刚学MFC的我们,肯定会从一个基本MFC程序开始. 而VC++6.0的MFC基础类提供了三种创建方式:单文档.多文档.对话框. 当我们创建多文档应用程序的时候,会自动启动一个子窗口. 在我们平时使用软 ...