qpid-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Fraser Adams <fraser.ad...@blueyonder.co.uk>
Subject Re: Instrumenting the Broker
Date Sat, 12 Jan 2013 13:46:04 GMT
On 11/01/13 22:36, Lance D. wrote:
> I love this discussion.  It's actually very helpful in getting a better
> grasp of where QPID fits into the bigger picture of the AMQP world.
> I'm going to inject a little more philosophical question into the nuance
> here.  I completely get what Andy said about the standard and it makes
> sense.  However, what frustrates me is that, as the API is implemented in
> QPID, internally QPID has access to exactly what I want, it was just
> overlooked or ignored when it comes to storing that detail.
So I think that you have to consider the difference between the API and 
what's actually going on on the wire and in the broker. That's 
specifically why I said in my earlier post that _the API_ can lead to 
the sort of confusion that we've both suffered.

The key thing is that if you want to *really* get under the skin of 
what's going on in your _system_ you have to consider the client 
application, the client runtime (e.g. the API implementation such as 
qpid::messaging or the JMS Impl) and the broker. If you only consider 
one of these you end up making assumptions which, when things end up not 
behaving as "expected", end up making diagnosing the problem a whole lot 

So in this case you need to realise that "the API is implemented in 
QPID" is really the client runtime environment that I refer to above. 
That API results in AMQP frames being sent over the wire. So whilst it's 
true to say that the client runtime has access to the information that 
we might want it's *not* true to extrapolate that to assuming that the 
broker has access to the same information. The broker and the client 
runtime talk to each other purely in AMQP terms which is why Andy is 
entirely correct to be talking in AMQP terms in terms of what 
information the QMF management objects maintained on the broker actually 
have access to. So I don't think your assertion "it was just overlooked 
or ignored when it comes to storing that detail." holds at all here.

As an aside another reason why I say it really helps to consider the 
system of systems relates to a scenario that I had when trying to 
understand why one of my brokers appeared to have a "memory leak". I'd 
employed consumer pre-fetching (which is what most people do for 
efficiency). What bit me was that it's the client *application* that 
does the acknowledgements, so when I had a slow consumer my broker used 
way more memory than I thought it should because I was using ring 
queues. What was actually going on though was that the broker also has 
to maintain references to messages that have been prefetched but not yet 
acknowledged (so it can resend them if the consumer fails). If you have 
lots of consumers that are slow relative to producers this can use way 
more memory than you "expect".

So it's a bit of a rambly aside but hopefully it illustrates why it's a 
good idea to consider the whole system. That scenario took me an 
absolute age to figure out so hopefully that little bit of advice gives 
you a leg up when you need to diagnose your own issues.

>    I say that
> because my tools can capture the connection events and collect enough
> detail that later I can see what publisher sent the message.  However, in
> order for that to work, my tools must be running before anyone connects;
> that is less useful for use debugging a large system of systems.
So my connection audit has a similar need to be running before anyone 
connects, the obvious approach is to start up qpidd from a script which 
also then fires up your QMF client.
> Aside from the standard's details that allow a connection to send to any
> queue,
A producer connection sends to exchanges not queues. Even in the case of 
the default direct exchange where the producer address "looks like" a 
queue name what's actually happening is that the message is getting sent 
to default direct exchange with the queue name as the binding key. 
That's another case of the APIs abstracting some of the detail away.

>   is there are reason that QPID doesn't keep some sort of mapping that
> maintains what was declared at connection time and/or the most recent
> destination?
As I said at the start of this mail that relates to the difference 
between the client run time and the broker, so the client runtime I 
suspect does "keep some sort of mapping that maintains what was declared 
at connection " 'cause when it does sender.send() it needs to find the 
session and connection associated with the sender, but once again the 
association that is formed in the client runtime translates to a 
*transient* association when the message is sent over the wire and 
that's all the broker has to work with - and it's the broker that 
maintains the QMF management objects.

So Qpid _as a system_ does conceptually have that mapping 'cause that's 
how the API works, but the Qpid broker does not, if you see what I mean?

Re "the most recent destination " I guess that what you really mean here 
is could the session object maintain some sort of exchangeRef in a 
similar way to the way subscription maintains a queueRef? It's an 
interesting thought because I suspect most use-cases are likely to 
involve producer connections publishing to a single exchange (or at 
least producer sessions doing that) so the "most recent association" 
might be useful. However I suspect it's an idea unlikely to gain any 
traction because it's pretending that what is really a transient 
association is really a full association (think in UML terms here) so 
the modeling is not accurate, moreover whilst in most cases the 
multiplicity between session and exchange is likely to be one it's 
really a zero to many transient association.

> Thanks and happy weekend folks!
> -Lance
> On Fri, Jan 11, 2013 at 12:39 PM, Fraser Adams <
> fraser.adams@blueyonder.co.uk> wrote:
>> Yes, with AMQP 0-10, the only time a producer indicates the destination of
>>> the message is when it actually sends the message. The message.transfer
>>> command includes the destination of the message, which is an exchange. A
>>> producer may send to various exchanges, simply by changing the destination
>>> in the message.transfer command with each message. As a result, from the
>>> broker's perspective, there's not really any way to look at a producer
>>> client and determine which exchange(s) it's sending to.
>>>   Thanks Andy that kind of makes sense.
>> I think that part of the confusion might stem from some of the higher
>> level APIs, I've only really used JMS and qpid::messaging (I've steered
>> well clear of qpid::client as recommended by Gordon and several others and
>> I know plenty of people who've been bitten by qpid::client which makes me
>> glad I did :-)).
>> So for qpid::messaging and JMS the model tends to be that one creates a
>> connection, then one creates a session and in general in qpid::messaging
>> one would create Senders specifying an address and in JMS similarly one
>> would create a MessageProducer. So I guess that it's fairly easy to
>> *assume* that the address (which in the case of a producer could just be
>> the exchange name for something like amq.match) is associated with the
>> Connection/Session.
>> if you normally do:
>> connection.open();
>> Session session = connection.createSession();
>> Sender sender = session.createSender("amq.**match");
>> ........
>> sender.send(message);
>> .........
>> it's easy to fall into that trap.
>> I guess that the alternate send which actually takes an address (e.g. the
>> JMS MessageProducer |*send <http://docs.oracle.com/**
>> javaee/5/api/javax/jms/**MessageProducer.html#send%**
>> 28javax.jms.Destination,%**20javax.jms.Message%29<http://docs.oracle.com/javaee/5/api/javax/jms/MessageProducer.html#send%28javax.jms.Destination,%20javax.jms.Message%29>
>>> *(**Destination <http://docs.oracle.com/**javaee/5/api/javax/jms/**
>> Destination.html<http://docs.oracle.com/javaee/5/api/javax/jms/Destination.html>>
>> destination, Message <http://docs.oracle.com/**javaee/5/api/javax/jms/**
>> Message.html <http://docs.oracle.com/javaee/5/api/javax/jms/Message.html>>
>> message)| ) is a closer analogue to the underlying AMQP message.transfer I
>> guess that the higher level abstraction just acts as a cache for the real
>> AMQP destinations.
>> Thanks again Andy I think that your explanation has helped clarify in my
>> mind the transient association between Connection and Exchange even though
>> I suspect in practice the vast majority of producer code is likely to be
>> written in a way that retains what looks like a more sustained association,
>> but that's only in the client runtime not in the broker.
>> Frase.

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