tilln / jmeter-iso8583

ISO8583 Plugin for JMeter
MIT License
62 stars 32 forks source link

Is there a way to send messages without waiting for the response? #45

Closed barspi closed 2 years ago

barspi commented 2 years ago

Maybe there's a way to do it with jmeter but I haven't found it.

I would like to configure the iso8583 plugin, so it sends N messages through each thread/connection without necessarily waiting for the response/timeout.

Then, as responses start coming, the MUX would match them (and somehow inform of the time delta to the listeners). It may put a heavy load on the local MUX, but that's what they're for!

Bonus points: a way to throttle those messages (such as sending 1 every x milliseconds, without waiting for the response, of course).

tilln commented 2 years ago

I think the typical approach for measuring response times (your "time delta" between request and response) is via using JMeter threads that synchronously wait for the responses. Each JMeter thread then just transparently interacts with the MUX.

Not sure why you would want to do it asynchronously (other than of course to overcome a capacity limitation if you need too many JMeter threads).

There are several JMeter components you can use to control the throughput, such as sending one request "every x milliseconds". Apart from plugins there are for example the core components Constant Throughput Timer and Precise Throughput Timer.

These "Timers" are meant to "delay" each request statically or dynamically, e.g. by a fixed amount of time or just as much as needed to achieve the desired throughput. Here is a general write-up on Timers.

Then there are more sophisticated components as well such as the "Throughput Shaping Timer" plugin (see here and here).

If you really want to send a message without waiting for a response you could specify a Sampler Timeout value zero though that would have the MUX ignore/discard the response as well AFAIK.

Unless you have any more question I suggest you close this as this is not a plugin issue but related to general use of JMeter.

barspi commented 2 years ago

Thank you for the response. I saw those timer components but haven't found the time to study them yet. I promise I will! (and I even thought about having the timeout set to 0... but then it would defeat the purpose of having time stats about responses)

Still, this solution [I think] doesn't 100% cover what I want to attempt .

If we want to load test a jPOS system (listening on a QServer and using a TransactionManager for example), currently the only way to do it from JMeter is by multiplying the number of connections (JMeter threads).

That is one dimension of the behavior (a QServer with hundreds of incoming connections), but typical systems may have 1 single-persistent-connection through which hundreds of messages may come form the remote end, one after the other (without waiting for responses), and then responses start coming back asynchronously (or not... some of them may never arrive in time). All using a single connection/socket/thread.

This could be accomplished from JMeter's side using the asynchronous version of MUX#request() : http://jpos.org/doc/javadoc/org/jpos/iso/MUX.html#request-org.jpos.iso.ISOMsg-long-org.jpos.iso.ISOResponseListener-java.lang.Object-

When the response comes back to the callback listener ISOResponseListener, through its responseReceived or expired methods, then we would inform JMeter that the response arrived/timed-out (I have no idea how you inform JMeter of that... I know ZERO about JMeter internals, but you're the guru here!! :-) )

So, my vision is to be able to configure the JMeter Thread Group with N threads, and M samples for each thread. And then, the ISO8583 Connection Configuration component could have a checkbox such as "Use asynch MUX" (if it's unchecked, then it's the old behavior).

With an asynch MUX, the M samples for each thread would be sent "as fast as we can" (or throttled by one of those Timer component that you suggested) and responses are processed as they arrive or time-out, in which order they happen (nothing guarantees they would arrive in the same order, as in real systems).

barspi commented 2 years ago

Sorry for the long message above. I hope my point is more clear now. If you still think this is 100% solvable by current JMeter tricks, or you don't feel like implementing it, please close the issue. I would do it and contribute to the project but currently don't have time to learn all JMeter internals

tilln commented 2 years ago

Hi @barspi

I think I understand your point now, however, allow me to challenge some of your assumptions first:

If we want to load test a jPOS system (listening on a QServer and using a TransactionManager for example), currently the only way to do it from JMeter is by multiplying the number of connections (JMeter threads).

[...] but typical systems may have 1 single-persistent-connection through which hundreds of messages may come form the remote end [...]

The ISO8583 Connection Configuration element has a field "Reuse Connection" that determines whether a persistent connection is used (which is the default setting).

This single connection is maintained by the QBean (Q2Server or ChannelAdaptor) on the JMeter side and is shared between all JMeter threads, so "multiplying the number of connections" does not happen when increasing the number of JMeter threads.

When the response comes back to the callback listener ISOResponseListener, through its responseReceived or expired methods, then we would inform JMeter that the response arrived/timed-out [...]

[...] responses are processed as they arrive or time-out, in which order they happen

The plugin uses the QMUX capabilities to match request and response, which you would lose and have to reimplement when sending asynchronously as you are suggesting.

So, I still think this is "solvable by current JMeter tricks" until you convince me otherwise :-)

barspi commented 2 years ago

Oh.. I got it the other way around! All this time I was thinking that each thread (configured at the Thread Group level) would open its own connection instead of what you told me (and just tested it), that they all share a common connection.

So what's missing now is a way to have multiple persistent connections :-)

But this is not as bad as I thought... because using many jMeter threads we can simulate lots of simultaneous messages coming in through the same socket.

Still not 100% what I had in mind, with asynchronous responses, but last night I spent poking around your code for awhile and googling a little bit, and now I'm afraid that JMeter's invocation model does not easily support asynchronous sample request/responses. There are some plugins that were created for ajax or other http async flows but that's the limit of my understanding.

The plugin uses the QMUX capabilities to match request and response, which you would lose and have to reimplement when sending asynchronously as you are suggesting.

The async MUX call still uses the QMUX matching capabilities, and you can receive, for example, the request ISOMsg (or other metadata) in the handback Object by your callback methods.
But, as I said above, the JMeter model may not be thought out as being used in this way.

Thanks for your time. Although this is not doing exactly what I would like yet, the situation is not as bad :-)

(close this issue if you want, or keep it open as a friendly reminder)

tilln commented 2 years ago

So what's missing now is a way to have multiple persistent connections

True, there is no direct way with this plugin.

You could use multiple ISO8583 Connection Configurations with a single persistent connection each.

Unless the Channel has a setting to configure the number of concurrent connections to use?

no-response[bot] commented 2 years ago

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.