Routing Swiftlet
Overview
The Routing Swiftlet is responsible for inter-router communication and message routing in a SwiftMQ router network. It manages the establishment of routing connections, the exchange of routing information, and the forwarding of messages between routers using efficient, transactional, and optionally XA-compliant protocols. The Swiftlet supports both static and dynamic routing, advanced route filtering, and robust connection management for high-availability and scalable messaging topologies.
Features
Routing Connections (Listeners and Connectors)
The Routing Swiftlet establishes and manages TCP connections between routers using two main entities: listeners and connectors. Listeners define inbound connection endpoints, specifying the local port, optional bind address, authentication password, buffer sizes, and other network parameters. Connectors define outbound connections to remote routers, specifying the remote hostname, port, authentication, and connection retry behavior. Each connection can be configured for TCP options, compression, and XA (2-phase commit) support. Listeners can restrict inbound connections by IP address using a host access list. Both listeners and connectors support fine-tuning of transactional parameters such as inbound transaction size and window size for optimal throughput and flow control.
Host Access List
Listeners can restrict inbound connections to specific IP addresses or hostnames by maintaining a host access list. This list can be dynamically updated, and only connections from allowed hosts will be accepted.
Wire-Level Compression
Both listeners and connectors can enable wire-level compression for routing traffic, reducing bandwidth usage at the cost of additional CPU overhead.
XA (2-Phase Commit) Support
Routing connections can participate in distributed transactions using the XA protocol. This ensures atomic delivery of messages across routers in transactional scenarios.
Configuration Example:
<swiftlet name="sys$routing">
<listeners>
<listener name="main-listener" port="4001" password="secret"/>
</listeners>
<connectors>
<connector name="to-router2" hostname="router2-host" port="4001" enabled="true"/>
</connectors>
</swiftlet>
Static and Dynamic Routing
The Routing Swiftlet supports both static and dynamic routing of messages between routers. Static routes are explicitly defined in the configuration and ensure that a route to a specific destination router is always available, regardless of dynamic route discovery. Dynamic routes are established automatically as routing connections are formed and route information is exchanged. The Swiftlet maintains a routing table reflecting all known routes, and updates it as connections are added or removed. Route propagation is controlled by a configurable hop limit to prevent routing loops and excessive route announcements.
Static Routes
Static routes are defined under the static-routes entity. Each static route specifies a destination router name. When a static route is present, the Swiftlet ensures a persistent routing path to the specified router.
Dynamic Route Exchange
Dynamic routes are discovered and exchanged automatically between routers. The Swiftlet uses a protocol handshake to exchange route information and update the routing table in real time.
Route Announce Hop Limit
The maximum hop count for route announcements is controlled by the route-announce-hop-limit property. This prevents excessive propagation of route information and limits the size of the routing table.
Configuration Example:
<swiftlet name="sys$routing">
<static-routes>
<static-route name="router2"/>
<static-route name="router3"/>
</static-routes>
</swiftlet>
Route Filtering
Route filters allow fine-grained control over which routes are announced to or accepted from specific routers. Filters can include or exclude routes based on the last hop or the destination router. Each filter is associated with a set of routers and a filter type, such as include_by_hop, exclude_by_hop, include_by_destination, or exclude_by_destination. This enables administrators to control the propagation of routing information and enforce network segmentation or security policies.
Filter Types
Available filter types are: - include_by_hop: Only routes whose last hop is in the specified router list are sent. - exclude_by_hop: Routes whose last hop is in the specified router list are excluded. - include_by_destination: Only routes whose destination is in the router list are sent. - exclude_by_destination: Routes whose destination is in the router list are excluded.
Configuration Example:
<swiftlet name="sys$routing">
<filters>
<filter name="router2" type="exclude_by_hop">
<routers>
<router name="router3"/>
</routers>
</filter>
</filters>
</swiftlet>
Transactional Message Routing
The Routing Swiftlet supports transactional message delivery between routers, with optional support for XA (2-phase commit) transactions. Each routing connection negotiates transaction and window sizes, and messages are transferred in batches for efficiency. The protocol ensures reliable delivery, duplicate detection, and flow control. Inbound flow control can be enabled to throttle message intake based on downstream router capacity. XA recovery is handled automatically in the event of failures, ensuring distributed transaction integrity across the router network.
Inbound Flow Control
When enabled, inbound flow control dynamically throttles the rate of incoming messages to prevent overload and ensure smooth message flow across routers.
Keepalive and Connection Health
Routing connections use periodic keepalive messages to detect and close stale or failed connections, ensuring high availability and fast failover.
Configuration Example:
<swiftlet name="sys$routing" inbound-flow-control-enabled="true"/>
Unroutable Message Handling
Messages that cannot be routed to their intended destination (due to missing routes, unavailable connections, or other errors) are placed in the unroutable queue. This queue is created automatically by the Routing Swiftlet and can be monitored for operational issues or misconfigurations. The unroutable queue is named unroutable@
Job Integration for Connector Management
The Routing Swiftlet integrates with the scheduler/job system to allow dynamic activation and deactivation of routing connectors. The 'Routing Connector' job type can start or stop a connector by name, enabling automated or scheduled changes to the router network topology.
Challenge/Response Authentication
Routing connections can be protected with password-based challenge/response authentication. The challenge/response factory class used for authentication can be customized via the crfactory-class property. This mechanism ensures only authorized routers can establish routing connections.
Configuration Example:
<swiftlet name="sys$routing" crfactory-class="com.swiftmq.auth.MyCustomCRFactory"/>
Internal Queue Naming
rt$<destination-router>@<local-router>— Routing queue for store-and-forward to a specific destination router. Each destination router has a dedicated routing queue.unroutable@<routername>— Queue for messages that cannot be routed to their destination. Used for operational monitoring and troubleshooting.
Configuration Guide
Enable Round Robin Scheduling for Outbound Routing
Use this scenario when you want to distribute outbound messages evenly across multiple routing connections to the same destination router. Round robin scheduling helps balance load and improve throughput in multi-connection topologies.
- Set the roundrobin-enabled property to true in the Routing Swiftlet configuration.
- Restart the router for the change to take effect.
<swiftlet name="sys$routing" roundrobin-enabled="true"/>
Restrict Inbound Routing Connections to Specific Hosts
Use this scenario to limit which remote routers can connect to your router by IP address or hostname, enhancing security.
- Edit the listener entity for your routing listener.
- Add allowed hostnames or IP addresses to the host-access-list.
<swiftlet name="sys$routing">
<listeners>
<listener name="main-listener" port="4001">
<host-access-list>
<host-access-entry name="192.168.1.10"/>
<host-access-entry name="router2.example.com"/>
</host-access-list>
</listener>
</listeners>
</swiftlet>
Define a Static Route to a Remote Router
Use this scenario to ensure a persistent route to a remote router, even if dynamic route discovery is unavailable or restricted.
- Add a static-route entity under the static-routes list with the destination router's name.
<swiftlet name="sys$routing">
<static-routes>
<static-route name="router2"/>
</static-routes>
</swiftlet>
Apply a Route Filter to Limit Route Announcements
Use this scenario to prevent certain routes from being announced to or accepted from specific routers, for network segmentation or policy enforcement.
- Define a filter entity under filters with the desired type (e.g., exclude_by_destination).
- List the routers to which the filter applies.
<swiftlet name="sys$routing">
<filters>
<filter name="router2" type="exclude_by_destination">
<routers>
<router name="router3"/>
</routers>
</filter>
</filters>
</swiftlet>
Scheduler Jobs
Routing Connector
Description: Activates a Routing Connector
Configuration Reference
The top-level entity in routerconfig.xml is <swiftlet name="sys$routing">.
<swiftlet name="sys$routing"> Properties
These properties are attributes of the <swiftlet name="sys$routing"> entity.
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
reject-disconnect-delay |
Long | 5000 |
No | No | Time (ms) after which a rejected Connection is closed (min: 1000) |
stage-valid-timeout |
Long | 15000 |
No | No | Time (ms) after which a Protocol Stage in a wait State becomes invalid (min: 1000) |
roundrobin-enabled |
Boolean | false |
No | Yes | Enables/Disables Round Robin Scheduling |
inbound-flow-control-enabled |
Boolean | false |
No | Yes | Enables/Disables Inbound Flow Control |
crfactory-class |
String | com.swiftmq.auth.ChallengeResponseFactoryImpl |
No | Yes | Challenge/Response Factory Class |
route-announce-hop-limit |
Integer | 3 |
No | No | Maximum Hop Count for Route Announce (-1 = unlimited) |
<swiftlet name="sys$routing" reject-disconnect-delay="5000" stage-valid-timeout="15000" roundrobin-enabled="false" inbound-flow-control-enabled="false" crfactory-class="com.swiftmq.auth.ChallengeResponseFactoryImpl" route-announce-hop-limit="3"/>
<static-routes> in <swiftlet name="sys$routing">
Static Route Definitions
Each <static-route> entry is identified by its name attribute (the Static Route).
<swiftlet name="sys$routing">
<static-routes>
<static-route name="..."/>
</static-routes>
</swiftlet>
<filters> in <swiftlet name="sys$routing">
Route Filter Definitions
Each <filter> entry is identified by its name attribute (the Route Filter).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
type |
String | — | Yes | No | Filter Type (choices: include_by_hop, include_by_destination, exclude_by_hop, exclude_by_destination) |
<swiftlet name="sys$routing">
<filters>
<filter name="..." type="..."/>
</filters>
</swiftlet>
<routers> in <filters>
Routers to filter
Each <router> entry is identified by its name attribute (the Router to filter).
<swiftlet name="sys$routing">
<filters>
<filter name="...">
<routers>
<router name="..."/>
</routers>
</filter>
</filters>
</swiftlet>
<listeners> in <swiftlet name="sys$routing">
Listener Definitions
Each <listener> entry is identified by its name attribute (the Listener).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
bindaddress |
String | — | No | No | Listener Bind IP Address |
port |
Integer | — | Yes | No | Listener Port |
use-tcp-no-delay |
Boolean | true |
Yes | No | Use Tcp No Delay |
socketfactory-class |
String | com.swiftmq.net.PlainSocketFactory |
No | No | Listener Socketfactory Class |
password |
String | — | No | No | Password |
keepalive-interval |
Long | 60000 |
No | No | Interval for sending Keep Alive Messages |
inbound-transaction-size |
Integer | 20 |
No | No | Number of Messages per Transaction |
inbound-window-size |
Integer | 10 |
No | No | Max. Number of open Transactions |
router-input-buffer-size |
Integer | 131072 |
No | No | Router Network Input Buffer Size (min: 65536) |
router-input-extend-size |
Integer | 65536 |
No | No | Router Network Input Extend Size (min: 65536) |
router-output-buffer-size |
Integer | 131072 |
No | No | Router Network Output Buffer Size (min: 1024) |
router-output-extend-size |
Integer | 131072 |
No | No | Router Network Output Extend Size (min: 1024) |
use-compression |
Boolean | false |
No | No | Uses Wirelevel Compression if enabled |
use-xa |
Boolean | true |
No | No | Uses 2 Phase Commit Protocol (XA) if enabled |
<swiftlet name="sys$routing">
<listeners>
<listener name="..." port="..." use-tcp-no-delay="..."/>
</listeners>
</swiftlet>
<host-access-list> in <listeners>
Host Access List
Each <host-access-entry> entry is identified by its name attribute (the Host Access Entry).
<swiftlet name="sys$routing">
<listeners>
<listener name="...">
<host-access-list>
<host-access-entry name="..."/>
</host-access-list>
</listener>
</listeners>
</swiftlet>
<connectors> in <swiftlet name="sys$routing">
Connector Definitions
Each <connector> entry is identified by its name attribute (the Connector).
| Parameter | Type | Default | Mandatory | Reboot Required | Description |
|---|---|---|---|---|---|
hostname |
String | — | Yes | No | Remote Hostname |
enabled |
Boolean | true |
No | No | Enables/Disables this Connector |
port |
Integer | — | Yes | No | Remote Port |
use-tcp-no-delay |
Boolean | true |
Yes | No | Use Tcp No Delay |
socketfactory-class |
String | com.swiftmq.net.PlainSocketFactory |
No | No | Connector Socketfactory Class |
password |
String | — | No | No | Password |
retry-time |
Long | 60000 |
No | No | Retry Time (min: 1000) |
inbound-transaction-size |
Integer | 20 |
No | No | Number of Messages per Transaction |
inbound-window-size |
Integer | 10 |
No | No | Max. Number of open Transactions |
router-input-buffer-size |
Integer | 131072 |
No | No | Router Network Input Buffer Size (min: 65536) |
router-input-extend-size |
Integer | 65536 |
No | No | Router Network Input Extend Size (min: 65536) |
router-output-buffer-size |
Integer | 131072 |
No | No | Router Network Output Buffer Size (min: 1024) |
router-output-extend-size |
Integer | 131072 |
No | No | Router Network Output Extend Size (min: 1024) |
use-compression |
Boolean | false |
No | No | Uses Wirelevel Compression if enabled |
use-xa |
Boolean | true |
No | No | Uses 2 Phase Commit Protocol (XA) if enabled |
<swiftlet name="sys$routing">
<connectors>
<connector name="..." hostname="..." port="..." use-tcp-no-delay="..."/>
</connectors>
</swiftlet>
Changelog
13.0.2 (2024-05-06)
- Modified DefaultScheduler
- RouteImpl: added null check; Modified RoundRobinScheduler
13.0.1 (2024-04-23)
- DefaultScheduler: added error handling, added null check