It does sound like you are becoming bandwidth or latency bound on the remote 
connections.   My gut feeling is that on the local network, you are becoming 
CPU bound.   The time it takes to escape the string is greater than the 
bandwidth restrictions so MTOM is really winning out.

On the remote connections, the bandwidth is effectively throttling things.   
For mtom, the cpu ends up just sitting around doing nothing while it waits to 
send stuff.   With non-mtom, the cpu can escape strings while data is being 
sent.

I'm willing to be that if you stuck a CPU monitor on, the MTOM case would show 
much lower cpu usage.   That COULD be good from a scalability standpoint as 
that CPU could be used to process additional requests and such.

Dan


On Wed September 30 2009 5:43:10 am Vitaly Litvak wrote:
> Hi.
> 
> We are testing our application on a channel with a low bandwidth. For the
> testing we've developed a simple service, which loads some data from a text
> file and then returns it through two web methods:
> 
> 1) simply returns file as a string.
> 2) returns a DataSource object, which we suppose to return our file as a
> MTOM attachment to SOAP response.
> 
> If test is ran in a local environment we got 15 times performance
> improvements when using MTOM attachments versus method returning a string:
> 
> Elapsed time: streaming=2017, string=33955
> 
> But if we move server application to remote host on Amazon there are no
> performance gain at all. We've tried moving it to some computer in local
> network and the performance gain present here. After that we've tried to
> move to private remote computer and it works the same as on Amazon again.
> And neither profiling (JProfiler), nor network monitoring (wireshark) can't
> guide us to the root reason of this. We've spent about three days making
> tests and unable to know why this is happening.
> 
> Here is the source code (also tried to attached it to e-mail message):
> 
> // IWS.java
> 
> package test;
> import javax.activation.DataSource;
> import javax.jws.WebService;
> 
> public interface IWS
> {
>     public DataSource xmlStream();
>     public String xmlString();
> }
> 
> // CWS.java
> 
> package test;
> import java.io.File;
> 
> import javax.activation.DataSource;
> import javax.mail.util.ByteArrayDataSource;
> 
> import org.apache.commons.io.FileUtils;
> 
> 
> public class CWS implements IWS
> {
>     private static ByteArrayDataSource xml;
>     private static String xmlString;
>     static
>     {
>         try
>         {
>             xmlString = FileUtils.readFileToString(new File("bs.txt"));
>             xml = new ByteArrayDataSource(xmlString.getBytes(), null);
>         }
>         catch (Exception ex)
>         {
>             ex.printStackTrace();
>         }
>     }
> 
>     @Override
>     public DataSource xmlStream()
>     {
>         return xml;
>     }
> 
>     @Override
>     public String xmlString()
>     {
>         return xmlString;
>     }
> 
> }
> 
> // Server.java
> 
> package test;
> import java.util.*;
> 
> import org.apache.cxf.common.util.SOAPConstants;
> import org.apache.cxf.feature.AbstractFeature;
> import org.apache.cxf.frontend.ServerFactoryBean;
> import org.apache.cxf.transport.http.AbstractHTTPDestination;
> import org.apache.cxf.transport.http.gzip.GZIPFeature;
> import org.apache.cxf.transports.http.configuration.HTTPServerPolicy;
> 
> 
> public class Server
> {
>     public static boolean GZIP = false;
>     public static boolean KEEPALIVE = false;
>     private static org.apache.cxf.endpoint.Server server;
> 
>     private static void init()
>     {
>         if (server == null)
>         {
>             /**
>              * Start main application server
>              */
>             CWS cws = new CWS();
>             ServerFactoryBean sfb = new ServerFactoryBean();
> 
>             Map<String,Object> props = new HashMap<String, Object>();
>             props.put(SOAPConstants.MTOM_ENABLED, Boolean.TRUE.toString());
> 
>             sfb.setProperties(props);
>             sfb.getServiceFactory().setDataBinding(DataBindings.get());
>             sfb.setServiceClass(IWS.class);
>             sfb.setAddress(Main.address);
>             sfb.setServiceBean(cws);
>             if (sfb.getFeatures() == null)
>             {
>                 sfb.setFeatures(new ArrayList<AbstractFeature>());
>             }
>             if (GZIP)
>             {
>                 System.out.println("Enabling GZIP");
>                 sfb.getFeatures().add(new GZIPFeature());
>             }
> 
>             server = sfb.create();
> 
>             if (KEEPALIVE)
>             {
>                 System.out.println("Enabling keep-alive");
>                 HTTPServerPolicy spol = ((AbstractHTTPDestination)
> server.getDestination()).getServer();
>                 spol.setHonorKeepAlive(true);
>                 spol.setKeepAliveParameters("timeout=60, max=10;");
>             }
>         }
>     }
> 
>     public static org.apache.cxf.endpoint.Server get()
>     {
>         init();
>         return server;
>     }
> 
>     public static void main(String... args)
>     {
>         for (String arg : args)
>         {
>             if (arg != null)
>             {
>                 if (arg.trim().equalsIgnoreCase("gzip"))
>                 {
>                     GZIP = true;
>                 }
>                 else if (arg.trim().equalsIgnoreCase("keepalive"))
>                 {
>                     KEEPALIVE = true;
>                 }
>             }
>         }
>         init();
>     }
> }
> 
> // Client.java
> 
> package test;
> import java.io.InputStream;
> import java.util.*;
> 
> import javax.activation.DataSource;
> 
> import org.apache.cxf.common.util.SOAPConstants;
> import org.apache.cxf.feature.AbstractFeature;
> import org.apache.cxf.frontend.ClientProxy;
> import org.apache.cxf.frontend.ClientProxyFactoryBean;
> import org.apache.cxf.transport.http.HTTPConduit;
> import org.apache.cxf.transport.http.gzip.GZIPFeature;
> import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
> 
> 
> public class Client
> {
>     public static boolean GZIP = true;
>     private static IWS client;
> 
>     public static void init(String address)
>     {
>         ClientProxyFactoryBean cfb = new ClientProxyFactoryBean();
>         cfb.setServiceClass(IWS.class);
>         cfb.setAddress(address);
> 
>         Map<String,Object> props = new HashMap<String, Object>();
>         props.put(SOAPConstants.MTOM_ENABLED, Boolean.TRUE.toString());
> 
>         cfb.setProperties(props);
>         cfb.getServiceFactory().setDataBinding(DataBindings.get());
>         if (cfb.getFeatures() == null)
>         {
>             cfb.setFeatures(new ArrayList<AbstractFeature>());
>         }
>         if (GZIP)
>         {
>             cfb.getFeatures().add(new GZIPFeature());
>         }
> 
>         client = (IWS) cfb.create();
> 
>         org.apache.cxf.endpoint.Client cl = ClientProxy.getClient(client);
> 
>         HTTPConduit cnd = (HTTPConduit)cl.getConduit();
>         HTTPClientPolicy cpol = cnd.getClient();
>         cpol.setConnectionTimeout(60 * 1000);
>         cpol.setAllowChunking(false);
>         cpol.setReceiveTimeout(60 * 1000);
>         if (GZIP)
>         {
>             cpol.setAcceptEncoding("gzip");
>         }
>         cnd.setClient(cpol);
>     }
> 
>     public static void runPerformanceTests(int COUNT) throws Exception
>     {
>         long t = System.currentTimeMillis();
>         for (int i = 0; i < COUNT; i++)
>         {
>             DataSource ds = Client.get().xmlStream();
> 
>             byte[] buf = new byte[100 * 1024];
>             InputStream is = ds.getInputStream();
>             while (is.read(buf) >= 0)
>             {
>             }
>             is.close();
>         }
>         long streaming = (System.currentTimeMillis() - t);
> 
>         t = System.currentTimeMillis();
>         for (int i = 0; i < COUNT; i++)
>         {
>             String xml = Client.get().xmlString();
>         }
>         long string = (System.currentTimeMillis() - t);
> 
>         System.out.println("Elapsed time: streaming=" + streaming + ",
> string=" + string);
>     }
> 
>     public static IWS get()
>     {
>         return client;
>     }
> 
>     public static void main(String args[]) throws Exception
>     {
>         init("http://remote.server.com:9336/cxf_test";);
>         runPerformanceTests(100);
>     }
> }
> 
> // Main.java
> 
> package test;
> 
> 
> public class Main
> {
>     public static String address = "http://localhost:9336/cxf_test";;
>     private final static boolean GZIP = true;
> 
>     public static void main(String... args)
>     {
>         long t = System.currentTimeMillis();
> 
>         try
>         {
>             Client.GZIP = GZIP;
>             Server.GZIP = GZIP;
> 
>             Server.get();
>             Client.init(address);
> 
>             Client.runPerformanceTests(100);
>         }
>         catch (Throwable ex)
>         {
>             ex.printStackTrace();
>         }
>         finally
>         {
>             Server.get().stop();
>             System.out.println("Time running: " +
> (System.currentTimeMillis() - t));
> 
>             System.exit(0);
>         }
>     }
> }
> 

-- 
Daniel Kulp
[email protected]
http://www.dankulp.com/blog

Reply via email to