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。