jakartaee / messaging

Jakarta Messaging
https://eclipse.org/ee4j/messaging
Other
41 stars 33 forks source link

Define how messages from a topic are delivered to clustered application server instances #73

Open glassfishrobot opened 12 years ago

glassfishrobot commented 12 years ago

This issue was raised on the JMS forum: https://forums.oracle.com/forums/thread.jspa?threadID=2124417 and is being logged here on behalf of that contributor

How many times are topic messages delivered ?

This may seem to be a trivial question, but when clustering is involved, it's not.

JEE has strong support for clustering, but many JEE specifications do not define what is actually supported, and leaves room for application server specific features. This is the case for JMS in the various specifications involved (JMS, JEE, EJB, JCA).

The question is how many times are messages delivered and treated (e.g. once per cluster or once per application server)?

Note that to simplify the problem I will not address selectors, delivery modes or acknowledgement considerations. I will also only address business application clustering, not JMS implementation clustering.

When Queues are used the situation is quite clear, the message is delivered once whether you use clustering or not. But when Topics are used, there is no simple answer.

When a message is sent to a Topic, each currently active non-durable subscriber should receive the message once. If the receiving application is clustered, the message should be received one time per application server instance in the cluster. That's what we get with JBoss 4.2.3.

This is actually not always the case. One example with WebSphere 6.1:

  • A business application is deployed to a cluster of two application servers
  • The JMS message engine is also deployed to a cluster of two application servers
  • The application uses a MDB with a non-durable subscription to a Topic
  • A message is sent to that Topic If the two clusters are different, then the message is received by one MDB on each application instance, so the message is treated twice. But if the two clusters are actually the same, then the message is only received by one MDB instance on the application server where the message engine instance runs, so the message is treated once instead of twice. Painful.

For reliability considerations, enterprise applications often use durable subscriptions to Topics. This makes the situation even more complicated.

Durable subscriptions are identified by a subscription name. This defines the number of deliveries, meaning that the message should be delivered once per distinct subscription name.

JMS offers three ways to receive messages: Message Driven Beans (MDB), synchronous receptions using MessageConsumer:receive and explicit message listeners using MessageConsummer:setMessageListener. We won't address message listeners as they are forbidden on the server side by the JEE specifications.

When doing synchronous receptions or message listeners, the durable subscription name is managed by the developper using Session:createDurableSubscriber. This way it is possible (it is actually required by the JMS specification) to give a different name per application instance in the cluster to choose the number of times the messages are received.

With MDB we cannot officially manage the subscription name, so there is not portable control of the number of messages delivery. Note that we cannot manage the client ID either. In more details, both client ID and subscription name are valid parameters as per the JCA specification, but they are not according to the EJB specification.

We need precise, portable and cluster compliant semantics about the number of time JMS messages get delivered.

Affected Versions

[1.1]

glassfishrobot commented 6 years ago
glassfishrobot commented 12 years ago

@glassfishrobot Commented Reported by @nigeldeakin

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: The JMS 2.0 public draft (Jan 2013) specified a new feature called "subscription scope" to address this issue. This was configured using a new MDB activation property subscriptionScope. The activation properties clientId and subscriptionName were also amended to support this new feature. Here's the text that the public draft contained:

MDB Activation properties

| Activation property | Description | | clientId | This property may be used to specify the client identifier that will be used when connecting to the JMS provider from which the endpoint (message-driven bean) is to receive messages.

Setting this property is always optional. If subscriptionScope is set (to Instance or Cluster) then this property must not be set. | | subscriptionName | This property only applies to endpoints (message-driven beans) that receive messages published to a topic. It may be used to specify the name of the durable or non-durable subscription.

If subscriptionScope is not set and the subscriptionDurability property is set to NonDurable then the subscriptionName property may be left unset.

If subscriptionScope is set (to Instance or Cluster) then the subscriptionName property may be left unset. A suitable subscription name will be generated automatically if needed.

If subscriptionScope is set to Instance and the subscriptionName property has been specified then the value of the subscriptionName property will be used as part of the subscription name.

If subscriptionScope is set to {[Cluster}

] and the subscriptionName property has been specified then the value of the subscriptionName property will be used as the subscription name.

| | subscriptionScope | The subscriptionScope property only applies to message-driven beans that receive messages published to a topic. It applies to both durable and non-durable subscriptions, as specified using the subscriptionDurability property.

Setting the subscriptionScope property is optional. If this property is set then it must be set to either Instance or Cluster.

For both durable and non-durable subscriptions, setting this property allows the deployer to specify the scope of the subscription that will be used.

instance scope

If the scope is Instance then the resource adapter will create a separate topic subscription for each application server instance into which the message-driven bean is deployed.

cluster scope

If the scope is Cluster, and the message-driven bean is deployed into a clustered application server, then the resource adapter will create a single shared topic subscription for the entire cluster. If the scope is Cluster, and the application server is not clustered, then the resource adapter will create a separate topic subscription for each application server instance into which the message-driven bean is deployed.

Generation of subscription name

The resource adapter will generate a suitable subscription name in the cases where a shared subscription is used.

If the scope is Instance, the subscriptionDurability is Durable and the subscriptionName property has been specified then the resource adapter will use the subscriptionName property as part of the subscription name.

If the scope is {[Cluster}}, the {{subscriptionDurability}] is Durable and the subscriptionName property has been specified then the the resource adapter will use the subscriptionName property as the subscription name. In this case the deployer is responsible to ensuring that the specified subscriptionName is unique to this cluster.

Client identifier

If the subscriptionScope property is specified then clientId must not be specified. Otherwise a deployment error will occur. |

Implementation of topic subscriptions

This section contains some additional recommendations as to how the specified ActivationSpec properties should be used in a resource adapter implementation.

When subscriptionScope is not specified

This section applies if the subscriptionScope property is not specified.

It is not defined whether a subscriptionDurability of NonDurable should be implemented using a shared or unshared non-durable subscription. If an unshared durable subscription is used then any subscriptionName specified will be ignored.

It is also not not defined whether a subscriptionDurability of NonDurable should be implemented using a shared or unshared durable subscription.

When subscriptionScope is set to Cluster

This section applies if the subscriptionScope property is set to Cluster.

It is recommended that a subscriptionDurability of NonDurable be implemented using a shared non-durable subscription.

It is recommended that a subscriptionDurability of Durable be implemented using a shared durable subscription.

If the message-driven bean is deployed into a clustered application server, then the subscription name that is generated should be the same for the same endpoint in each application server instance within the cluster but otherwise unique.

When subscriptionScope is set to Instance

This section applies if the subscriptionScope property is set to Instance.

It is not defined whether a non-durable subscription should be implemented using a shared or unshared non-durable subscription, or whether a durable subscription should be implemented using a shared or unshared durable subscription.

If the subscriptionScope property is set to instance, and the message-driven bean is deployed into a clustered application server, then the subscription name that is generated must be different for every endpoint and for every application server instance.

When subscriptionScope is set to Instance or Cluster

This section applies if the subscriptionScope property is set to either Instance or Cluster.

It is recommended that the subscription name that is generated includes a unique identifier to ensure that it is unique across other clusters or across other application server instances that are not part of the cluster.

If the application server instance into which the message-driven bean is deployed is not part of a cluster, then that the subscription name that is generated must be must be different for every endpoint and for every application server instance.

In this case it is recommended that the subscription name that is generated includes a unique identifier to ensure that it is as unique as possible across all application server instances.

Requirements for generated subscription names

The subscription name generated by the resource adapter must be a valid JMS subscription name. This means that it must be no longer than 128 characters and must consist only of Java letters or digits (as defined in the Java Language Specification) or the underscore (_), dot (.) or minus characters.

Since a durable subscription can be used to store messages indefinitely it is recommended that its name remains unchanged even if the application server is restarted or reconfigured, or if the application is redeployed.

Since a subscription name may be visible to the user or administrator it is recommended that the subscription name is at least partly human-readable.

Implementation in a resource adapter

The Java EE Connector Architecture (JCA) specification defines a method getInstanceName on javax.resource.spi.BootstrapContext and a method getActivationUniqueName on MessageEndpointFactory. If a scope of Cluster is specified then a suitable subscription name may be obtained by calling the getActivationUniqueName method. If a scope of Instance is specified then a suitable subscription name may be obtained by calling the getInstanceName and getActivationUniqueName methods and concatenating the results.

However if the subscriptionName property and the subscription is durable then the value of this property should be used instead of the value returned by getActivationUniqueName.

The term "application server instance" as used in this section refers to a single application server JVM. The exact meaning of the term "application server cluster" as used in this section is left to the application server to define but is intended to refer to a group of co-operating application server JVMs to which an identical Java EE application may be deployed.

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: For the reasons described here and here this feature has been dropped from JMS 2.0 and deferred until a later version of JMS.

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: Tagged for review for JMS 2.1

glassfishrobot commented 11 years ago

@glassfishrobot Commented @nigeldeakin said: Removing "fix version=2.0" as this issue was removed from the spec

glassfishrobot commented 12 years ago

@glassfishrobot Commented Issue-Links: blocks JMS_SPEC-103

glassfishrobot commented 7 years ago

@glassfishrobot Commented This issue was imported from java.net JIRA JMS_SPEC-73