You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mina.apache.org by Сергей Григорьев <s....@gmail.com> on 2010/12/21 08:54:31 UTC

how to set up the speed limit for a session ?

Hello All,
My company is evaluating MINA  for building a content-delivery system. I am
in charge of creaing a pilot project. The prototype is a simple HTTP proxy
which stands between the clients and a heavy-loaded web server. I've found
an example of proxy in MINA souces, then tried it. It didn't work, because
the connection between the client and proxy is relatively slow, and
connection between proxy and the web server is very fast, so it consumed
2GBytes of memory. So we ended up with a proxy with a  lot of queued
messages from web server waiting to be delivered to the client. Then I
decided to create a filter which watches for the number of messages in write
queue (from proxy to the clients), and if the number is greater than 2,
then the filter tells the other session (from proxy to server) to suspend
reading, otherwise resumeReading.  It ended up with all worker threads
blocked:

pool-5-thread-593" prio=10 tid=0x00002aab387cf000 nid=0x451f waiting for
monitor entry [0x000000006d91c000]
java.lang.Thread.State: BLOCKED (on object monitor)
at sun.nio.ch.EPollArrayWrapper.setInterest(EPollArrayWrapper.java:151)

   - waiting to lock <0x00002aaab3988d48> (a java.util.LinkedList)
   at sun.nio.ch.EPollSelectorImpl.putEventOps(EPollSelectorImpl.java:164)
   at
   sun.nio.ch.SocketChannelImpl.translateAndSetInterestOps(SocketChannelImpl.java:799)
   at sun.nio.ch.SelectionKeyImpl.nioInterestOps(SelectionKeyImpl.java:87)
   at sun.nio.ch.SelectionKeyImpl.interestOps(SelectionKeyImpl.java:65)
   at
   org.apache.mina.transport.socket.nio.NioProcessor.setInterestedInWrite(NioProcessor.java:207)
   at
   org.apache.mina.transport.socket.nio.NioProcessor.setInterestedInWrite(NioProcessor.java:42)
   at
   org.apache.mina.core.polling.AbstractPollingIoProcessor.updateTrafficControl(AbstractPollingIoProcessor.java:1041)
   at
   org.apache.mina.core.polling.AbstractPollingIoProcessor.updateTrafficControl(AbstractPollingIoProcessor.java:66)
   at
   org.apache.mina.core.service.SimpleIoProcessorPool.updateTrafficControl(SimpleIoProcessorPool.java:259)
   at
   org.apache.mina.core.service.SimpleIoProcessorPool.updateTrafficControl(SimpleIoProcessorPool.java:77)
   at
   org.apache.mina.core.session.AbstractIoSession.resumeRead(AbstractIoSession.java:660)
   at com.pmstation.mina.ThrottleFilter.throttle(ThrottleFilter.java:44)
   at com.pmstation.mina.ThrottleFilter.messageSent(ThrottleFilter.java:17)
   at
   org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageSent(DefaultIoFilterChain.java:462)
   at
   org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1300(DefaultIoFilterChain.java:46)
   at
   org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageSent(DefaultIoFilterChain.java:802)
   at
   org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:80)
   at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)
   at
   java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at
   java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at java.lang.Thread.run(Thread.java:619)


I was assuming that suspending reading or resuming reading affects the
session only, and from the stack trace I can see that tries to resume
reading on the NIO channel which serves many sessions.  What approach should
I take to balance the speed of incoming and outgoing  channels ?

public class ThrottleFilter extends IoFilterAdapter {

  private static final long MAX__QUEUED__MESSAGES = 2;


  @Override
  public void messageSent(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
    throttle(session);
    super.messageSent(nextFilter, session, writeRequest);

  }

  @Override
  public void sessionClosed(NextFilter nextFilter, IoSession session) throws
Exception {
    super.sessionClosed(nextFilter, session);
  }

  @Override
  public void sessionIdle(NextFilter nextFilter, IoSession session,
IdleStatus status) throws Exception {
    throttle(session);
    super.sessionIdle(nextFilter, session, status);
  }

  @Override
  public void filterWrite(NextFilter nextFilter, IoSession session,
WriteRequest writeRequest) throws Exception {
    throttle(session);
    super.filterWrite(nextFilter, session, writeRequest);
  }

  private void throttle(IoSession session) {
    IoSession otherSesion = Utils.getPeerSession(session);
    if (otherSesion == null)
      return;
    if (session.getScheduledWriteMessages() <  MAX__QUEUED__MESSAGES) {
      otherSesion.resumeRead();
    } else {
      otherSesion.suspendRead();
    }
  }

Re: how to set up the speed limit for a session ?

Posted by Emmanuel Lecharny <el...@gmail.com>.
On 12/21/10 8:54 AM, Сергей Григорьев wrote:
> Hello All,
> My company is evaluating MINA  for building a content-delivery system. I am
> in charge of creaing a pilot project. The prototype is a simple HTTP proxy
> which stands between the clients and a heavy-loaded web server. I've found
> an example of proxy in MINA souces, then tried it. It didn't work, because
> the connection between the client and proxy is relatively slow, and
> connection between proxy and the web server is very fast, so it consumed
> 2GBytes of memory. So we ended up with a proxy with a  lot of queued
> messages from web server waiting to be delivered to the client. Then I
> decided to create a filter which watches for the number of messages in write
> queue (from proxy to the clients), and if the number is greater than 2,
> then the filter tells the other session (from proxy to server) to suspend
> reading, otherwise resumeReading.  It ended up with all worker threads
> blocked:

Just a question : have you played with the received and send buffer size 
? If you are sending big messages, this may have a huge impact on 
performances.


-- 
Regards,
Cordialement,
Emmanuel Lécharny
www.iktek.com