最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GoLang RabbitMQ實現(xiàn)六種工作模式示例

 更新時間:2022年12月17日 16:00:42   作者:Onemorelight95  
這篇文章主要介紹了GoLang RabbitMQ實現(xiàn)六種工作模式,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

六種工作模式介紹

1.簡單(Simple)模式

P:生產(chǎn)者,也就是要發(fā)送消息的程序。

C:消費者:消息的接收者,會一直等待消息到來。

queue:消息隊列,圖中紅色部分。類似一個郵箱,可以緩存消息;生產(chǎn)者向其中投遞消息,消費者從其中取出消息。

簡單模式就是單發(fā)單收,消息的消費者監(jiān)聽消息隊列,如果隊列中有消息,就消費掉,消息被拿走后,自動從隊列中刪除。

2.工作隊列(Work Queue)模式

這種模式就是多個消費者消費同一個隊列中的消息,既然消費者多了那么就出現(xiàn)了消息分配的問題,所以對應著兩種分配策略:

  • 公平分發(fā):每個消費者接收消息的概率是相等的,消息隊列會循環(huán)依次給每個消費者發(fā)送消息,這種是默認的策略。
  • 公平派遣:保證消費者在消費完某個消息,并發(fā)送確認信息后,消息隊列才會向它推送新的消息,在此之間若是有新的消息,將會被推送到其它消費者,若所有的消費者都在消費消息,那么就會等待。

3.發(fā)布/訂閱(Pub/Sub)模式

在這種模型中,多了一個 Exchange 角色,而且過程略有變化:

P:生產(chǎn)者,也就是要發(fā)送消息的程序,但是不再發(fā)送到隊列中,而是發(fā)給X (交換機)。

C:消費者,消息的接收者,會一直等待消息到來。

Queue:消息隊列,接收消息、緩存消息。

Exchange:交換機(X) ,一方面,接收生產(chǎn)者發(fā)送的消息。另一方面,如何處理消息,遞交給某個特別隊列、遞交給所有隊列、或是將消息丟棄。到底如何操作,取決于Exchange的類型。 Exchange有以下4種類型:

  • Fanout:廣播,將消息交給所有綁定到交換機的隊列。
  • Direct:全值匹配,把消息交給符合指定routing key的隊列。
  • Topic:通配符,與Direct類型類似,但Direct類型要求routing key完全相等,而Topic類型是對routing key進行模糊匹配,比Direct靈活。
  • Headers:根據(jù)Message的一些頭部信息來分發(fā)過濾Message,用的比較少。

注意:Exchange負責轉發(fā)消息,不具備存儲消息的能力,因此如果沒有任何隊列與Exchange綁定,或者沒有符合路由規(guī)則的隊列,那么消息會丟失。

4.路由(Routing)模式

路由模式其實就是上述發(fā)布/訂閱模式的交換機轉發(fā)類型變成了Direct類型。在這種模式下:

Exchange 不再把消息交給每一個綁定的隊列,而是根據(jù)消息的routing key進行判斷,只有隊列的

routing key與消息的routing key完全一致,才會接收到消息。

P:生產(chǎn)者,向 Exchange 發(fā)送消息,發(fā)送消息時,會指定一個routing key。

X:Exchange(交換機),接收生產(chǎn)者的消息,然后把消息遞交給與routing key完全匹配的隊列。

C1:消費者,其所在隊列指定了需要routing key為error的消息。

C2:消費者,其所在隊列指定了需要routing key為 info、error、warning 的消息。

5.通配符(Tpoic)模式

路由模式其實就是上述發(fā)布/訂閱模式的交換機轉發(fā)類型變成了Topic類型。在這種模式下:

隊列的routing key與消息的routing key符合匹配規(guī)則,就可以接收到消息,有兩種規(guī)則:

*:可以(只能)匹配一個單詞。

#:可以匹配多個單詞(或者零個)。

所以圖中,routing keya.orange.b的消息就會被轉發(fā)到Q1,而routing keyLazy.a.b.c的消息就會被發(fā)送到Q2。

Go語言的實現(xiàn)

安裝操作庫

安裝API庫

Go可以使用streadway/amqp庫來操作rabbit,使用以下命令來安裝:

go get github.com/streadway/amqp

封裝rabbitmq

接下來我們對streadway/amqp庫的內(nèi)容進行一個二次封裝,封裝為一個rabbitmq.go文件:

package rabbitmq
import (
	"encoding/json"
	"github.com/streadway/amqp"
	"log"
)
// RabbitMQ RabbitMQ結構
type RabbitMQ struct {
	channel  *amqp.Channel
	Name     string
	exchange string
}
// Connect 連接服務器
func Connect(s string) *RabbitMQ {
	//連接rabbitmq
	conn, e := amqp.Dial(s)
	failOnError(e, "連接Rabbitmq服務器失敗!")
	ch, e := conn.Channel()
	failOnError(e, "無法打開頻道!")
	mq := new(RabbitMQ)
	mq.channel = ch
	return mq
}
// New 初始化消息隊列
//第一個參數(shù):rabbitmq服務器的鏈接,第二個參數(shù):隊列名字
func New(s string, name string) *RabbitMQ {
	//連接rabbitmq
	conn, e := amqp.Dial(s)
	failOnError(e, "連接Rabbitmq服務器失敗!")
	ch, e := conn.Channel()
	failOnError(e, "無法打開頻道!")
	q, e := ch.QueueDeclare(
		name,  //隊列名
		false, //是否開啟持久化
		true,  //不使用時刪除
		false, //排他
		false, //不等待
		nil,   //參數(shù)
	)
	failOnError(e, "初始化消息隊列失??!")
	mq := new(RabbitMQ)
	mq.channel = ch
	mq.Name = q.Name
	return mq
}
// QueueDeclare 聲明queue
func (q *RabbitMQ) QueueDeclare(queue string) {
	_, e := q.channel.QueueDeclare(queue, false, true, false, false, nil)
	failOnError(e, "聲明queue失??!")
}
// QueueDelete 刪除queue
func (q *RabbitMQ) QueueDelete(queue string) {
	_, e := q.channel.QueueDelete(queue, false, true, false)
	failOnError(e, "刪除queue失??!")
}
// Qos 配置queue參數(shù)
func (q *RabbitMQ) Qos() {
	e := q.channel.Qos(1, 0, false)
	failOnError(e, "無法設置QoS")
}
// NewExchange 初始化交換機
//第一個參數(shù):rabbitmq服務器的鏈接,第二個參數(shù):交換機名字,第三個參數(shù):交換機類型
func NewExchange(s string, name string, typename string) {
	//連接rabbitmq
	conn, e := amqp.Dial(s)
	failOnError(e, "連接Rabbitmq服務器失?。?)
	ch, e := conn.Channel()
	failOnError(e, "無法打開頻道!")
	e = ch.ExchangeDeclare(
		name,     // name
		typename, // type
		true,     // durable
		false,    // auto-deleted
		false,    // internal
		false,    // no-wait
		nil,      // arguments
	)
	failOnError(e, "初始化交換機失敗!")
}
// ExchangeDelete 刪除交換機
func (q *RabbitMQ) ExchangeDelete(exchange string) {
	e := q.channel.ExchangeDelete(exchange, false, true)
	failOnError(e, "刪除交換機失??!")
}
// Bind 綁定消息隊列到exchange
func (q *RabbitMQ) Bind(exchange string, key string) {
	e := q.channel.QueueBind(
		q.Name,
		key,
		exchange,
		false,
		nil,
	)
	failOnError(e, "綁定隊列失敗!")
	q.exchange = exchange
}
// Send 向消息隊列發(fā)送消息
//Send方法可以往某個消息隊列發(fā)送消息
func (q *RabbitMQ) Send(queue string, body interface{}) {
	str, e := json.Marshal(body)
	failOnError(e, "消息序列化失敗!")
	e = q.channel.Publish(
		"",    //交換
		queue, //路由鍵
		false, //必填
		false, //立即
		amqp.Publishing{
			ReplyTo: q.Name,
			Body:    []byte(str),
		})
	msg := "向隊列:" + q.Name + "發(fā)送消息失??!"
	failOnError(e, msg)
}
// Publish 向exchange發(fā)送消息
//Publish方法可以往某個exchange發(fā)送消息
func (q *RabbitMQ) Publish(exchange string, body interface{}, key string) {
	str, e := json.Marshal(body)
	failOnError(e, "消息序列化失?。?)
	e = q.channel.Publish(
		exchange,
		key,
		false,
		false,
		amqp.Publishing{ReplyTo: q.Name,
			Body: []byte(str)},
	)
	failOnError(e, "向交換機發(fā)送消息失??!")
}
// Consume 接收某個消息隊列的消息
func (q *RabbitMQ) Consume() <-chan amqp.Delivery {
	c, e := q.channel.Consume(
		q.Name, //指定從哪個隊列中接收消息
		"",
		true,
		false,
		false,
		false,
		nil,
	)
	failOnError(e, "接收消息失??!")
	return c
}
// Close 關閉隊列連接
func (q *RabbitMQ) Close() {
	q.channel.Close()
}
//錯誤處理函數(shù)
func failOnError(err error, msg string) {
	if err != nil {
		log.Fatalf("%s: %s", msg, err)
	}
}

簡單(Simple)模式

生產(chǎn)者

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "simple")
	i := 0
	for {
		// 每隔2s發(fā)送一次消息
		time.Sleep(time.Second * 2)
		producer.Send("simple", " simple message: "+strconv.Itoa(i))
		i = i + 1
	}
}

消費者

func main() {
	consumer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "simple")
	//接收消息時,指定
	messages := consumer.Consume()
	go func() {
		for ch := range messages {
			log.Printf("Received a message: %s", ch.Body)
			// 消費消息要用3s
			time.Sleep(time.Second * 3)
		}
	}()
	select {}
}

運行結果:

2022/11/05 18:54:47 Received a message: " simple message: 0"
2022/11/05 18:54:52 Received a message: " simple message: 1"
2022/11/05 18:54:57 Received a message: " simple message: 2"

工作隊列(Work Queue)模式

公平分發(fā)模式:

公平分發(fā)模式采用的是輪詢機制,它會將數(shù)個任務按順序平均分發(fā)給消費者。

生產(chǎn)者

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	i := 0
	for {
		// 每隔2s發(fā)送一次消息
		time.Sleep(time.Second * 2)
		producer.Send("worker", " worker message: "+strconv.Itoa(i))
		i = i + 1
	}
}

消費者1

func main() {
	consumer1 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	//接收消息
	messages := consumer1.Consume()
	go func() {
		for ch := range messages {
			log.Printf("Received a message: %s", ch.Body)
			// 消費消息要用3s
			time.Sleep(time.Second * 3)
		}
	}()
	select {}
}

消費者2

func main() {
	consumer2 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	//接收消息
	messages := consumer2.Consume()
	go func() {
		for ch := range messages {
			log.Printf("Received a message: %s", ch.Body)
			// 消費消息要用3s
			time.Sleep(time.Second * 3)
		}
	}()
	select {}
}

運行結果:

# 消費者1
2022/11/05 19:45:03 Received a message: " worker message: 0"
2022/11/05 19:45:07 Received a message: " worker message: 2"
2022/11/05 19:45:11 Received a message: " worker message: 4"

# 消費者2
2022/11/05 19:45:05 Received a message: " worker message: 1"
2022/11/05 19:45:09 Received a message: " worker message: 3"
2022/11/05 19:45:13 Received a message: " worker message: 5"

可以發(fā)現(xiàn),公平模式下,偶數(shù)消息都被發(fā)送給了消費者1,而奇數(shù)消息都被發(fā)送給了消費者2。

公平派遣模式:

有時候,如果消息之間的復雜度不同,那么不同消費者消費消息所用的時間會不同。這個時候如果使用公平派發(fā)模式,可能會造成某一個消費者需要消費的消息積壓過多??梢圆捎霉脚汕材J剑?/p>

公平派遣模式下發(fā)送端與公平分發(fā)相同,消費者端只需要加一段配置代碼,我們可以將預取計數(shù)設置為1。這告訴RabbitMQ一次不要給消費者一個以上的消息。換句話說,在處理并確認上一條消息之前,不要將新消息發(fā)送給消費者。而是將其分派給不忙的下一個消費者。

關于消息的確認:

為了確保消息永不丟失,RabbitMQ支持 消息確認。消費者發(fā)送回一個確認(acknowledgement),以告知RabbitMQ已經(jīng)接收,處理了特定的消息,并且RabbitMQ可以自由刪除它。

我們之前的代碼中,RabbitMQ一旦向消費者傳遞了一條消息,便立即將其標記為刪除(調(diào)用Consumer的第三個參數(shù)是autoAck,表示是否自動回復)。在這種情況下,如果你終止一個消費者那么你就可能會丟失這個任務,我們還將丟失所有已經(jīng)交付給這個消費者的尚未消費的消息。如果一個消費者意外宕機了,那么我們希望將任務交付給其他消費者來消費者。

所以一旦向消費者傳遞了一條消息,就不能馬上將其標記為刪除,而是要手動確認。我們需要在創(chuàng)建消費者的時候將autoAck參數(shù)標記為false:

// Consume 接收某個消息隊列的消息
func (q *RabbitMQ) Consume() <-chan amqp.Delivery {
	c, e := q.channel.Consume(
		q.Name, //指定從哪個隊列中接收消息
		"",
		false, // 不自動確認消息
		false,
		false,
		false,
		nil,
	)
	failOnError(e, "接收消息失??!")
	return c
}

然后每消費完一條消息需要調(diào)用Ack(false)函數(shù)手動回復。

生產(chǎn)者

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	i := 0
	for {
		// 每隔2s發(fā)送一次消息
		time.Sleep(time.Second * 2)
		producer.Send("worker", " worker message: "+strconv.Itoa(i))
		i = i + 1
	}
}

消費端限流:

實現(xiàn)公平派遣模式我們需要設置消費者端一次只能消費一條消息,之前我們已經(jīng)進行了封裝,直接在消費者端調(diào)用即可:

// Qos 配置queue參數(shù)
func (q *RabbitMQ) Qos() {
	e := q.channel.Qos(1, 0, false)
	failOnError(e, "無法設置QoS")
}

消費者1

func main() {
	consumer1 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	// 指定一次只消費一條消息,直到消費完才重新接收
	consumer1.Qos()
	//接收消息
	messages := consumer1.Consume()
	go func() {
		for ch := range messages {
			log.Printf("Received a message: %s", ch.Body)
			// 消費消息要用10s
			time.Sleep(time.Second * 10)
			// 手動回復
			ch.Ack(false)
		}
	}()
	select {}
}

消費者2

func main() {
	consumer2 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "worker")
	// 指定一次只消費一條消息,直到消費完才重新接收
	consumer2.Qos()
	//接收消息
	messages := consumer2.Consume()
	go func() {
		for ch := range messages {
			log.Printf("Received a message: %s", ch.Body)
			// 消費消息要用2s
			time.Sleep(time.Second * 2)
			// 手動回復
			ch.Ack(false)
		}
	}()
	select {}
}

運行結果:

# 消費者1
2022/11/05 20:31:26 Received a message: " worker message: 0"
2022/11/05 20:31:36 Received a message: " worker message: 5"

# 消費者2
2022/11/05 20:31:28 Received a message: " worker message: 1"
2022/11/05 20:31:30 Received a message: " worker message: 2"
2022/11/05 20:31:32 Received a message: " worker message: 3"
2022/11/05 20:31:34 Received a message: " worker message: 4"
2022/11/05 20:31:38 Received a message: " worker message: 6"
2022/11/05 20:31:40 Received a message: " worker message: 7"

發(fā)布/訂閱(Pub/Sub)模式

生產(chǎn)者

func main() {
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue")
	rabbitmq.NewExchange("amqp://guest:guest@35.76.111.125:5672/", "exchange1", "fanout")
	i := 0
	for {
		time.Sleep(time.Second)
		// fanout模式下不用routing key
		producer.Publish("exchange1", "pubsub message: "+strconv.Itoa(i), "")
		i = i + 1
	}
}

消費者1

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer1 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue1")
	// 隊列綁定到exchange
	consumer1.Bind("exchange1", "")
	//接收消息
	msgs := consumer1.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer1 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

消費者2

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer2 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue2")
	// 隊列綁定到exchange
	consumer2.Bind("exchange1", "")
	//接收消息
	msgs := consumer2.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer2 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

運行結果:

# 消費者1
2022/11/05 22:32:19 Consumer1 received a message: "pubsub message: 0"
2022/11/05 22:32:20 Consumer1 received a message: "pubsub message: 1"
2022/11/05 22:32:21 Consumer1 received a message: "pubsub message: 2"
2022/11/05 22:32:22 Consumer1 received a message: "pubsub message: 3"
2022/11/05 22:32:23 Consumer1 received a message: "pubsub message: 4"
2022/11/05 22:32:24 Consumer1 received a message: "pubsub message: 5"

# 消費者2
2022/11/05 22:32:19 Consumer2 received a message: "pubsub message: 0"
2022/11/05 22:32:20 Consumer2 received a message: "pubsub message: 1"
2022/11/05 22:32:21 Consumer2 received a message: "pubsub message: 2"
2022/11/05 22:32:22 Consumer2 received a message: "pubsub message: 3"
2022/11/05 22:32:23 Consumer2 received a message: "pubsub message: 4"
2022/11/05 22:32:24 Consumer2 received a message: "pubsub message: 5"

路由(Routing)模式

生產(chǎn)者

func main() {
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue")
	// 指定為direct類型
	rabbitmq.NewExchange("amqp://guest:guest@35.76.111.125:5672/", "exchange", "direct")
	i := 0
	for {
		time.Sleep(time.Second)
		// 如果是奇數(shù),就發(fā)key1
		// 如果是偶數(shù),就發(fā)key2
		if i%2 != 0 {
			producer.Publish("exchange", "routing message: "+strconv.Itoa(i), "key1")
		} else {
			producer.Publish("exchange", "routing message: "+strconv.Itoa(i), "key2")
		}
		i = i + 1
	}
}

消費者1

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer1 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue1")
	// 隊列綁定到exchange
	consumer1.Bind("exchange", "key1")
	//接收消息
	msgs := consumer1.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer1 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

消費者2

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer2 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue2")
	// 隊列綁定到exchange
	consumer2.Bind("exchange", "key2")
	//接收消息
	msgs := consumer2.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer2 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

運行結果:

# 消費者1
2022/11/05 22:51:10 Consumer1 received a message: "routing message: 1"
2022/11/05 22:51:12 Consumer1 received a message: "routing message: 3"
2022/11/05 22:51:14 Consumer1 received a message: "routing message: 5"
2022/11/05 22:51:16 Consumer1 received a message: "routing message: 7"

# 消費者2
2022/11/05 22:51:11 Consumer2 received a message: "routing message: 0"
2022/11/05 22:51:13 Consumer2 received a message: "routing message: 2"
2022/11/05 22:51:15 Consumer2 received a message: "routing message: 4"
2022/11/05 22:51:17 Consumer2 received a message: "routing message: 6"

通配符(Tpoic)模式

生產(chǎn)者

func main() {
	producer := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue")
	// 指定為topic類型
	rabbitmq.NewExchange("amqp://guest:guest@35.76.111.125:5672/", "exchange2", "topic")
	var i int
	for {
		time.Sleep(time.Second)
		if i%2 != 0 {
			producer.Publish("exchange2", "topic message: "+strconv.Itoa(i), "a.test.b.c")
		} else {
			producer.Publish("exchange2", "topic message: "+strconv.Itoa(i), "a.test.b")
		}
		i++
	}
}

消費者1

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer1 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue1")
	// 隊列綁定到exchange
	consumer1.Bind("exchange2", "*.test.*")
	//接收消息
	msgs := consumer1.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer1 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

消費者2

func main() {
	//第一個參數(shù)指定rabbitmq服務器的鏈接,第二個參數(shù)指定創(chuàng)建隊列的名字
	consumer2 := rabbitmq.New("amqp://guest:guest@35.76.111.125:5672/", "queue2")
	// 隊列綁定到exchange
	consumer2.Bind("exchange2", "#.test.#")
	//接收消息
	msgs := consumer2.Consume()
	go func() {
		for d := range msgs {
			log.Printf("Consumer2 received a message: %s", d.Body)
			d.Ack(false)
		}
	}()
	select {}
}

運行結果:

# 消費者1
2022/11/05 23:09:53 Consumer1 received a message: "topic message: 0"
2022/11/05 23:09:55 Consumer1 received a message: "topic message: 2"
2022/11/05 23:09:57 Consumer1 received a message: "topic message: 4"
2022/11/05 23:09:59 Consumer1 received a message: "topic message: 6"

# 消費者2
2022/11/05 23:09:53 Consumer2 received a message: "topic message: 0"
2022/11/05 23:09:54 Consumer2 received a message: "topic message: 1"
2022/11/05 23:09:55 Consumer2 received a message: "topic message: 2"
2022/11/05 23:09:56 Consumer2 received a message: "topic message: 3"
2022/11/05 23:09:57 Consumer2 received a message: "topic message: 4"
2022/11/05 23:09:58 Consumer2 received a message: "topic message: 5"
2022/11/05 23:09:59 Consumer2 received a message: "topic message: 6"

到此這篇關于GoLang RabbitMQ實現(xiàn)六種工作模式示例的文章就介紹到這了,更多相關GoLang RabbitMQ工作模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go中strings的常用方法詳解

    Go中strings的常用方法詳解

    這篇文章主要介紹了Go中strings的常用方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03
  • go web 預防跨站腳本的實現(xiàn)方式

    go web 預防跨站腳本的實現(xiàn)方式

    這篇文章主要介紹了go web 預防跨站腳本的實現(xiàn)方式,文中給大家介紹XSS最佳的防護應該注意哪些問題,本文通過實例代碼講解的非常詳細,需要的朋友可以參考下
    2021-06-06
  • 使用go gin來操作cookie的講解

    使用go gin來操作cookie的講解

    今天小編就為大家分享一篇關于使用go gin來操作cookie的講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Go語言基礎知識總結(語法、變量、數(shù)值類型、表達式、控制結構等)

    Go語言基礎知識總結(語法、變量、數(shù)值類型、表達式、控制結構等)

    這篇文章主要介紹了Go語言基礎知識總結(語法、變量、數(shù)值類型、表達式、控制結構等),本文匯總了Go語言的入門知識,需要的朋友可以參考下
    2014-10-10
  • Go語言學習之映射(map)的用法詳解

    Go語言學習之映射(map)的用法詳解

    Map是一種無序的鍵值對的集合。這篇文章主要為大家詳細介紹了Go語言中映射的用法,文中的示例代碼講解詳細,對我們學習Go語言有一定的幫助,需要的可以參考一下
    2022-04-04
  • Golang信號量設計實現(xiàn)示例詳解

    Golang信號量設計實現(xiàn)示例詳解

    這篇文章主要為大家介紹了Golang信號量設計實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • go開發(fā)過程中mapstructure使用示例詳解

    go開發(fā)過程中mapstructure使用示例詳解

    mapstructure是一個Go語言庫,用于將映射(如map或struct)解碼為結構體,便于處理JSON、YAML等配置文件數(shù)據(jù),通過字段名或結構體標簽控制解碼,支持嵌套結構體、靈活處理多種數(shù)據(jù)源,需要注意錯誤處理,該庫適合于Go開發(fā)中配置數(shù)據(jù)的讀取和轉換
    2024-10-10
  • Go打印結構體提升代碼調(diào)試效率實例詳解

    Go打印結構體提升代碼調(diào)試效率實例詳解

    這篇文章主要介紹了Go打印結構體提升代碼調(diào)試效率實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-02-02
  • Go語言實現(xiàn)二維數(shù)組的2種遍歷方式以及案例詳解

    Go語言實現(xiàn)二維數(shù)組的2種遍歷方式以及案例詳解

    這篇文章主要介紹了Go語言實現(xiàn)二維數(shù)組的2種遍歷方式以及案例詳解,圖文代碼聲情并茂,有感興趣的可以學習下
    2021-03-03
  • Golang實現(xiàn)自己的Redis(有序集合跳表)實例探究

    Golang實現(xiàn)自己的Redis(有序集合跳表)實例探究

    這篇文章主要為大家介紹了Golang實現(xiàn)自己的Redis(有序集合跳表)實例探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2024-01-01

最新評論

万安县| 甘孜| 田林县| 明水县| 奈曼旗| 南涧| 锡林郭勒盟| 镇雄县| 固原市| 都兰县| 建水县| 密云县| 揭西县| 扬中市| 隆德县| 柘荣县| 鹿泉市| 罗江县| 神池县| 施甸县| 仪陇县| 建湖县| 甘孜县| 东阿县| 都兰县| 无为县| 施甸县| 巴林左旗| 枞阳县| 望谟县| 闽清县| 定结县| 潜山县| 旺苍县| 嘉义县| 烟台市| 内江市| 深水埗区| 寿宁县| 丰顺县| 通江县|