简单理解消息队列

Posted myuniverse

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单理解消息队列相关的知识,希望对你有一定的参考价值。

  • 简单图示

技术图片

  • 把数据放到消息队列叫做生产者
  • 从消息队列中获取数据叫做消费者
  • 消息队列
    • 概念:生产者和消费者之间的一个中间件。本质是一个队列。
  • 消息队列能做的事情(为什么)
    • 解耦(各个的部分,互不影响)
    • 异步处理(每个部分异步处理,缩短时间)
    • 削峰/限流(降低服务器的压力)
  • 消息队列要注意的问题
    • 数据保存
    • 高可用性(可以在别的服务器上也可以运行)
    • 删除消息
  • 一条消息的产生-》消息队列-》消费-》完整的流程

    • 用户触发某件事情,发起某个请求,生成一个数据
    • 将信息放到消息队列中
    • 中间件轮询,直到消费者获取到自己想要的数据
    • 使用这条数据进行处理其他事情
  • 简单演示,一个生产者对多消费者

    • 思路

    技术图片

    • 参考代码

server.go

package main

import(
    "fmt"
    "log"
    "net/http"
)

func main()
    mux := http.NewServeMux()
    mux.HandleFunc("/Login",Login)
    mux.HandleFunc("/Consumer1",Consumer1)
    mux.HandleFunc("/Consumer2",Consumer2)
    mux.HandleFunc("/Consumer3",Consumer3)
    if err:=http.ListenAndServe(":8080",mux);err!=nil
        log.Fatal(err)
    


/*一个生产者和多消费者*/

// 假定一个生产者
func Login(w http.ResponseWriter,r *http.Request)
    if r.Method != "GET"
        return
    
    fmt.Fprint(w,"生产者来了")


// 多个消费者
func Consumer1(w http.ResponseWriter,r *http.Request)
    if r.Method != "GET"
        return
    
    fmt.Fprint(w,"消费者1")


func Consumer2(w http.ResponseWriter,r *http.Request)
    if r.Method != "GET"
        return
    
    fmt.Fprint(w,"消费者2")


func Consumer3(w http.ResponseWriter,r *http.Request)
    if r.Method != "GET"
        return
    
    fmt.Fprint(w,"消费者3")

client.go

package main

import(
    "fmt"
    "sync"
    "net/http"
    "io/ioutil"
)

type Message struct
    Data string

var wg sync.WaitGroup
// 使用切片充当队列
var messages []*Message

func main()
    fmt.Println("客户端这边执行消息队列")
    producer()
    wg.Add(3)
    // 轮询,获取消息
    for
        if len(messages)>0
            // 按需获取消息
            if messages[0]!=nil
                go comsumer("Consumer1")
                go comsumer("Consumer2")
                go comsumer("Consumer3")
                wg.Wait()
                break
            
        
    
    fmt.Println("打印结果")


// 生产者
func producer()error
    mg := Message
    res,err := http.Get("http://localhost:8080/Login")
    if err!=nil
        fmt.Println("err :",err)
        return err
    
    defer res.Body.Close()
    data,err := ioutil.ReadAll(res.Body)
    if err!=nil
        fmt.Println("err:",err)
        return err
    
    fmt.Println(string(data))
    mg.Data = string(data)
    messages = append(messages,&mg)
    return nil


// 消费者
func comsumer(url string)error
    defer wg.Done()
    mg := Message
    res,err := http.Get("http://localhost:8080/"+url)
    if err!=nil
        fmt.Println("err :",err)
        return err
    
    defer res.Body.Close()
    data,err := ioutil.ReadAll(res.Body)
    if err!=nil
        fmt.Println("err:",err)
        return err
    
    fmt.Println(string(data))
    mg.Data = string(data)
    messages = append(messages,&mg)
    return nil
  • 输出结果

    客户端这边执行消息队列
    生产者来了
    消费者2
    消费者3
    消费者1
    打印结果
  • 明确观点:本人觉得,消息队列是客户端和服务端的一个中间插件

  • 学习资料

以上是关于简单理解消息队列的主要内容,如果未能解决你的问题,请参考以下文章

消息队列----理解随记

消息队列----理解随记

一个最简单的消息队列,带你理解 RabbitMQ!

消息队列在企业架构中扮演着什么角色?

转MSMQ 微软消息队列 简单 示例

消息队列1:消息队列概述