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);
        }
    }
}

Attachment: cxf-test.tar.gz
Description: GNU Zip compressed data

Reply via email to