On 02/25/2016 03:57 PM, Alan Conway wrote:
I like this a lot.
The directional terms are still a problem. "source/sink" clashes with
AMQP "source/target". "inTreatment/outTreatment" is confusing because
"treatment" covers message and link treatments, but they don't always
flow in the same direction. E.g.
outTreatment: linkBalanced
"out" refers to *outbound* messages, but "linkBalanced" means balance
the *inbound* receiver link-open requests across external servers. This
made my head hurt.
"out" refers to the outbound leg of the route. In this case it means
that messages flow out from the topic via links established by the
consumers.
I have been fiddling around trying to find something genuinely better
but not there yet. I've got a couple of thoughts but not concrete yet:
- separate message and link treatments in "treatment". This is clearer
but redundant and multiplies the number of in/out settings.
I think there's real value in having treatment be one-dimensional for
simplifying the configuration.
- if you need separate in/out treatments, split the waypoint into a
source/sink pair for the same address. That is less confusing because
the "half-route" only has one message flow direction so no need for
inFoo/outFoo. It makes the config a little more verbose but this is a
complex use case.
I prefer the second for clarity and future-proofing. It means we can
add future options that might be set differently for inbound/outbound
without multiplying inFoo/outFoo, inBar/outBar on the route.
This makes sense to me. It significantly reduces the number of
attributes of a route and still keeps the most common cases simple.
On Wed, 2016-02-24 at 16:06 -0500, Ted Ross wrote:
Ok, how about this?
For direct messaging between producers and consumers:
Direct multicast delivery (one copy to every subscriber to the
address):
route {
address: service.mcast
type: direct
treatment: multicast
}
Direct delivery to only the closest (lowest cost) subscriber:
route {
address: service.regional
type: direct
treatment: closest
}
Direct delivery to one subscriber favoring subscribers that settle
deliveries more quickly.
route {
address: service
type: direct
treatment: balanced
}
For messaging involving a queue, topic, or other intermediate
process.
In these cases, the remote container may be identified by container-
id
or connection label (container-id shown in examples):
Link-routing to a queue:
route {
address: my_queue
type: waypoint
treatment: linkBalanced
container: <broker-container-id>
}
Link-routing only for enqueue:
route {
address: my_queue
type: sink
treatment: linkBalanced
container: <broker-container-id>
}
Link-routing only for dequeue:
route {
address: my_queue
type: source
treatment: linkBalanced
container: <broker-container-id>
}
Simple queue waypoint (treatment defaults to 'balanced'):
route {
address: my_queue
type: waypoint
container: <broker-container-id>
}
Simple topic waypoint that supports selectors:
route {
address: my_topic
type: waypoint
inTreatment: multicast
outTreatment: linkBalanced
container: <broker-container-id>
}
Distributed (sharded) queue waypoint:
route {
address: my_queue
type: waypoint
container: <broker-1-container-id>
}
route {
address: my_queue
type: waypoint
container: <broker-2-container-id>
}
Distributed (sharded) topic waypoint:
route {
address: my_topic
type: waypoint
inTreatment: multicast
outTreatment: linkBalanced
container: <broker-1-container-id>
}
route {
address: my_topic
type: waypoint
inTreatment: multicast
outTreatment: linkBalanced
container: <broker-2-container-id>
}
=====================================================================
Syntax:
route: {
type: direct | source | sink | waypoint
address: (address or prefix)
treatment: multicast | closest | balanced | linkBalanced
connector: (label of a connection to/from a remote container)
container: (ID of a connected remote container)
inTreatment: (override treatment for inbound traffic)
outTreatment: (override treatment for outbound traffic)
inAddress: (override address for inbound traffic)
outAddress: (override address for outbound traffic)
}
Some notes:
- I don't care for the negative connotations of "detour" and prefer
"waypoint" for describing a thing you must go through on your way
to
the final destination.
- I've replaced "fanout" + "bias" with "treatment" to describe how
the
router handles the forwarding of messages. There is precedent for
the use of this term (hat tip to Andy Smith) in Cisco's router
documentation.
- Link-routing is just another kind of treatment, like multicast or
closest-consumer. This removes the need for the "mixed" route as
described by Gordon. It also removes any distinction between a
waypoint and a link-route-destination as a link-route-destination
simply becomes a waypoint with linkBalanced treatment.
- I'm avoiding Alan's distinction between direct and indirect routes
by
noting that "direct" is the only direct option whereas the other
types are indirect.
- The notion of "direction" is replaced by the "source" and "sink"
route types.
-Ted
On 02/24/2016 09:18 AM, Alan Conway wrote:
Minor update attached - I included Gordon's point about indirect
routes
being able to use a listener to accept an incoming broker
connection as
well as a connector to make an outgoing one, the new part:
----
Indirect routes can use incoming connections from the external
application by specifying a `listener` instead of a `connector` and
an
AMQP `container` name to identify the external application.
indirectRoute {
address: my_queue # TODO address patterns.
listener: secure_broker_listener
container: "mybroker-container-id"
mode="message"
}
----
Here's the full thing:
===========
Terminology
===========
AMQP messages are sent on *links*. A link that sends messages from
an
application to a dispatch router is a *sender*. A link that
receives
messages for an application from a dispatch router is a *receiver*.
Dispatch router configuration defines *routes*. A route has an
*address*. Addresses can be AMQP address strings or patterns (TODO)
Incoming client links (senders or receivers) are attached to the
route
with a matching address. If a sender link has no address, messages
are
routed individually using the *to* address. Receiver links with no
address are not allowed.
There are several types of route:
A *directRoute* accepts sender and receiver links and forwards
messages
from senders to receivers. This allows clients to communicate
directly
without the need for a broker.
Example: direct route "foo" with fanout (replaces fixedAddress)
"directRoute": { "address": "foo", "fanout": "multiple" }
An *indirectRoute* creates links to an external application (such
as a
broker) and forwards messages from senders to the application, and
messages from the application to receivers. There are two modes:
- message routing: the route creates its own links to the
external
application, there is no relationship with the sender/receiver
links.
- link routing: the route creates external links that correspond
exactly with sender/receiver links. It forwards all link
information
(name, flow control, properties etc.) to the external application.
Link routing preserves more AMQP context between the client and the
external application. Message routing offers more flexibility to
modify
the message flow e.g. to load balance messages over multiple
brokers.
An indirectRoute can initiate a connection to the external
application
or accept an incoming connection from it.
Example: broker integration with link routing (replaces
linkRoutePattern)
indirectRoute {
address: my_queue # TODO address patterns.
connector: my_broker
mode="link"
}
Example: broker integration with message routing (replaces simple
waypoint)
indirectRoute {
address: my_queue # TODO address patterns.
connector: my_broker
mode="message"
}
Indirect routes can use incoming connections from the external
application by specifying a `listener` instead of a `connector` and
an
AMQP `container` name to identify the external application.
indirectRoute {
address: my_queue # TODO address patterns.
listener: secure_broker_listener
container: "mybroker-container-id"
mode="message"
}
For more complex cases routes can create links to other routes.
Routes
always allow internal links, but a route can be configured to allow
only senders, receivers, both or none from outside. An external
link is
attached to the route that has the right its address *and* allows
that
link type. A route with `"allow": "none"` is an internal routing
detail
and cannot be accessed directly by clients.
Example: waypoint chaining
# Route for messages sent to my_queue, forward to broker1
indirectRoute {
address: my_queue
allow: sender
connector: broker1
mode: message
}
# Internal route for messages coming back from broker1,
forward to
broker2
indirectRoute {
address: my_queue
allow: none # internal only
connector: broker1
internalSender: ["broker2"] # send to broker2
mode: message
}
# Route messages through broker2 and then back to receivers.
indirectRoute {
internalAddress: "broker2"
connector: broker2
allow: receiver
mode: message
}
Example: message-routing with load balancing over two brokers.
# Route for senders to my_queue.
directRoute {
address: my_queue
allow: sender
internalSenders: ["broker1_my_queue", "broker2_my_queue"]
fanout: multiple
}
# Route for receivers from my_queue.
directRoute {
address: my_queue
allow: receiver
internalReceivers: ["broker1_my_queue",
"broker2_my_queue"]
}
# Internal route to broker1
indirectRoute {
internalAddress: broker1_my_queue
allow: none
connector: broker1
}
# Internal route to broker2
indirectRoute {
internalAddress: broker2_my_queue
allow: none
connector: broker2
}
TODO:
- indirect route with multiple listeners/connectors with/without
container name giving multiple choices of external apps. Policy
controol: link routes can't fan-out but they can load balance.
- mix link & message routes: "tap" messages from a link route and
message route them.
- pattern matching
- internal address rewriting?
- multi-tennant
-----------------------------------------------------------------
----
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]