We have a simple performance test flow in an application.
We login
Search based on some criteria
repeat searches for different parameters.
We are using Jmeter to do a performance testing. We need to have multiple threads running to test this in a scalable manner.
The way we currently have this arranged is:
-Test Plan
- Thread Group
- Cookie Manager
- Login To application
- Search on param 1
- Search on param 2
- results summary table
- Summary report
So basically we have summary return table and report present on plan level while cookie manager is present on thread group level.
When I run for one thread it runs fine and completes well. When I scale it to multiple threads, as soon as the next thread kicks off, the session for the last thread is invalidated. This causes failures for all the already running threads due to newly spawned thread.
I reached this result with observation:
1. If I run multiple threads, only last thread has got valid responses in result summary tree
2. If I run with 2 threads with ramp up period as 10 seconds, which means each thread gets time to finish itself, then both of them run successfully.
As per my understanding each thread login's into application and since cookie manager is at thread level, the values will be maintained for session id for each thread respectively? But what is causing the override of the session id value between threads?
Any help will be much appreciated.
Copied from jmeter documentation:
The last element is a HTTP Cookie
Manager . A Cookie Manager should be
added to all web tests - otherwise
JMeter will ignore cookies. By adding
it at the Thread Group level, we
ensure that all HTTP requests will
share the same cookies.
From chapter "4.2.2 Logic Controllers" in http://jmeter.apache.org/usermanual/test_plan.html.
EDIT: I guess you should use http://jmeter.apache.org/usermanual/component_reference.html#Simple_Controller to group your requests together with Cookie Manager.
I think that Andrey's answer cannot help. He quotes that each request will use the same cookies BUT according to jmeter manual:
Each JMeter thread has its own "cookie storage area".
As far as I understand the question, you want each thread to share the same session ID cookie. So it seems to me you need to have two thread groups and execute them consecutively. First thread group (with a single thread that executes once only) should login and save the session cookie value to a global parameter (perhaps you need to use jmeter's scripting capabilities).
Then set that cookie in the cookie manager of the second thread group.
Hope that helps.
Try to increase the ramp up time. I ran into the same issue where the ramp up time was about 1 second then I increased it to 3 seconds per thread and it ran fine.
Try this:
Open the user.properties present in the bin folder of JMeter
Edit it and add the following line:
CookieManager.check.cookies=false
Save it and run the script. I hope it will solve your problem.
First change your code to:
jmeter.properties
CookieManager.save.cookies=true
CookieManager.name.prefix=mycookie_
Next, add a HTTP cookie manager in the same thread group as your java sampler.
Then in your java sampler add:
JMeterVariables jmv = JMeterContextService.getContext().getVariables();
Iterator<Map.Entry<String,Object>> it = jmv.getIterator();
while(it.hasNext()){
Map.Entry<String,Object> v = it.next();
System.out.println("name: " + v.getKey() + " value: " + v.getValue());
}
Related
I'm dealing with the Tomcat configuration on springboot.
Let's supposse i have the following configuration:
server:
tomcat:
min-spare-threads: ${min-tomcat-threads:20}
max-threads: ${max-tomcat-threads:20}
accept-count: ${accept-concurrent-queue:1}
max-connections: ${max-tomcat-connections:100}
I have a simple RestController with this code:
public String request(#Valid #RequestBody Info info) {
log.info("Thread sleeping");
Thread.sleep(8000);
return "OK";
}
Then i make the following test:
I send 200 HTTP request per second.
I check the log and as I expected I see 100 simultaneous executions and after 8 seconds I see the last one (queued).
Other executions are rejected.
The main problem that i have with this is that if i have a timeout control on client call (for example, 5 seconds), the queued operation will be processed on server anyways even if it was rejected on client.
I want to avoid this situation, so I tried:
server:
tomcat:
min-spare-threads: ${min-tomcat-threads:20}
max-threads: ${max-tomcat-threads:20}
accept-count: ${accept-concurrent-queue:0}
max-connections: ${max-tomcat-connections:100}
But this "0" is totally ignored (i think in this case it means "infinite").
So, my question is:
¿Is it possible to configure Tomcat to don't queue operations if the max-connections limit is reached?
Or maybe
¿Is it possible to configure Tomcat to reject any operation queued?
Thank you very much in advance.
Best regards.
The value of the acceptCount parameter is passed directly to the operating system: e.g. for UNIX-es it is passed to listen. Since an incoming connection is always put in the OS queue before the JVM accepts it, values lower than 1 make no sense. Tomcat explicitly ignores such values and keeps its default 100.
However, the real queue in Tomcat are the connections that where accepted from the OS queue, but are not being processed due to a lack of processing threads (maxThreads). You might have at most maxConnections - maxThreads + 1 such connections. In your case it's 81 connections waiting to be processed.
In Jmeter I created 7 Threads to login multiple users.I put 7 usernames and 7 passwords in csv file then I created CSV Data set config in JMeter and it works well but when I start to test it shows fail 7 threads pls see the image.
My expectation is that you need to perform correlation of the SessionId parameter, like:
Add a relevant Post-Processor as a child of the first request (the recommended one for HTML response type is CSS/JQuery Extractor) and configure it to fetch SessionId value from the previous response
Substitute recorded value of 467132418 with the JMeter Variable originating form the Post-Processor in the subsequent request
Repeat steps 1 and 2 for all samplers where SessionId is being used
This might be a simple problem, but I can't seem to find a good solution right now.
I've got:
OldApp - a Java application started from the command line (no web front here)
NewApp - a Java application with a REST api behind Apache
I want OldApp to call NewApp through its REST api and when NewApp is done, OldApp should continue.
My problem is that NewApp is doing a lot of stuff that might take a lot of time which in some cases causes a timeout in Apache, and then sends a 502 error to OldApp. The computations continue in NewApp, but OldApp does not know when NewApp is done.
One solution I thought of is fork a thread in NewApp and store some kind of ID for the API request, and return it to OldApp. Then OldApp could poll NewApp to see if the thread is done, and if so - continue. Otherwise - keep polling.
Are there any good design patterns for something like this? Am I complicating things? Any tips on how to think?
If NewApp is taking a long time, it should immediately return a 202 Accepted. The response should contain a Location header indicating where the user can go to look up the result when it's done, and an estimate of when the request will be done.
OldApp should wait until the estimate time is reached, then submit a new GET call to the location. The response from that GET will either be the expected data, or an entity with a new estimated time. OldApp can then try again at the later time, repeating until the expected data is available.
So The conversation might look like:
POST /widgets
response:
202 Accepted
Location: "http://server/v1/widgets/12345"
{
"estimatedAvailableAt": "<whenever>"
}
.
GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
"estimatedAvailableAt": "<wheneverElse>"
}
.
GET /widgets/12345
response:
200 OK
Location: "http://server/v1/widgets/12345"
{
"myProperty": "myValue",
...
}
Yes, that's exactly what people are doing with REST now. Because there no way to connect from server to client, client just polls very often. There also some improved method called "long polling", when connection between client and server has big timeout, and server send information back to connected client when it becomes available.
The question is on java and servlets ... So I would suggest looking at Servlet 3.0 asynchronous support.
Talking from a design perspective, you would need to return a 202 accepted with an Id and an URL to the job. The oldApp needs to check for the result of the operation using the URL.
The thread that you fork on the server needs to implement the Callable interface. I would also recommend using a thread pool for this. The GET url for the Job that was forked can check the Future object status and return it to the user.
I am using Spring 4.0.2 for my Web Application. My Web Application is about file processing. There are some statues about files like "In Progress", "On Hold", "Completed". One user can complete multiple files, but only one at a time. So at a time only one file must be "In Progress" for a single user. Now, I want to check after every 15 mins whether is there any event occurred with particular file or not. If there is no event occurred, I want to change file status from "In Progress" to "On Hold". So that I tried to write Scheduler in Spring as given below.
#Scheduler(fixedDelay = 15*60*1000)
public void checkFrequently()
{
// here I am doing some operation to check for any event occurred in last 15 min or not.
// here, I need HttpSession for two purposes.
// 1. to get current logged in user
// 2. to get current file for current user
}
Is there any possibility to get session in this method? If it is impossible, what are the alternatives?
It is not possible. The scheduler is started at application launch, when there is no session, and runs in a thread separated from the servlet container.
Usually, you will persist in some form the states that you would like to make accessible by bean managed by the scheduler (being in a database, a plain file, a queue, etc...)
I am trying to benchmark SSL handshakes per second using a variety of tools, JMeter included. I have successfully created a test plan that meets my needs except I now want to test how the SSL handshakes per second compare with and without SSL session reuse. As I understand, by default Java has an unlimited size SSL session cache and entries expire after 24 hours.
I've tried using the JMeter properties "https.use.cached.ssl.context" and "https.sessioncontext.shared", but even when these properties are false it doesn't meet my needs. When both are false, the first HTTPS request in the thread uses a new session id, but each HTTPS request after that in the thread reuses a session id. Even if I set the undocumented Java property "javax.net.ssl.sessionCacheSize" to 1 to only allow one SSL session ID to be cached, if I have 10 threads making a total of 5 HTTP requests each, I see 10 new SSL session negotiated, and 40 SSL sessions reused (verified with ssldump and STunnel logs).
Is it possible through JMeter or Java to have every HTTPS request use a new SSL session id?
This works:
https.use.cached.ssl.context=false is set in user.properties
AND use either HTTPClient 3.1 or 4 implementations for HTTP Request
EDIT (after Kaelen comment):
Setting the https.use.cached.ssl.context property to false (with HTTPClient 3.1/4) does work, the only tricky part is that the SSL session context only gets reset at the end of an iteration of the Thread Group. In the test plan the thread group did not iterate, there was an infinite loop inside the group that ran until a # of requests occurred. Because the thread group never iterated, the SSL context wasn't reset.
In this case remove the Loop inside Thread Group and configure number of iterations in Thread Group.