activemq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Howard Gao <howard....@gmail.com>
Subject [DISCUSS] Artemis FQQN(Full Qualified Queue Name) implementation
Date Thu, 06 Apr 2017 03:41:42 GMT
So I've been doing this FQQN support (ARTEMIS-1093) and I'd like
to share my thoughts and current implementations of key functionalities,
as well as some concerns. I'd appreciate any comments
and adivces to make it better.

More details about FQQN concepts please see official doc:
https://github.com/apache/activemq-artemis/blob/master/docs/user-manual/en/address-model.md#fully-qualified-queue-names

Simply put, a FQQN takes form of <address>::<queue name>. It uniquely
and explicitly identifies a 'queue' entity within a broker. With FQQN
any clients can have access to any 'core' queues, so long as the addresses
and queue names are known to them.

For example, if a core queue "q1" is deployed on address "address1", its
FQQN would be "address1::q1". A JMS consumer can receive messages that
routed
to "q1" by referencing the queue directly using its FQQN, as illustrated
in the following code snippet:

...
Queue q1 = session.createQueue("address1::q1");
MessageConsumer consumer1 = session.createConsumer(q1);
Message m = consumer1.receive(2000);
...

Before FQQN, clients using any protocols only can access a queue by its
name, which must be unique across all addresses within a broker. If we
implement FQQN based on this uniqueness restriction, we don't need change
any internal bindings management code. Simply removing the address prefix
(like "address1::" in FQQN "address1::q1") from client requests and every
thing would work just fine.

However, with FQQN in place it is possible that queues of same names can be
created on different addresses while still won't lose their uniqueness.
For example, "address1::q1" and "address2::q1" are two distinct queues and
can perfectly live within a broker together. In this case, a client trying
to access one of the queues can't just simply specify the queue name "q1".
Because the broker wouldn't know which queue it refers to (ambiguity).

To solve this issue, I need to add some 'extra' logic to the existing
binding management. Here is what I do:
(PR: https://github.com/apache/activemq-artemis/pull/1172 )

1. Inside broker it used a map (SimpleAddressManager.nameMap) to store
bindings (queues) and the keys are queue names. As queue names will no
longer be guaranteed to be unique with FQQN, a composite key (BindingKey)
is introduced so that the address part of the queues will paticipate in
key 'hash' and 'equals' calculation.

2. In order to detect 'ambiguous' binding queries, a new map called
uniqueNameMap is added to SimpleAddressManager to keep the number of
addresses a binding is bound to. For example if a queue "q1" is bound to
both addresses "address1" and "address2", the number stored in this map for
"q1" is 2 ("q1"->2).

When a binding is added these two maps gets updated.
To understand how it works consider the following scenarios:

In all of the scenarios below suppose the broker have 3 queues
"address1::q1", "address1::q2", "address2::q1"

[Scenario 1] A client comes in requesting access to a queue by its name
"q2".
Broker first checks the uniqueNameMap and finds that there is only
one binding for this queue name, no ambiguity, and it goes ahead to
get the binding from nameMap and returns it.

[Scenario 2] A client comes in requesting access to a queue by its FQQN
"address2::q1". Because FQQN is used we don't need to check ambiguity
this time. it therefore goes directly to find the binding in nameMap
and returns it.

[Scenario 3] A client comes in requesting access to a queue by its name
"q1".
Because there are two bindings (queues) bound to different addresses and
client doesn't use FQQN, broker checks the uniqueNameMap and finds that
there are more than one (two in this case) bindings exists by the same
queue name, in which case it can't determine which one is the one needed.
So it gives a warning message and returns null result.

Some concerns with my implementation:

1) Although the logic seems straightforward, but the actual code looks
like a bit too complex, as some folks pointed out. I'm currently seeking
a way to make it simple. Probably separating it into smaller tasks?

2) String manipulations (like concat() and String/SimpleString conversions)
added performance cost. Need a way to minimize the impact.

Again any comments are welcomed.

Thanks,
Howard

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message