SAMM - Service Adapter for MQTT Microservices
217
SAMM is a building block for creating MQTT enabled microservices. SAMM connects to an MQTT message bus, subscribes to your topics and forwards the received messages to your custom processors stdin in JSON - one message == one line. If your processor wants to emit a message, you only need to write a JSON line to stdout.
The SAMM architecture implements a separation of concern:
SAMM will execute your service processor as a continuously running subprocess establishing communication to your processor via its stdin/out/err pipes.
| +-------------------------------------------------+
M| | samm starts subprocess |
Q| | +---------------------+ |
T| | | processor | |
T| | | | |
+-----> subscribe ------> stdin | |
+-----< publish <------ stdout | |
B| | <------ stderr | |
U| | +---------------------+ |
S| +-------------------------------------------------+
[^binaries]
SAMM comes with an extra binary for bridge mode - sammbridge - which allows for easy bridging of subscribed messages from MQTT_LISTENER_URL to MQTT_PUBLISHER_URL.
The Dockerfile serves as an example on how to make use of this image in your multistage microservice builds. Find the Docker image here: https://hub.docker.com/r/flaneurtv/samm/
docker pull flaneurtv/samm
The message schema should look like that but is not enforced. The only required field is "topic", which MUST NOT contain these characters: # +
We recommend to make your service as generic as possible, which also applies to the topic you choose for message publishing. Make sure to prepend the generic topic with $NAMESPACE_PUBLISHER env variable, to allow for personalisation. $NAMESPACE_LISTENER is used when SAMM subscribes to messages. There is two, so you can receive messages from Bus A but publish results to Bus B. Could also be used to build a message bridge, but we provide a special executable for this very purpose.
{
"topic": "$NAMESPACE_PUBLISHER/$YOURTOPIC",
"service_uuid": "$SERVICE_UUID",
"service_name": "$SERVICE_NAME",
"service_host": "$SERVICE_HOST",
"created_at": "$CREATED_AT",
"payload": {
}
}
{
"log_level": "debug",
"log_message": "$TICK_UUID $TICK_TIMESTAMP",
"created_at": "$CREATED_AT"
}
* Contrary to this layout, message must be formatted as a one-liner terminated by a newline but without newlines in between.
{
"username": "username",
"password": "password"
}
A few examples are contained in this repository. The Dockerfile by default creates a container spinning up an echo-sender service, which - when hooked up to an MQTT broker - will echo everything you send to topic "default/test" back on topic "default/log/test".
A more complex and integrated examples can be spun up using the docker-compose-*.yml files.
docker-compose -f docker-compose-demo.yml build
docker-compose -f docker-compose-demo.yml up
A message bus for communication allows us to loosely couple services in a one-to-many manner. Neither at the time of writing a service, nor at any time in production does a service have to know, who will consume its data.
We have chosen MQTT publish and subscribe message bus protocol, as it is lightweight and MQTT broker implementations are performant and scalable. Moreover it provides both a TCP socket and a Websocket interface.
We are only utilizing QOS 0, as we follow an non deterministic approach to message delivery in our own service architecture. We count on messages being lost and account for this on a different architectural level, thereby making out infrastructure more tolerant to errors. Additionally, only using the most basic MQTT features makes us more protocol independant, as this minimal feature set is supported in a wide range of other message bus protocols as well.
We follow a Convention over Configuration approach. Configuration files - such as subscription.txt - and also the processor file need to reside in certain locations to be started without further configuration needed. Configuration is only necessary, if you deviate from the norm.
Content type
Image
Digest
Size
15.1 MB
Last updated
over 7 years ago
docker pull flaneurtv/samm