users@grizzly.java.net

Re: Concurrent connections using Grizzly/Jersey

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Mon, 31 Oct 2011 08:40:05 +0100

Hi Vivek,

> 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.
Well, TCP connect/accept is relatively expensive anyways, IMO you may
feel it on higher load.

> Closing the connection lets us reuse threads on grizzly side.
Hmm, when connection is idle it doesn't occupy any thread in Grizzly.

> 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.
IMO keeping connections alive is not directly related to load balancing
or treating requests separately.
You can look at keep-alive feature as some low-level TCP connection
cache, which is not even related to HTTP.

WBR,
Alexey.


>
> ------------------------------------------------------------------------
> 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 <mailto:oleksiy.stashok_at_oracle.com>
> To: users_at_grizzly.java.net <mailto: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 <mailto:users_at_grizzly.java.net>
> > From: bird_sky_at_hotmail.com <mailto: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/"
> <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";
> > }
> > }
> > =========================
>
>
>