Howard W. Smith, Jr. smithh032...@gmail.com wrote on 05/04/2013
21:22:33:
On Fri, Apr 5, 2013 at 9:07 AM, Anton Piatek1
anton.pia...@uk.ibm.comwrote:
I am seeing what at first appears to be a bug, but given the lack of
other
reports I can't believe I am the only person seeing this, so maybe it
is
user-error.
I have tomcat (was 7.0.30, but I just tried with 7.0.39) running a
website
which uses websockets. The websockets code in tomcat isn't that
complicated - My servlet returns a new subclass of StreamInbound which
has
overridden the onTextData() and onBinaryData() methods. This seems to
generally work fine, and I can send and receive data happily.
However when I load up several browser windows I find that tomcat
hangs. I
used jconsole to check the tomcat threads and found that as I open
each
new websocket, the tomcat worker threads go from idle threads waiting
for
work to the following busy, blocking threads waiting for websocket
data.
I have not written low-level websocket code as you are doing, but I
think I
have seen this behavior even in/with my app, and others have reported
and
discussed this issue in more ways than one.
I am using Atmosphere Framework via PrimeFaces Push to implement
websockets
in my app, and it does work well with one browser tab/window, but it is
commonly reported that websockets do not work when one client (machine)
has
multiple simultaneous websocket connections to the server.
Since I use Atmosphere Framework, I searched their google groups for the
following:
browser windows
and found the following (URL and quote from page at URL below):
https://github.com/Atmosphere/atmosphere/issues/493
According to HTTP RFC
http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html
:
Clients that use persistent connections SHOULD limit the number of
simultaneous connections that they maintain to a given server. A
single-user client SHOULD NOT maintain more than 2 connections with any
server or proxy.
This can cause problems if you have multiple tabs/window open, which all
maintain a persistent connection. It would be great if persistent
connections should be shared (as GWT or Bayeux
Protocolhttp://svn.cometd.com/trunk/bayeux/bayeux.htm does
it).
Multiple tabs/windows is one thing, but multiple clients are just as big a
problem.
Have you looked at how many tomcat threads you have running and what
happens to each of them as you open more websockets? What if you open more
websockets than you have threads...
Name: http-bio-4415-exec-5
State: RUNNABLE
Total blocked: 50 Total waited: 112
Stack trace:
java.net.SocketInputStream.socketRead0(Native Method)
java.net.SocketInputStream.read(SocketInputStream.java:161)
java.net.SocketInputStream.read(SocketInputStream.java:132)
org.apache.coyote.http11.upgrade.UpgradeBioProcessor.read
(UpgradeBioProcessor.java:81)
org.apache.catalina.websocket.WsFrame.nextFrame(WsFrame.java:214)
org.apache.catalina.websocket.WsInputStream.nextFrame(WsInputStream.java:68)
org.apache.catalina.websocket.StreamInbound.onData(StreamInbound.java:149)
org.apache.coyote.http11.upgrade.UpgradeProcessor.upgradeDispatch
(UpgradeProcessor.java:83)
org.apache.coyote.AbstractProtocol
$AbstractConnectionHandler.process(AbstractProtocol.java:587)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run
(JIoEndpoint.java:310)
- locked org.apache.tomcat.util.net.SocketWrapper@ddb0d168
java.util.concurrent.ThreadPoolExecutor.runWorker
(ThreadPoolExecutor.java:1156)
java.util.concurrent.ThreadPoolExecutor$Worker.run
(ThreadPoolExecutor.java:626)
java.lang.Thread.run(Thread.java:780)
I am trying to figure out what I am missing. I didn't think I needed
to
override StreamInbound.onData() in my class, but as that seems to be
what
is keeping the thread busy, presumably waiting for data looking at
that
stack.
Am I misunderstanding something, or is this possibly a tomcat bug?
I don't think this is a tomcat bug, but I could be mistaking.
My thinking about it being a bug is that to support N clients with
websockets, you need N threads available on tomcat, even though they are
only getting updates every x seconds.
It becomes trivial to denial-of-service a tomcat running websockets with
this sort of behaviour, as all you have to do is open 10 websockets which
lock up all 10 tomcat worker threads. Now nobody can connect to tomcat.
Sure, I can increase the number of tomcat threads, but if I want to
support 1000 concurrent users, I need well over 1000 tomcat threads to
achieve this!
Anton
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU