Hessian http

Hessian是一个轻量级的remoting on http工具,采用的是Binary RPC协议,所以它很适合于发送二进制数据,同时又具有防火墙穿透能力。Hessian一般是通过Web应用来提供服务,因此非常类似于平时我们用的WebService。只是它不使用SOAP协议,但相比webservice而言更简单、快捷。

Hessian官网:http://hessian.caucho.com/

接下来我们测试一下Hessian的性能

测试类如下:

接口:

package test.hessian;

public interface IHello {

    String sayHello(String name);

    public TestBean testBean(int i,String j);

    public void test(TestBean t);
}

实现:

package test.hessian;

import com.caucho.hessian.server.HessianServlet;

public class HelloImpl extends HessianServlet implements IHello {

    private static final long serialVersionUID = 1464625224364842441L;

    @Override
    public String sayHello(String name) {
        return "hello:" + name;

    }

    @Override
    public TestBean testBean(int i, String j) {
        TestBean t = new TestBean();
        t.setTestInt(i);
        t.setTestString(j);
        return t;
    }

    @Override
    public void test(TestBean t) {
        System.out.println(t);
    }

}

TestBean:

package test.hessian;

import java.io.Serializable;

public class TestBean implements Serializable {

    private static final long serialVersionUID = 3726175313904115945L;

    private int testInt;

    private String testString;

    private byte[] byteArray = new byte[1024 * 10];

    public TestBean() {
    }

    public TestBean(int testInt, String testString) {
        this.testInt = testInt;
        this.testString = testString;
    }

    public int getTestInt() {
        return testInt;
    }

    public void setTestInt(int testInt) {
        this.testInt = testInt;
    }

    public String getTestString() {
        return testString;
    }

    public void setTestString(String testString) {
        this.testString = testString;
    }

    public byte[] getByteArray() {
        return byteArray;
    }

    public void setByteArray(byte[] byteArray) {
        this.byteArray = byteArray;
    }

}

准备完毕,现在启动服务:

package test.hessian;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;

public class ServletContext {

    public static void main(String[] args) throws Exception {

        Server server = new Server(8080);

        ServerConnector connector = new ServerConnector(server);

        server.addConnector(connector);

        ServletContextHandler context = new ServletContextHandler();

        context.setContextPath("/test");

        server.setHandler(context);

        context.addServlet(new ServletHolder(new HelloImpl()), "/hello");

        server.start();
    }

}

到此为止,这个服务的服务器端已经搭建起来了,现在开始用压测程序压测

package test.hessian;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

import com.caucho.hessian.client.HessianProxyFactory;

public class StressTest {

    private final static String url = "http://127.0.0.1:8080/test/hello";

    public static void main(String args[]) throws Throwable {

        HessianProxyFactory hpf = new HessianProxyFactory();

        hpf.setChunkedPost(false);

        final IHello hello = (IHello) hpf.create(IHello.class, url);

        // 创建收集信息list
        final List<StopWatch> list = new ArrayList<StopWatch>();
        //线程数量
        int count = 100;
        final long start1 = System.currentTimeMillis();
        final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() {
            @Override
            public void run() {
                long end1 = System.currentTimeMillis();
                //分析收集到的信息
                analyseStopWatch(list, (end1 - start1));
            }
        });
        final Object obj = new Object();
        for (int i = 0; i < count; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int j = 0; j < 1000; j++) {
                            //创建收集信息对象
                            StopWatch sw = new StopWatch();
                            long startTime = System.currentTimeMillis();
                            sw.setStartTime(startTime);
                            try {
                                hello.sayHello("" + j);
                                //TestBean t = hello.testBean(j, j + "");
                                sw.setStatus(true);
                            } catch (Throwable e) {
                                sw.setStatus(false);
                                e.printStackTrace();
                            }
                            long endTime = System.currentTimeMillis();
                            sw.setEndTime(endTime);
                            sw.setElapsedTime(endTime - startTime);
                            //将收集信息对象添加到list中
                            synchronized (obj) {
                                list.add(sw);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    try {
                        barrier.await();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            });
            //  if (i < 29) {
            //      t.setDaemon(true);
            //  }
            t.start();
        }
    }

    private static void analyseStopWatch(List<StopWatch> stopWatchs, long totalSpend) {
        Collections.sort(stopWatchs, new Comparator<StopWatch>() {
            @Override
            public int compare(StopWatch o1, StopWatch o2) {
                Long elapsedTime1 = o1.getElapsedTime();
                Long elapsedTime2 = o2.getElapsedTime();
                return elapsedTime1.compareTo(elapsedTime2);
            }
        });
        int size = stopWatchs.size();
        long min = 0;
        for (StopWatch sw : stopWatchs) {
            if (sw.getElapsedTime() > 0) {
                min = sw.getElapsedTime();
                break;
            }
        }
        System.out.println("spend time min = " + min + "MS   |   max = " + stopWatchs.get(size - 1).getElapsedTime() + "MS");
        int failCount = 0;
        long spendTime = 0L;
        for (StopWatch sw : stopWatchs) {
            spendTime += sw.getElapsedTime();
            if (!sw.isStatus()) {
                failCount += 1;
            }
        }
        System.out.println("total spend time = " + totalSpend + "MS");
        System.out.println("total request count = " + size);
        double d1 = totalSpend;
        double d2 = size;
        double averageST = d1 / d2;
        System.out.println("average spend time = " + spendTime / size + "MS");
        System.out.println("Transaction Per Second = " + (1000 / averageST));
        System.out.println("total fail count = " + failCount);
    }

}

StopWatch :

package test.hessian;

public class StopWatch {

    private long startTime;
    private long endTime;
    private long elapsedTime;
    private boolean status;

    public StopWatch() {
        this.startTime = 0L;
        this.endTime = 0L;
        this.elapsedTime = 0L;
        this.status = false;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }

    public long getEndTime() {
        return endTime;
    }

    public void setEndTime(long endTime) {
        this.endTime = endTime;
    }

    public boolean isStatus() {
        return status;
    }

    public void setStatus(boolean status) {
        this.status = status;
    }

    public long getElapsedTime() {
        return elapsedTime;
    }

    public void setElapsedTime(long elapsedTime) {
        this.elapsedTime = elapsedTime;
    }

}

开始测试:

1,测试传输数据量为0的性能:

输出:

spend time min = 1MS | max = 153MS (方法执行最小时长最大时长)

total spend time = 27859MS (测试程序运行时间)

total request count = 100000 (请求远程方法次数)

average spend time = 27MS (平均每个方法执行的时间)

Transaction Per Second = 3589.504289457626(每秒方法返回次数)

total fail count = 0 (总共失败次数)

2,测试传输数据量为10K的性能:

private byte[] byteArray = new byte[1024*10];
//hello.sayHello("" + j);
TestBean t = hello.testBean(j, j + "");

输出:

spend time min = 1MS | max = 449MS

total spend time = 39660MS

total request count = 100000

average spend time = 39MS

Transaction Per Second = 2521.4321734745336

total fail count = 0

3,测试传输数据量为1M的性能:

private byte[] byteArray = new byte[1024*1024];

输出:

spend time min = 18MS | max = 3786MS

total spend time = 1712132MS

total request count = 100000

average spend time = 1701MS

Transaction Per Second = 58.406711632047056

total fail count = 0

测试结果:

Hessian调用caucho公司的resin服务器号称是最快的服务器,在java领域有一定的知名度。Hessian做为resin的组成部分,其设计也非常精简高效,实际运行情况也证明了这一点。平均来看,Hessian在少量或中等数据时,表现相当优秀,数据量特别大时,性能稍差。但也很快,Hessian的好处是精简高效,可以跨语言使用,而且协议规范公开,我们可以针对任意语言开发对其协议的实现。目前已有实现的语言有:java, c++, .net, python, ruby。还没有delphi的实现。另外,Hessian与WEB服务器结合非常好,借助WEB服务器的功能,在处理大量用户并发访问时会有很大优势,在资源分配,线程排队,异常处理等方面都可以由成熟的WEB服务器保证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值