Complete redo after much interesting discussion. This time not trying
to stay close to existing router configuration, but the intent is to
reflect existing router functionality using simpler terminology and
config. For simplicity I use "address" as if we were dealing with
fixed-string addresses only. I will follow up with a more detailed
proposal for pattern matching, prefixes etc.
I only have a single "address" per route but you can define linked
"half routes" to give different semantics in each direction. I think
this is more flexible and simpler, also it avoids words like "ingress"
and "egress" :)
This is just a high-level user outline of the config with simple
examples, hopefully it gives the idea.
===========
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 links 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 # TODO allow it to use an acceptor also,
how to identify connections?
mode="link"
}
Example: broker integration with message routing (replaces simple
waypoint)
indirectRoute {
address: my_queue # TODO address patterns.
connector: my_broker
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 address *and* allows that link
type. A route with `"allow": "none"` is an internal routing detail and
cannot be accessed directly by clients. Internal links use an
internalAddress to identify routes which is independent from the
"address" that clients use.
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
}
Aside: since we are creating internal links between routes to handle
the complex cases, we *might* be able to do internal link-routing.
Needs thought.
On Tue, 2016-02-23 at 22:40 +0000, Gordon Sim wrote:
> On 23/02/16 19:56, Gordon Sim wrote:
> > I like both your and Alan's attempts to simplify/unify the
> > configuration. I do think 'provisioned' is too opaque a name
> > though.
> > What about 'route' with types 'simple', 'link' or 'path'?
>
> Or thinking about it a little more:
>
> route: {
> type: broadcast | anycast | link | detour | mixed,
> address: the address or prefix,
> bias: spread | close (not relevant for 'broadcast' routes)
> connector: connection details for establishing connection
> to external process; specifying this implies that
> the router should establish a connection and links
> when needed to route messages/links for this
> address (multiple connectors can be sepcified),
> container: AMQP container-id of external process to which links
> should be established as necessary in order to route
> links/messages,
> ingress_type: broadcast | anycast | link //relevant only for
> 'detour' and 'mixed' routes
> egress_type: broadcast | anycast | link //relevant only for
> 'detour' and 'mixed' routes
> ingress_source: address to which messages entering the
> router network are routed;
> egress_target: address used for messages which should be
> exiting the router network
> }
>
> So simple, message routed, direct routes would be e.g.
>
> route: {
> type: anycast,
> address: foo
> }
>
> Meaning messages addressed to 'foo' (whether by the target address
> of
> the link on which they arrived or the to field in the body itself)
> would
> be distributed between links whose source address is also 'foo'.
>
> route: {
> type: broadcast,
> address: bar
> }
>
> Meaning messages addressed to 'bar' (whether by the target address
> of
> the link on which they arrived or the to field in the body itself)
> would
> be forwarded to all links whose source address is also 'bar'.
>
> Link routing would be configured like this:
>
> route: {
> type: link,
> address: abc
> connector: mybroker
> }
>
> connector: {
> name: mybroker,
> host: myhost.acme.com,
> port: 5678
> }
>
> Meaning any link established with target or source address abc, will
> be
> link routed to the broker identified by 'mybroker', with the router
> establishing a connection for the link as needed. An alternative
> would
> be e.g.:
>
> route: {
> type: link,
> address: abc
> container: mybroker
> }
>
> Meaning any link established with target or source address abc, will
> be
> link routed over any existing connection whose container-id is
> 'mybroker'. If no such connection existed, then the 'upstream' link
> would be detached.
>
> A simple 'queue' address might be:
>
> route: {
> type: detour,
> address: myqueue,
> connector: mybroker
> }
>
> connector: {
> name: mybroker,
> host: myhost.acme.com,
> port: 5678
> }
>
> Meaning messages addressed to 'myqueue' (whether by the target
> address
> of the link on which they arrived or the to field in the body
> itself),
> when entering the router network, will be routed to 'myqueue' on
> 'mybroker', and consumers with 'myqueue' as their source address will
> be
> routed messages from 'myqueue' on 'mybroker'. The router will
> establish
> links to and from the broker, as well as a connection over which
> these
> links are established, as necessary to achieve this.
>
> You could also have simply:
>
> route: {
> type: detour,
> address: myqueue
> }
>
> Messages addressed to 'myqueue' when entering the router network,
> would
> be routed to any link whose source address was myqueue-ingress.
> Messages
> addressed to myqueue-egress would be distributed between links whose
> source was myqueue. This would allow for the case where links were
> established by the broker.
>
> More control over 'detour' routes could be achieved by specifying
> some
> of the other attributes e.g.:
>
> route: {
> type: detour,
> address: mytopic,
> egress_type: broadcast,
> connector: mybroker
> }
>
> connector: {
> name: mybroker,
> host: myhost.acme.com,
> port: 5678
> }
>
> Which would route all messages addressed to 'myqueue' when entering
> the
> router network to mytopic on mybroker. Messages received from mytopic
> on
> mybroker would however be delivered over all links whose source
> address
> was mytopic.
>
> Or:
>
> route: {
> type: detour,
> address: myplace,
> ingress_source: to_myplace,
> egress_target: from_myplace
> }
>
> Which would route all messages addressed to 'myplace' when entering
> the
> router network, to any link whose source address was 'to_myplace'.
> Messages addressed to 'from_myplace' would be distributed between
> links
> whose source address was 'myplace'.
>
> You could also define 'mixed' routes, e.g.
>
> route: {
> type: mixed,
> address: my_sharded_queue,
> ingress_type: link,
> egress_type: anycast,
> egress_target: xyz
> connector: [broker1, broker2]
> }
>
> connector: {
> name: broker1,
> host: host1.acme.com,
> }
>
> connector: {
> name: broker2,
> host: host2.acme.com,
> }
>
> Here, any link established to the router network with target address
> 'my_sharded_address' would be link routed to one or other of the
> brokers
> defined by the two connectors. Messages addressed to 'xyz' would be
> distributed between any links whose source was 'my_sharded_queue'
> (i.e.
> message routed)
>
> ---------------------------------------------------------------------
> 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]