nats中的消息序列号

1、自己设置消息ID

设置:

js.Publish(subject, []byte(data), nats.MsgId(msgID))

获取:

msg.Header.Get("Nats-Msg-Id")

此消息号只是相当于其中一个字段,不会影响nats的逻辑,没有体会到具体用途。

2、nats自己的序列号

stream最新序列号:

stream.LatestState()

type StreamState struct {
	Msgs       uint64          `json:"messages"`
	Bytes      uint64          `json:"bytes"`
	FirstSeq   uint64          `json:"first_seq"`
	FirstTime  time.Time       `json:"first_ts"`
	LastSeq    uint64          `json:"last_seq"`
	LastTime   time.Time       `json:"last_ts"`
	NumDeleted int             `json:"num_deleted,omitempty"`
	Deleted    []uint64        `json:"deleted,omitempty"`
	Lost       *LostStreamData `json:"lost,omitempty"`
	Consumers  int             `json:"consumer_count"`
}

LastSeq基本准确。

cusumer最新序列号:
目前已传输的序列号

consumer.DeliveredState()

type SequenceInfo struct {
	Consumer uint64     `json:"consumer_seq"`
	Stream   uint64     `json:"stream_seq"`
	Last     *time.Time `json:"last_active,omitempty"`
}

Stream最终跟stream中的LastSeq一致,有时候两个msg用一个seq,大部分情况下还是每个msg一个seq。
Consumer基本是每个msg一个,有时候会大于Stream。

获取消息中的序列号:

metaData,err := jsm.ParseJSMsgMetadata(msg)
	if err != nil {
		log.Errorf("ParseJSMsgMetadata err: %s[%s-%v]", err, msg.Subject, msg.Data)
		return err
	}

	seqStr := metaData.StreamSequence()
	seqCons := metaData.ConsumerSequence()

3、客户端订阅

pull模式:

consumer, err := stream.LoadOrNewConsumer(consumerName,
		jsm.DurableName(consumerName),	
		jsm.StartWithLastReceived(),
	)
msg, err := consumer.NextMsg()

先pub数据,在添加consumer,comsumer只能获取到最后一个消息(consumer中stream_seq为最新序列号减一,consumer_seq为0,收到消息是从stream_seq+1开始,直到stream中的最新序列号,所以是一个消息)。
之后重启客户端,consumer是load出的,消息订阅正常。

而consumer的配置是无法update的。
所以只能每次删除重建consumer或者创建两个consumer,一个用来接收从0到第一次consumer创建期间的消息(可以通过consumer是不是新建的,或者consumer中的consumer_seq是否为0判断),一个用来接收之后的消息。

或者每个subject设置一个consumer()

其中的opt:
jsm.DeliverySubject不能使用通配符
NewConsumer error: consumer deliver subject has wildcards
不用通配符好像不管用。

jsm.FilterStreamBySubject(“001”)可以设置通配符,但通配以后跟不设置效果一样

push模式:

sub, err := js.Subscribe(subj, func(msg *nats.Msg) {
	metaData, err := jsm.ParseJSMsgMetadata(msg)

	if err != nil {
		fmt.Printf("ParseJSMsgMetadata err: %s[%s-%v]\r\n", err, msg.Subject, msg.Data)
	}

	//先使用stream seq
	seq := metaData.StreamSequence()
	seqCons := metaData.ConsumerSequence()
	fmt.Printf("RcvSyncMsg: [%d %d]%s - %v\r\n", seq, seqCons, msg.Subject, msg.Data)
}, nats.StartSequence(7))

push模式通过每次调整startSequence可以获取到所有消息(首次启动需要设置为1)。
可以通过持久化当前接收序列号来实现,防止client异常重启。

或者使用 nats.Durable(“test1001”),server会为client维护断点信息,经测试可以使用。
不同的subject可以使用相同的durable name。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值