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);
}
}
}
cxf-test.tar.gz
Description: GNU Zip compressed data
