NATS Weekly #13
Published on Feb 14th, 2022
Week of February 7 - 13, 2022
🗞 Announcements, writings, and projects
A short list of announcements, blog posts, projects updates and other news.
️ 💁 News
- CVE-2022-24450 - Unconstrained account assumption by authenticated clients
Official releases from NATS repos and others in the ecosystem.
- nats-io/nats.rs - v0.18.1
- nats-io/k8s - v0.13.0
- nats-io/nats-account-server - v1.0.1
- nats-io/nats-pure.rb - v2.0.0
Github Discussions from various NATS repos.
- nats-server - Could I publish message with wildcards?
- nats.net - Missing async methods for PullSubscriptions
- nats.go - Message acknowledgement with external subsystems
💡 Recently asked questions
Questions sourced from Slack, Twitter, or individuals. Responses and examples are in my own words, unless otherwise noted.
How can I model an interested-based retention policy on a stream for N consumers?
A stream can be configured with a retention policy referred to as interest-based which states:
Messages are kept as long as there are Consumers active for them.
What does this mean in practice? If we consider the base case of zero consumers and a message is written to the stream, what do you think will happen? The message is discarded immediately.
What if we add one consumer to the stream and then write a message? The message will be retained even if there is no active subscription. The server knows there is a consumer, but the message has not yet been consumed, so it keeps the message.
Once the message is consumed (push or pull), the message is removed. This effectively acts as a work queue for a single consumer.
If two or more consumers are added, the message is not removed until all consumers consume the message (ack or term).
One up front design decision that needs to be made are the set of consumers. In other words, if a new one is added later, it won't have access to the historical messages if all of the other consumers ack'ed them.
How can I get the last sequence that was ack'ed by a consumer?
ConsumerInfo contains this information along with quite a bit of other info. Using Go, this can fetched as follows:
nc, _ := nats.Connect(...) js, _ := nc.JetStream() info, err := js.ConsumerInfo("stream-name", "consumer-name")
Can NATS be a replacement for gRPC for intra-service communication?
Yes, and this is a core use case of NATS. There are a number of articles on the Web (and linked in previous releases of this newsletter) as well a book that goes in depth about how to build a microservices platform on top of NATS.
The NATS website has a comparison matrix with a handful of related technologies including gRPC. In my opinion, comparing these two technologies is a bit apples to oranges, but I understand from a use case standpoint "which tech is better for microservices?" can lead to concrete discussion.
The term "better" is, generally, the wrong word to use. All tech that has solutions to overlapping use cases should be evaluated based on the trade-offs the tech or you, the user, need to consider.
I would argue the primary value-add of gRPC is the code generation. As a developer, you need to write some IDL and then run the protobuf compiler with the proper language extensions configured. You will get stubs for the server-side and working code for the client-side. Implement the server-side stubs and package up the client-side code for each language, and you can ship a working API.
If you find the value of code generation high and/or if you need to support many client languages, you may want to check out the nats-rpc GitHub org which provides protobuf-based code generation and use NATS as the transport layer.
A common argument that is made when comparing the two technologies is that NATS is lower-level. I agree it is which has pros and cons depending on the level of abstraction you or your team are comfortable working with.
However, if we compare the capabilities and relative simplicity, NATS as the basis for microservice communication is significantly more robust and extensible than the point-to-point interactions that gRPC offers (which uses HTTP/2 under the covers).
The comparison matrix highlights a handful of these points, but I would argue NATS is on a whole other playing field than gRPC at the protocol level. There is a common fallacy among the software industry that a successful "Quick Start" guide, a great demo, or a tech giant successfully using technology is a good indicator to maintainability, evolvability, or operational success. 🤷🏻♂️ It isn't.