nats 发布订阅的系统的使用记录

本文介绍了NATS,一种专注于高效消息传递的分布式系统,用于构建高性能应用。通过Go语言示例展示了异步和同步发布/订阅功能,以及如何优雅地关闭连接。同时提到了NATS的局限性和与RabbitMQ等中间件的比较。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

更侧重于提供快速的消息传递和简单的API。
主要用于构建高性能的分布式系统,如微服务通信、实时消息系统等。
支持多种客户端语言,易于集成和部署。
设计上更注重于轻量级和速度,牺牲了一些功能性和消息传递保证(如消息持久化)来实现这一点。
如果是使用更可靠的消息,还是建议使用rabbitmq 等中间件

注意的在nats 中, 如果你发布到一个主题,而这个主题没有任何订阅者,那么发送的消息会被丢弃。

编写代码

测试基础代码异步和同步发布订阅

func TestNats(t *testing.T) {
	var err error
	var sub *nats.Subscription
	// 连接到服务器
	nc, _ := nats.Connect(nats.DefaultURL)
	// 简单的异步订阅者
	sub, err = nc.Subscribe("foo", func(m *nats.Msg) {
		fmt.Printf("接收到消息:%s\n", string(m.Data))
		time.Sleep(time.Second)
		nc.Publish(m.Reply, []byte("I can help!"))

	})

	// 简单的发布者
	err = nc.Publish("foo", []byte("1,Hello World"))
	err = nc.Publish("foo", []byte("2.Hello World"))
	err = nc.Publish("foo", []byte("3.Hello World"))
	if err != nil {
		t.Fatalf("发布消息失败:%v", err)
	}

	t.Log("取消订阅")
	sub.Drain()         // 平滑取消订阅,之前push 到队列里面的,会处理,新的消息不会处理
	sub.Unsubscribe()   // 立马就取消了,不会处理队列里面的消息
	for sub.IsValid() { // 会等待队列里面的消息处理完 ,一般配合 drain 使用
		time.Sleep(time.Millisecond * 100)
		//t.Log("等待取消订阅")
	}
	
	// 简单的同步订阅者
	msg, err := nc.Request("foo", []byte("帮帮我"), 2000*time.Millisecond)
	if err != nil {
		t.Fatalf("请求失败:%v", err)

	}
	t.Log("我收到:", string(msg.Data))
	nc.Drain() // 平滑关闭,等待队列里面的消息处理完 ,默认会调用 Close()
	//nc.IsDraining() // 判断是否排空了
	time.Sleep(20 * time.Second)

}

测试优雅关闭订阅和连接

func TestNatsClient(t *testing.T) {
	var notifyChan = make(chan struct{})
	go func() {
		//var err error
		//var sub *nats.Subscription
		nc, _ := nats.Connect(nats.DefaultURL)
		// 简单的异步订阅者
		_, err := nc.Subscribe("foo", func(m *nats.Msg) {
			fmt.Printf("接收到消息:%s\n", string(m.Data))
			time.Sleep(1 * time.Second)
		})
		if err != nil {
			t.Fatalf("订阅失败:%v", err)
		}
		time.Sleep(2 * time.Second)
		nc.Drain()
		for nc.IsDraining() {
			time.Sleep(1000 * time.Millisecond)
			t.Log("等待排空")
		}
		for !nc.IsClosed() {
			time.Sleep(1000 * time.Millisecond)
			t.Log("等待关闭")
		}
		t.Log("nc old close,启动新的订阅")
		ncs, _ := nats.Connect(nats.DefaultURL)
		_, err = ncs.Subscribe("foo", func(m *nats.Msg) {
			fmt.Printf("v2接收到消息:%s\n", string(m.Data))
			time.Sleep(time.Second)
		})
		time.Sleep(10 * time.Millisecond)
		notifyChan <- struct{}{}
		t.Log("优雅关闭并且通知了")

	}()

	go func() {
		nc, _ := nats.Connect(nats.DefaultURL)
		// 简单的发布者
		time.Sleep(10 * time.Millisecond)
		for i := 0; i < 5; i++ {
			err := nc.Publish("foo", []byte(fmt.Sprintf("%d,Hello World", i)))
			if err != nil {
				t.Fatalf("发布消息失败:%v", err)
			}
		}
		t.Log("发布完成")
		<-notifyChan
		close(notifyChan)
		t.Log("收到关闭通知")
		for i := 5; i < 10; i++ {
			err := nc.Publish("foo", []byte(fmt.Sprintf("%d,2222 World", i)))
			if err != nil {
				t.Fatalf("发布消息失败:%v", err)
			}
		}
	}()

	time.Sleep(30 * time.Second)

}
订阅信息的http
http://localhost:8222/connz
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gitxuzan_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值