nats-io / nats-server

High-Performance server for NATS.io, the cloud and edge native messaging system.
https://nats.io
Apache License 2.0
15.89k stars 1.4k forks source link

Support weight consumers #4970

Open chenjpu opened 9 months ago

chenjpu commented 9 months ago

Proposed change

Like Support pausing and resuming consumers Introduce an API on $JS.API.CONSUMER.WEIGHT.*.* for weight consumers

weighted-mappings is implemented through an account or static configuration,It is more complicated to use in the dynamic service scenarios

Use case

micro For A/B Testing or Canary Releases

Contribution

No response

Jarema commented 9 months ago

Thanks for filling in the proposal.

The consumers have nothing to do with micro service API - as it is using Core NATS for all its communication. You can already use weighted mappings for it.

As for other use cases - This would rather fall into the Stream configuration, where we already have subject mappings, but AFAIK without weights. cc @jnmoyne

jnmoyne commented 9 months ago

(micro doesn't use JetStream) but indeed stream subject mappings are not weighed.

However for simple AB testing you could use the in-stream subject transform to insert a partition number token in the subject (as long as you have or can put something in the subject to distribute on).

For example a stream listening on foo.* you could insert a partition number token and for example decide to use just 2 partitions, so the message subjects get transformed to from foo.<id> to foo.0.<id> and foo.1.<id> (depending on a consistent hash of the value of ), and then have version A create a consumer with a filter of foo.0.* and version B with a filter or foo.1.* to have a 50/50 distribution between A and B. You can use more partitions if you want to split differently (e.g. 3 partitions you could have A consume partitions 0 and 1 and B partition 2). Not as simple as typing a percentage, but should get you there.

You could make this more transparent as well using multiple streams and sourcing. For example the request come to a stream that A consumes from, and you create another stream that sources this stream and that that B consumes from (both A and B get a copy). Or insert a partition number token and then create 2 streams for A and B that source whichever partition(s) you want to send to A/B (and can use subject mapping again to remove the partition number token and restore the subject as it gets sourced if needed).