A JMeter JMS Point-to-Point request_reply sampler times out although replies reach the reply queue. What do you check?
answer
- The broker is not the suspect here
- Two sides of one key, set separately
- Both boxes ticked is rarely right
- Elapsed time pinned at the timeout
basics
~20 sCheck the two correlation checkboxes under Use alternate fields for message correlation. JMeter files each reply under one id and waits on another; if they disagree the reply is discarded and the sample fails with No reply message received.
solid answer
~50 sWith a **JNDI name Receive queue** filled in, JMeter runs one background receiver on that queue and matches replies to waiting requests through a shared registry keyed by an id. Which id depends on the checkboxes under **Use alternate fields for message correlation**. **Use Request Message Id** ticked makes the waiting thread key on the request's `JMSMessageID`, unticked on its `JMSCorrelationID`. **Use Response Message Id** ticked makes the receiver file each reply under the reply's own `JMSMessageID`, unticked under its `JMSCorrelationID`. A service that copies the request's message id into the reply's correlation id therefore needs **Use Request Message Id only**; ticking both files the reply under an id nobody is waiting on, it is dropped, and the thread waits out the **Timeout** — `2000` ms by default — and reports `No reply message received`.
code
xml · 11 lines<JMSSampler guiclass="JMSSamplerGui" testclass="JMSSampler" testname="Order-Reply" enabled="true">
<stringProp name="JMSSampler.queueconnectionfactory">ConnectionFactory</stringProp>
<stringProp name="JMSSampler.SendQueue">dynamicQueues/ORDERS</stringProp>
<stringProp name="JMSSampler.ReceiveQueue">dynamicQueues/ORDER_REPLIES</stringProp>
<boolProp name="JMSSampler.useReqMsgIdAsCorrelId">true</boolProp>
<boolProp name="JMSSampler.useResMsgIdAsCorrelId">false</boolProp>
<stringProp name="JMSSampler.timeout">2000</stringProp>
<stringProp name="JMSSampler.initialContextFactory">org.apache.activemq.jndi.ActiveMQInitialContextFactory</stringProp>
<stringProp name="JMSSampler.contextProviderUrl">tcp://localhost:61616</stringProp>
<intProp name="JMSSampler.communicationStyle">1</intProp>
</JMSSampler>go deeper
Recall that Request Response matching depends on message ids, and that a timeout with replies visible on the queue points at correlation rather than at the broker.
Explain what each of the two correlation checkboxes selects and which combination fits a service that echoes the request's message id.
Demonstrate the diagnosis: recognise the timeout-shaped elapsed time, ask what the service puts in the reply, and use a temporary reply queue as the control experiment.
Own the convention: which correlation pattern the organisation's services implement, so test plans and services are not each guessing at the other's contract.
This is the classic JMS Point-to-Point failure on an order pipeline: the order service is demonstrably replying, you can browse the reply queue and see the messages, and every JMeter sample still fails after almost exactly two seconds. Nothing is wrong with the broker. JMeter is waiting on one key and filing replies under another. ## What Request Response actually sets up The **Communication style** dropdown offers five values: `request_only`, `request_reply`, `read`, `browse` and `clear`. With `request_reply` the behaviour splits on whether **JNDI name Receive queue** is filled: - **Left empty** — JMeter uses a temporary queue per request. The reply comes back on a private destination, so nothing has to be correlated and the sending thread simply blocks until the reply arrives or the timeout expires. - **Filled in** — JMeter starts a background receiver on that shared queue. Every arriving reply is filed in a process-wide registry under a key; every waiting sampler thread parks on a latch registered under its own key. A match releases the latch. No match, and the reply is logged at debug level and thrown away. The whole failure mode lives in that second arrangement, and it is the one teams pick because temporary queues are often disallowed in shared environments. ## The two checkboxes They are not a pair of styles; they name the two sides of the key independently. | Setting | Key used by the waiting thread | Key the receiver files replies under | |---|---|---| | both unticked | request's `JMSCorrelationID` | reply's `JMSCorrelationID` | | Use Request Message Id only | request's `JMSMessageID` | reply's `JMSCorrelationID` | | Use Response Message Id only | request's `JMSCorrelationID` | reply's `JMSMessageID` | | both ticked | request's `JMSMessageID` | reply's `JMSMessageID` | The two patterns that appear in real services map onto the first two rows: 1. **Correlation-id pattern** — the caller sets a correlation id, the service echoes it. Untick both, and put the id into the request by adding a row named `JMSCorrelationID` to the sampler's **JMS Properties** table; JMeter special-cases that name and calls `setJMSCorrelationID` rather than setting an ordinary property. Leave it out and the sampler refuses to send at all, with `Correlation id is null. Set the JMSCorrelationID header.` 2. **Message-id pattern** — the caller sets nothing, the service copies the request's `JMSMessageID` into the reply's `JMSCorrelationID`. Tick **Use Request Message Id** only. Ticking both is only correct when request and reply are the same message — that is, when the send and receive queues are the same and you are measuring raw broker throughput rather than a service. ## The diagnosis, in order 1. Confirm the shape of the failure: `No reply message received`, and an elapsed time pinned at the **Timeout** value. The default is `2000` ms; `0` means wait forever, which turns the symptom into a hang instead. 2. Ask what the service puts in the reply. That single answer picks the row of the table above. 3. Check the checkboxes against it, and remember they are independent — a plan converted from an older one often carries both ticked. 4. If both are unticked, confirm the request actually carries a correlation id via the **JMS Properties** table. 5. If the queues are shared with other JMeter runs or other consumers, consider a **JMS Selector** so the receiver only accepts replies meant for this run. 6. As a control, blank the receive queue and let JMeter use a temporary queue. If the sampler starts passing, correlation was the problem and not the service. ## Things worth knowing before you tune anything - The registry that matches replies is a single shared object in the JVM, so a mismatch does not fail loudly — it just leaves a latch that nobody releases. - The sample is created as failed and only turned successful when a reply is matched, so a discarded reply always shows as a failure and never as a suspiciously fast pass. - A reply that has not arrived inside the timeout fails that sample, and the late reply is then discarded: the waiting entry is removed from the registry when the thread gives up. - `request_only` sidesteps all of it, because it never waits for anything.
- How do you put a correlation id on the request when both correlation checkboxes are unticked?Add a row to the sampler's **JMS Properties** table named `JMSCorrelationID`. JMeter special-cases that name and calls `setJMSCorrelationID` on the message instead of setting an ordinary string property, because some providers refuse to let that header be set as a property. Without it the sampler throws `Correlation id is null. Set the JMSCorrelationID header.` before sending.
- What changes if you leave the JNDI name Receive queue empty?JMeter switches to a temporary queue per request. The reply comes back on a destination only that request knows about, so no correlation is needed and the checkboxes stop mattering. The sending thread blocks until the reply or the timeout. It is the cleanest control experiment, but many shared brokers disallow temporary queues.
- Which Communication style would you use to check a queue's depth without consuming anything?`browse`. It reports the current number of messages on the queue and leaves them in place, unlike `read`, which consumes, and `clear`, which removes everything. It is a useful setUp or tearDown step around an order-queue run, and it does not need a reply queue at all.
It is a coat check with two ticket books in use. You keep a stub with the request's number; the cloakroom staples the coat to a ticket bearing the reply's own number. Both slips are real, neither matches, and you stand at the counter until closing time.
saying these in an interview costs you the question
- Blaming the broker when the elapsed time equals the timeout exactly
- Treating the two correlation checkboxes as one setting
- Raising the timeout instead of fixing the correlation key
- Expecting a correlation id without a JMSCorrelationID property row
- Assuming an unmatched reply raises a visible error