• 简单理解消息队列


    • 简单图示

    • 把数据放到消息队列叫做生产者

    • 从消息队列中获取数据叫做消费者

    • 消息队列

      • 概念:生产者和消费者之间的一个中间件。本质是一个队列。
    • 消息队列能做的事情(为什么)

      • 解耦(各个的部分,互不影响)
      • 异步处理(每个部分异步处理,缩短时间)
      • 削峰/限流(降低服务器的压力)
    • 消息队列要注意的问题

      • 数据保存
      • 高可用性(可以在别的服务器上也可以运行)
      • 删除消息
    • 一条消息的产生-》消息队列-》消费-》完整的流程

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

      • 思路

      • 参考代码

    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
      打印结果
      
    • 明确观点:本人觉得,消息队列是客户端和服务端的一个中间插件

    • 学习资料

  • 相关阅读:
    《人月神话》阅读笔记2
    【个人作业】单词链
    【个人作业】找水王
    【团队】 冲刺一(10/10)
    【团队】 冲刺一(9/10)
    【个人作业】单词统计续
    【团队】 冲刺一(8/10)
    【团队】 冲刺一(7/10)
    【团队】 冲刺一(6/10)
    【团队】 冲刺一(5/10)
  • 原文地址:https://www.cnblogs.com/MyUniverse/p/11626259.html
Copyright © 2020-2023  润新知