Hi Alexey,
Thanks. I will look at Grizzly 2.0 and will try that.
The keep-alive is enabled between client and haproxy, but is disabled between haproxy and grizzly. Haproxy and grizzly are on the same LAN (well, technically they are in EC2 VPC), so the connection is quite fast. Closing the connection lets us reuse threads on grizzly side. Also, we manipulate and load balance requests using haproxy, so we treat each request separately and can't enable a keep-alive directly from client to grizzly.
Vivek
Date: Mon, 24 Oct 2011 15:19:36 +0200
From: oleksiy.stashok_at_oracle.com
To: users_at_grizzly.java.net
Subject: Re: Concurrent connections using Grizzly/Jersey
Hi Vivek,
Our threads make external web service calls and make some
expensive DB queries. So, they are often in the waiting state
like sleep(1000). We are testing the max threads under
production load and trying to find the best number.
I see.
I looked around some Grizzly source code and noticed that
there is an internal queue for managing requests which have
not been allotted a thread. How can we configure the queue
size and other queue properties?
You mean the task queue, where threads picking up tasks from?
Please take a look at queueLimit parameter
http://grizzly.java.net/nonav/docs/docbkx2.0/html/core-config.html#threadpool-config
Though there is no clean way to set it up in Grizzly Web server
1.9.x.
Would you mind to switch to 2.x? Please check Jersey samples, they
have Jersey + Grizzly 2.x samples as well.
Our application is behind haproxy load balancer, which
disables keep alive. So, our Java app doesn't need to have
keep alive. I disabled keep alive in Java as I believed that
we will get performance gain since Haproxy when forwarding the
request adds Connection: Close to the request.
haproxy disable keepalive in client <-> haproxy communication
or haproxy <-> server? If earlier - then keep-alive still
makes sense imo.
Thanks.
WBR,
Alexey.
Regards,
Vivek
Date: Fri, 21 Oct 2011 15:43:58 +0200
From: oleksiy.stashok_at_oracle.com
To: users_at_grizzly.java.net
Subject: Re: Concurrent connections using Grizzly/Jersey
Hi Vivek,
Answering my own email. We were
able to fix it and scale to 50 worker threads by using
the following code snippet
You're right, by increasing the thread-pool size you can
increase number of requests Jersey/Grizzly will be able to
process simultaneously.
Though it makes sense only if request processing is
expensive (like in your case sleep(1000)), otherwise we
recommend to keep thread-pool size = number of CPU/cores.
It's similar to how Scott suggests to configure Glassfish
[1], see "Tune the HTTP threads" section.
Also I'd not recommend to set
grizzlyWebServer.getSelectorThread().setMaxKeepAliveRequests(0);
it's going to disable HTTP keep-alive mechanism, which may
have significant impact on server perf.
Thanks.
WBR.
Alexey.
[1]
http://weblogs.java.net/blog/sdo/archive/2007/12/a_glassfish_tun.html
GrizzlyWebServer
grizzlyWebServer = new GrizzlyWebServer(8080);
grizzlyWebServer.getSelectorThread().setMaxKeepAliveRequests(0);
grizzlyWebServer.setCoreThreads(30);
grizzlyWebServer.setMaxThreads(50);
ServletAdapter
jerseyAdapter = new ServletAdapter();
jerseyAdapter.addInitParameter("com.sun.jersey.config.property.packages",
"com.test");
jerseyAdapter.setServletInstance(new
ServletContainer());
grizzlyWebServer.addGrizzlyAdapter(jerseyAdapter,
new String[]{"/"});
grizzlyWebServer.start();
Please
let me know if we can embed grizzly while using
jersey in a better way.
Thanks,
Vivek
>
To: users_at_grizzly.java.net
> From: bird_sky_at_hotmail.com
> Subject: Concurrent connections using
Grizzly/Jersey
> Date: Thu, 20 Oct 2011 21:18:11 +0000
>
> Hi,
>
> We are embedding Grizzly in our code and are
facing concurrent
> connections in production. We are unable to
scale beyond 7-8 concurrent
> requests. I believe the problem lies in the way
we are using Grizzly
> and appreciate any help you can offer. I am
able to replicate the
> problem with the following sample code.
>
> Please suggest what we are doing wrong and how
can we use grizzly to
> scale up to many more concurrent requests.
>
> ==========Main.java==========
> import com.sun.grizzly.http.SelectorThread;
> import
com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
> import java.io.IOException;
> import java.util.HashMap;
> import java.util.Map;
> public class Main {
> public static void main(String[] args) throws
InterruptedException
> {
> Map<String, String> initParams=new
HashMap<String, String>();
>
initParams.put("com.sun.jersey.config.property.packages",
> "com.test");
> try {
> SelectorThread threadSelector =
> GrizzlyWebContainerFactory.create("http://localhost:8080/",
> initParams);
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
> }
> ========Default.java=========
> package com.test;
> import javax.ws.rs.GET;
> import javax.ws.rs.Path;
> import javax.ws.rs.Produces;
>
> @Path("{path:.*}")
> public class Default {
> @GET
> @Produces( "text/plain" )
> public String getMessage() {
> try {
> // Adding sleep to simulate some background
processing
> Thread.sleep(1000);
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> return "Hello World";
> }
> }
> =========================