`
san_yun
  • 浏览: 2662239 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

java socket远程读取文件性能测试

 
阅读更多

为了比较beansdb,写了一个基于socket的java文件读取测试。

 

 server:

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PushbackInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;

import org.apache.commons.io.FileUtils;

import com.taobao.tlog.util.NamedThreadFactory;

public class FileServer {

	public void run() throws IOException {

		bosses.submit(new Boss());

	}

	static ExecutorService bosses = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("boss", false));
	static ExecutorService workers = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("worker", false));

	private static class Boss implements Callable {

		@Override
		public Object call() throws Exception {
			ServerSocket server = new ServerSocket(8080);
			while (true) {
				Socket socket = server.accept();
				workers.submit(new Wroker(socket));
			}
		}
	}

	private static class Wroker implements Callable {

		Socket socket;
		PushbackInputStream input;

		public Wroker(Socket socket) throws IOException {
			this.socket = socket;
			input = new PushbackInputStream(socket.getInputStream(), 1);
		}

		protected void receive(String path) throws IOException {
			File file = new File(path);
			byte[] data = FileUtils.readFileToByteArray(file);
			OutputStream output = socket.getOutputStream();
			output.write(data);
			output.flush();
			System.out.println(path+" flush");
		}

		public void accept() throws Exception {
			int bytesToRead = 0;
			while (true) {
				bytesToRead = input.available();
				if (bytesToRead > 0) {
					byte[] t = new byte[45];
					input.read(t);
					String path = new String(t);
//					System.out.println("path=" + path);
					receive(path);
				} else {
					int b = input.read(); // 此操作会阻塞,直到有数据被读到
					if (b < 0) {
						throw new IOException(
								" end of the socket input stream has been reached,may be server socket is closed!");
					} else {
						input.unread(b);
						continue;
					}

				}
			}
		}

		@Override
		public Object call() {
			while (true) {
				try {
					accept();
				} catch (Exception e) {
					e.printStackTrace();
					System.exit(-1);
				}
			}
		}

	}

	public static void main(String[] args) throws IOException {
		new FileServer().run();
	}
}

 

client

import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PushbackInputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.text.DecimalFormat;
import java.util.Random;

public class FileClient {

	static Random random = new Random();

	Socket socket;
	PushbackInputStream input;

	public FileClient() throws IOException {
		init();
	}

	public void init() throws IOException {
		socket = new Socket();
		socket.setReuseAddress(true);
		socket.setKeepAlive(true);
		socket.setTcpNoDelay(true);
		socket.setSoLinger(true, 0);
		socket.setSoTimeout(60000);
		socket.connect(new InetSocketAddress("localhost", 8080), 60000);
		input = new PushbackInputStream(socket.getInputStream(), 1);
	}

	public void send(String path) throws IOException {
//		System.out.println(path);
		OutputStream out = socket.getOutputStream();
		OutputStreamWriter writer = new OutputStreamWriter(out);
		writer.write(path);
		writer.flush();
	}

	/**
	 * 	System.out.println("readed:" + readBytes + ",bytesToRead:" + bytesToRead);
	 *  <pre>
	 *  readed:-1,bytesToRead:0
	 *	readed:-1,bytesToRead:180224
	 *	readed:131072,bytesToRead:376831
	 *	readed:262144,bytesToRead:344063
	 *	readed:393216,bytesToRead:324300
	 *	readed:524288,bytesToRead:193228
	 *	readed:655360,bytesToRead:62156
	 *	readed:717516,bytesToRead:0
	 * </pre>
	 * @throws IOException
	 */
	public void readLine() throws IOException {

		int bytesToRead = 0;
		int readBytes = -1;
		while (true) {
			bytesToRead = input.available();
			if (readBytes >= 717516) {
				break;
			}
			if (bytesToRead > 0) {
				byte[] data = new byte[bytesToRead];
				readBytes += input.read(data);
			} else {
				int b = input.read(); // 此操作会阻塞,直到有数据被读到
				if (b < 0) {
					throw new IOException(
							" end of the socket input stream has been reached,may be server socket is closed!");
				} else {
					input.unread(b);
					continue;
				}

			}
		}
	}

	public void test() throws IOException {

		DecimalFormat df = new DecimalFormat("#00");
		long begin = System.currentTimeMillis();
		for (int i = 0; i < 100; i++) {
			int id = random.nextInt(10000);
			int month = id % 12 + 1;
			int day = id % 30 + 1;
			int ix = id % 99 + 1;
			String file = "/duitang/data/pic_test/2013/" + df.format(month) + "/" + df.format(day) + "/HDFS"
					+ df.format(ix) + ".jpeg";
			send(file);
			readLine();
		}
		long end = System.currentTimeMillis();
		System.out.println((end - begin) + "ms ");
	}

	public static void main(String[] args) throws IOException {
		FileClient client = new FileClient();
		for (int i = 0; i < 10; ++i) {
			client.test();
		}
	}
}

 

测试数据准备,测试数据按照/year/month/day/data 存放,一共36000张图片:

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;

import org.apache.commons.io.FileUtils;

public class FileUtil {

	public static void buildData() throws IOException {
		DecimalFormat format = new DecimalFormat("#00");

		String path = "/duitang/data/pic_test/2013";
		for (int month = 1; month < 13; ++month) {

			File mongthPath = new File(path, format.format(month));
			mongthPath.mkdirs();
			for (int day = 1; day < 31; ++day) {

				File dayPath = new File(mongthPath, format.format(day));
				dayPath.mkdirs();
				
				for (int i = 1; i < 100; ++i) {
					FileUtils.copyFile(new File("/tmp/HDFS.jpeg"), new File(dayPath, "HDFS" + format.format(i)
							+ ".jpeg"));
				}
			}
		}
	}

}

 

在我笔记本上的性能:

187ms 
174ms 
157ms 
169ms 
171ms 
154ms 
168ms 
155ms 
163ms 
164ms 

 产生的图片请求,确保是随机的:

/duitang/data/pic_test/2013/03/27/HDFS48.jpeg flush
/duitang/data/pic_test/2013/09/09/HDFS39.jpeg flush
/duitang/data/pic_test/2013/02/08/HDFS74.jpeg flush
/duitang/data/pic_test/2013/06/12/HDFS87.jpeg flush
/duitang/data/pic_test/2013/08/08/HDFS50.jpeg flush
/duitang/data/pic_test/2013/01/07/HDFS79.jpeg flush
/duitang/data/pic_test/2013/10/16/HDFS52.jpeg flush
/duitang/data/pic_test/2013/02/08/HDFS47.jpeg flush
/duitang/data/pic_test/2013/07/19/HDFS88.jpeg flush
/duitang/data/pic_test/2013/05/29/HDFS14.jpeg flush
/duitang/data/pic_test/2013/08/20/HDFS71.jpeg flush
/duitang/data/pic_test/2013/08/20/HDFS26.jpeg flush
/duitang/data/pic_test/2013/03/09/HDFS45.jpeg flush
/duitang/data/pic_test/2013/03/15/HDFS36.jpeg flush
/duitang/data/pic_test/2013/09/21/HDFS39.jpeg flush
/duitang/data/pic_test/2013/11/23/HDFS53.jpeg flush
/duitang/data/pic_test/2013/04/10/HDFS64.jpeg flush
/duitang/data/pic_test/2013/02/26/HDFS80.jpeg flush
/duitang/data/pic_test/2013/09/27/HDFS06.jpeg flush
/duitang/data/pic_test/2013/01/07/HDFS46.jpeg flush
/duitang/data/pic_test/2013/04/16/HDFS19.jpeg flush
/duitang/data/pic_test/2013/10/10/HDFS88.jpeg flush
/duitang/data/pic_test/2013/05/11/HDFS29.jpeg flush
/duitang/data/pic_test/2013/08/14/HDFS86.jpeg flush
/duitang/data/pic_test/2013/07/07/HDFS85.jpeg flush
/duitang/data/pic_test/2013/09/21/HDFS51.jpeg flush

 

disable linux cache后:
普通FS
326 ms 
286 ms 
303 ms 
292 ms 
296 ms 
283 ms 
292 ms 
290 ms 
273 ms 
289 ms 

beansdb
368.748903275 ms
326.793909073 ms
337.444067001 ms
322.673082352 ms
336.313009262 ms
331.909179688 ms
329.982995987 ms
275.442838669 ms
271.515130997 ms
333.788871765 ms

基于BufferedRandomAccess
127ms 
125ms 
125ms 
123ms 
127ms 
126ms 
125ms 
128ms 
127ms 
126ms 

 

分享到:
评论

相关推荐

    基于net的超市管理系统源代码(完整前后端+sqlserver+说明文档+LW).zip

    功能说明: 环境说明: 开发软件:VS 2017 (版本2017以上即可,不能低于2017) 数据库:SqlServer2008r2(数据库版本无限制,都可以导入) 开发模式:mvc。。。

    LABVIEW程序实例-公式节点.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    大米商城开源版damishop(适合外贸)

    大米外贸商城系统 简称damishop 完全开源版,只需做一种语言一键开启全球133中语言自动翻译功能,价格实现自动汇率转换,集成微信支付宝 paypal以及国外主流支付方式,自带文章博客系统。 软件架构 基于MVC+语言包模式,增加控制台,API导入产品方便对接其他系统(带json示例数据)。 使用要求 PHP7.4+ MYSQL5.6+ REDIS(可选) 安装方法 composer install 打开安装向导安装 http://您的域名/install 特色 1、缓存层增加时间与批量like删除 2、API产品导入方便对接其他系统 3、增加控制台命令行,命令行生成语言翻译包 4、后台一键开启自动翻译模式,支持全球133中语言,由于google代理翻译需要收费,这个功能需要付费。 5、可选购物车与ajax修改购物车产品 6、一键结算checkout 7、增加网站前台自定义路由 方便seo 更新日志 v3.9.7 集成鱼码支付接口,方便个人站长即使收款到账使用 v3.9.3 更新内容 1:增加ueditor与旧编辑器切换 2:增加可视化布局插

    LABVIEW程序实例-通过全局变量接收数据.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    LABVIEW程序实例-日历控件.zip

    labview程序代码参考学习使用,希望对你有所帮助。

    毕设和企业适用springboot人工智能客服系统类及旅游规划平台源码+论文+视频.zip

    毕设和企业适用springboot人工智能客服系统类及旅游规划平台源码+论文+视频

Global site tag (gtag.js) - Google Analytics