changes through the data flow…” (wikipedia.org/wiki/Reactive_programming) § Microservices: “…small, lightweight services, where each performs a single function…arranged in independently deployable groups and communicate with each other via a well defined interface…” (davidmorgantini.blogspot.ch/2013/08/micro-services-what-are-micro-services.html)
changes through the data flow…” (wikipedia.org/wiki/Reactive_programming) § Microservices: “…small, lightweight services, where each performs a single function…arranged in independently deployable groups and communicate with each other via a well defined interface…” (davidmorgantini.blogspot.ch/2013/08/micro-services-what-are-micro-services.html) § Etc.
Architecture: “…decomposes a complex, event-driven application into a set of stages connected by queues…” (http://en.wikipedia.org/wiki/Staged_event-driven_architecture)
Architecture: “…decomposes a complex, event-driven application into a set of stages connected by queues…” (http://en.wikipedia.org/wiki/Staged_event-driven_architecture) § Message Bus (Message-‐Oriented Middleware): “…relies on asynchronous message-passing, as opposed to a request-response architecture…” (http://en.wikipedia.org/wiki/Message-oriented_middleware)
Routing a message to a user 2) Finding a message for a user § “PostofQice”: Routing a message internally in the nyt⨍aбrik Message nyt⨍aбrik Core Gateway Core Gateway
but “.” is reserved) – the 1st element is the “category” “category”: “feeds”, “2nd element”: “breaking-news” “3rd element”: “0012345” § The elements are joined by “.” for routing “path”: “feeds.breaking-news.00123456”
path denotes a sorted “folder” containing messages in reverse datetime order (using the timestamp from the version 1 uuid uniquely identifying each message) “feeds.breaking-news.56”/bd1961f5-1062-11e4-a630-406c8f1838fa “feeds.breaking-news.56”/b94e8b45-1062-11e4-900d-406c8f1838fa
path denotes a sorted “folder” containing messages in reverse datetime order (using the timestamp from the version 1 uuid uniquely identifying each message) “feeds.breaking-news.56”/bd1961f5-1062-11e4-a630-406c8f1838fa “feeds.breaking-news.56”/b94e8b45-1062-11e4-900d-406c8f1838fa § Subscribing to a path is done by “binding”, typically with wildcards: “*” matches any one element, “#” matches any sequence of elements All breaking-‐news messages: “feeds.breaking-news.#”
storage can be done by path, e.g. the “latest” breaking-‐news messages for item 56: “feeds.breaking-news.56” § But retrieval can also be done using trailing wild cards: “feeds.breaking-news.#” will return the “latest” breaking-‐news messages for all “current” items
storage can be done by path, e.g. the “latest” breaking-‐news messages for item 56: “feeds.breaking-news.56” § But retrieval can also be done using trailing wild cards: “feeds.breaking-news.#” will return the “latest” breaking-‐news messages for all “current” items § The Cassandra data store is designed to return hierarchical queries with a single request and in the desired order
and paths for retrieving persisted messages, including the use of wild cards, are the same, e.g.: When a user logs in she is “subscribed” using her ID; messages “published” to her will be received while “persisted” messages and subscription preferences are retrieved (a few 10’s of milliseconds)
and paths for retrieving persisted messages, including the use of wild cards, are the same, e.g.: When a user logs in she is “subscribed” using her ID; messages “published” to her will be received while “persisted” messages and subscription preferences are retrieved (a few 10’s of milliseconds) Once subscription preferences arrive, she will be “subscribed” to them and any corresponding “persisted” messages retrieved The same paths are used for subscription and retrieval
of them) have numeric IDs – using those IDs directly for routing, specigically for the “binding” function, would be inefgicient “id.prefs.09067832” (namespace of 3rd element is too large)
of them) have numeric IDs – using those IDs directly for routing, specigically for the “binding” function, would be inefgicient “id.prefs.09067832” (namespace of 3rd element is too large) § Instead we convert the ID to base62 elements and take advantage of the patricia trie search structures built into RabbitMQ and our gateway “id.prefs.c.2.x.M” (equivalent to the above, used for routing)
“bus” that connects all the services in all the nyt⨍aбrik instances globally § It is physically segmented and the segments are connected using RabbitMQ “shovels” and “federation” Gateway Core Gateway Gateway Core Gateway postoffice logical view
together as an ordered sequence like this: <action>.<from address>.<to address> “route.\ us-west-2.search.resolve.i-123.12.\ us-west-2.search.route.-.-”
together as an ordered sequence like this: <action>.<from address>.<to address> “route.\ us-west-2.search.resolve.i-123.12.\ us-west-2.search.route.-.-” § Meaning: This is a request for a “route” action from a specigic invocation of the “search” product “resolve” service addressed to any “search” product “route” service in region “us-‐west-‐2”
the postofgice using its unique address to get messages specigically directed to it, e.g. asynchronous RPC responses <any action>.<any address>.<my address> “*.\ *.*.*.*.*.\ us-west-2.search.route.i-123.12”
“binds” to the postofgice using addresses that will select messages appropriate for its service <my action>.<my domain>.<my service> “route.\ us-west-2.*.*.*.*.\ *.*.route.*.*”
“binds” to the postofgice using addresses that will select messages appropriate for its service <my action>.<my domain>.<my service> “route.\ us-west-2.*.*.*.*.\ *.*.route.*.*” § All this address manipulation is handled by common methods in the nyt⨍aбrik
a slow-witted human being I have a very small head” from "Notes on Structured Programming" (EWD249) § from ‘What Led to "Notes on Structured Programming”’ (EWD1308)
~50 small-ish instances in production 50 x $.13 / hr x 30 x 24 = $4680 / month § Other costs < $300 / month § Too much – targeting half that within a few months
latency routing, fast cache, etc. § Resilient: Yes active/active/… across multiple independent regions and zones § Scalable: Getting there algorithm is good, scaling up is fine, working on browser interaction, new automation tools (ansible) are being staged into production
than a product: § Replay “Building a Messaging Fabric” as a series of blog posts § Post the code on github as OSS § Take community contributions using other languages, message brokers, persistence stores, cloud providers, etc. § Let me know if there is interest!