`
20921556
  • 浏览: 93529 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

socket 优化传输效率!!高手进

阅读更多
一个服务单 一个客户端

1.将服务器,和客户端都在本机上进行传输 很快
本机很快,1s可发几万次

2.将服务器放到 局域网内另一台 linux 机器,客户端放到windows 上进行发送的时候就很慢
  将服务器放到 局域网内另一台 windows 机器,客户端放到windows 进行发送,发送效率一样慢



客户端:
while(true){

一次发送的数据为 (8+15)=23字节,write(23字节);
等服务端得响应 read(16字节);

}
服务端:
while(true){
接受,
然后返回 响应 12+4 = 16的字节

}

客户端发送23字节,循环发送1000次,用时 60s。

将socket TcpNodelay设置为true后效率有所提升
发送23字节,循环发送1000次,用时 3s。
settcpnodelay(true)

我定位影响效率的原因是 in.read()阻塞导致的.
settcpnodelay(flase)即默认情况下
每次read()耗时 202ms左右,write() 0ms
settcpnodelay(true)即禁用negal算法,
每次read()耗时 1ms 左右,write() 1-3ms左右
偶尔出现一次40ms的情况

请教各位大侠,该如何优化,网络传输,read阻塞的情况啊

是JVM虚拟机的对socket的网络发送,有限制??

小弟先在此谢过!!



最新测试结果..

settcpnodelay(flase)
情况下
在一次发送 1536字节 获取响应70字节 循环一1000。。只需1500ms左右
在发送<1500字节的时候  获取响应70字节 循环一1000。。竟然达到 41000ms左右



settcpnodelay(true)
情况下
在一次发送 1536字节 获取响应70字节 循环一1000。。只需1500ms左右
在发送<1500字节的时候  获取响应70字节 循环一1000。。只需800ms左右






附带测试的小程序..
jar包中,包含源程序!
等待各位大侠优化~~


更多解决方案请进入code110技术导航站


方案优化1. 小数据包请将setNodelay(true);能够明显提升速度,此为TCP不延迟发送
  • 大小: 72 KB
  • 大小: 27.2 KB
  • send.jar (14.3 KB)
  • 描述: send.jar(客户端发送小程序)
  • 下载次数: 269
  • server.jar (14.3 KB)
  • 描述: server.jar(服务端接收小程序)
  • 下载次数: 212
分享到:
评论
45 楼 20921556 2011-04-28  
多线程..
性能有所提升..
增加socket.setTrafficClass(0x10);
44 楼 Dark-Mraz 2011-04-27  
楼主是单线程测试还是多线程?
43 楼 20921556 2011-04-27  
问题仍未解决..我试下测试mina看看
42 楼 hot66hot 2011-04-26  
tanjiazhang 写道
read是阻塞的,write是非阻塞的,比较它们的执行时间有意义吗。

大侠谁说write是非阻塞的,只是阻塞的时候少见,TCP的socket开发建议先看看TCP协议。。。。
41 楼 JMS_Exception 2011-04-26  
20921556 写道
JMS_Exception 写道
20921556 写道
一个服务单 一个客户端

1.将服务器,和客户端都在本机上进行传输 很快
本机很快,1s可发几万次

2.将服务器放到 局域网内另一台 linux 机器,客户端放到windows 上进行发送的时候就很慢
  将服务器放到 局域网内另一台 windows 机器,客户端放到windows 进行发送,发送效率一样慢



客户端:
while(true){

一次发送的数据为 (8+15)=23字节,write(23字节);
等服务端得响应 read(16字节);

}
服务端:
while(true){
接受,
然后返回 响应 12+4 = 16的字节

}

客户端发送23字节,循环发送1000次,用时 60s。

将socket TcpNodelay设置为true后效率有所提升
发送23字节,循环发送1000次,用时 3s。
settcpnodelay(true)

我定位影响效率的原因是 in.read()阻塞导致的.
settcpnodelay(flase)即默认情况下
每次read()耗时 202ms左右,write() 0ms
settcpnodelay(true)即禁用negal算法,
每次read()耗时 1ms 左右,write() 1-3ms左右
偶尔出现一次40ms的情况

请教各位大侠,该如何优化,网络传输,read阻塞的情况啊

是JVM虚拟机的对socket的网络发送,有限制??

小弟先在此谢过!!

lz
求解   服务器这段时间不间断的出现这个问题
2011-4-24 9:01:51 org.apache.jk.core.MsgContext action
警告: Unable to send headers
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)


操作系统是怎样的
什么情况下出现的??

linux
40 楼 pufan 2011-04-26  
你把服务器的代码贴全呀, server.accept后的handleConnection方法内部用线程池做的处理吗,估计问题在这里。
39 楼 pan_java 2011-04-25  
用mina,netty试一下。是不是程序有问题
38 楼 20921556 2011-04-25  
nakupanda 写道
试一下关闭相关计算机的防火墙或杀毒软件


我应该已经把防火墙什么的都关闭了!!
37 楼 nakupanda 2011-04-25  
试一下关闭相关计算机的防火墙或杀毒软件
36 楼 kakaluyi 2011-04-25  
上面的代码
1 socket.setPerformancePreferences(connectionTime, latency, bandwidth)为什么bandwidth(带宽权重要设置为0),试试socket.setPerformancePreferences(0,1,2)
2 还有缓冲区被注释了,明显还是要缓冲比较好
35 楼 w800927 2011-04-25  
我看了看这个
http://en.wikipedia.org/wiki/Nagle's_algorithm
我就好奇,这个算法在传输数据较多,较频繁的情况下,从理论上讲明明是可以提升效率的,为啥禁用了,反而效率高呢
34 楼 20921556 2011-04-25  
kakaluyi 写道
read 阻塞是由于没有新的数据达到客户端,所以read才会阻塞到,这个是正常的,三个问题
1 lz两台机器是同一个网段吗
2 两个机器连接没有通过一个proxy把
3 是否有额外的进程(防火墙?)

如果方便,实现的关键代码贴出来下 ,这种socket单节点通信实现都是差不多,不用怕什么代码泄露


代码并不复杂,跟附件中的小程序,类似!单线程,单客户端连接的情况

server:
incomingConnection = server.accept();
//                incomingConnection.setSendBufferSize(Env.SO_SENDBUFF);
                if(!incomingConnection.getTcpNoDelay()) incomingConnection.setTcpNoDelay(true);
                incomingConnection.setPerformancePreferences(1,2,0);
                incomingConnection.setTrafficClass(0x1C);
                handleConnection(incomingConnection);


处理
Object obj = null;
		Instruction inst = null;
		try{
			inst = Instruction.malloc();
			//long st = System.currentTimeMillis();
			if (read(in, inputBuffer, 0, s) != s) {
				Instruction.free(inst);
				return -1;
			}
			int r = InstructionType.typeOf(inputBuffer, sbit, ebit);
			if (r == InstructionType.XFR)
				obj = unpack(inst,in, inputBuffer, s);
			else if (r == InstructionType.CCC)
				obj = unpackCCC(inst,param,in, inputBuffer, s);

		}catch (EmptyStackException ex) {
			return NISAC_RESULT_CODE.RULE_FULL; 
		}catch (IOException e) {
			if (inst != null) {
				log4j.error("IOException:" + inst.toString());
				Instruction.free(inst);
			}
			inst = null;
			throw e;
		}

		return obj;


响应
if(!NISAC_HEAD.pack(head, outputBuffer, 0)) return false;
		
		if(!BLOCK_0D.pack(block, outputBuffer, NISAC_HEAD.BLOCK_LENGTH)) return false;
		
		out.write(outputBuffer, 0, head.message_length*4);
		return true;




client:=================================================
connection = new Socket(hostIp, hostPort);
            	in = new DataInputStream(connection.getInputStream());
            	out = new DataOutputStream(connection.getOutputStream());
//            	connection.setReceiveBufferSize(1024);
//            	connection.setSendBufferSize(1024);
            	if(!connection.getTcpNoDelay())connection.setTcpNoDelay(true);
            	connection.setPerformancePreferences(1,2,0);
            	connection.setTrafficClass(0x1C);

获取响应

read(in,inputBuffer, NISAC_HEAD.BLOCK_LENGTH);
		NISAC_HEAD.unpack(inputBuffer, 0, head);

		if (head.block_type == BLOCK_0D.BLOCK_TYPE) {
			read(in,inputBuffer, (head.message_length * 4 - NISAC_HEAD.BLOCK_LENGTH));
			BLOCK_0D.unpack(inputBuffer, 0, block);
			if (block.result == NISAC_RESULT_CODE.OK) {
				return true;
			}
		}

33 楼 kakaluyi 2011-04-25  
read 阻塞是由于没有新的数据达到客户端,所以read才会阻塞到,这个是正常的,三个问题
1 lz两台机器是同一个网段吗
2 两个机器连接没有通过一个proxy把
3 是否有额外的进程(防火墙?)

如果方便,实现的关键代码贴出来下 ,这种socket单节点通信实现都是差不多,不用怕什么代码泄露
32 楼 pouyang 2011-04-25  
用mina试试。
31 楼 kimmking 2011-04-25  
kimmking 写道
客户端换了,
新旧客户端,两台都是pc server上的(xp sp3)

可能我碰到的是个案,仅供参考。
30 楼 kimmking 2011-04-25  
客户端换了,
新旧客户端,两台都是pc server上的(xp sp3)
29 楼 20921556 2011-04-25  
kimmking 写道
dennis_zane 写道
kimmking 写道
dennis_zane 写道
首先,你传输的都是十几个字节,所以一定要禁用nagle算法,也就是tcpNoDelay设置为true,提高响应速度。

其次,你的读写应该是批量的吧,发送接受都是搞一个byte数组缓冲区

其实感觉最大的问题不是nagle,也不是batch或buffer、async或sync,
这些都不会有那么大的差别。

目前 不到2k*1000次,1.5s的速度还是慢,
吞吐量不到2M/s

如果网络问题排除,则测试机器可能有问题,换一个机器+新装的系统试试。


大量发这种小数据包,nagel算法的对响应的影响是非常大的,楼主自己测试的结果就可以看出来。


是的,nagel影响比较大。主要是响应时间。
我的意思是,nagel不是问题的关键。 我前不久也遇到类似的问题,最后发现是环境问题。
loadrunner压力下,throughout就是上不去,6M/s就再也上不去。
飞鸽和ftp下,都可以到70M/s+, 1G的网卡+网线+交换机。他们都正常,就是java下的socket在loadrunner里上不去。

然后,换了个机器测试就好了。



是客户端,服务端都换.??还是??
jre使用什么版本..?
28 楼 20921556 2011-04-25  
kimmking 写道
dennis_zane 写道
kimmking 写道
dennis_zane 写道
首先,你传输的都是十几个字节,所以一定要禁用nagle算法,也就是tcpNoDelay设置为true,提高响应速度。

其次,你的读写应该是批量的吧,发送接受都是搞一个byte数组缓冲区

其实感觉最大的问题不是nagle,也不是batch或buffer、async或sync,
这些都不会有那么大的差别。

目前 不到2k*1000次,1.5s的速度还是慢,
吞吐量不到2M/s

如果网络问题排除,则测试机器可能有问题,换一个机器+新装的系统试试。


大量发这种小数据包,nagel算法的对响应的影响是非常大的,楼主自己测试的结果就可以看出来。


是的,nagel影响比较大。主要是响应时间。
我的意思是,nagel不是问题的关键。 我前不久也遇到类似的问题,最后发现是环境问题。
loadrunner压力下,throughout就是上不去,6M/s就再也上不去。
飞鸽和ftp下,都可以到70M/s+, 1G的网卡+网线+交换机。他们都正常,就是java下的socket在loadrunner里上不去。

然后,换了个机器测试就好了。


后来换的测试机,是什么操作系统??
27 楼 kimmking 2011-04-25  
dennis_zane 写道
kimmking 写道
dennis_zane 写道
首先,你传输的都是十几个字节,所以一定要禁用nagle算法,也就是tcpNoDelay设置为true,提高响应速度。

其次,你的读写应该是批量的吧,发送接受都是搞一个byte数组缓冲区

其实感觉最大的问题不是nagle,也不是batch或buffer、async或sync,
这些都不会有那么大的差别。

目前 不到2k*1000次,1.5s的速度还是慢,
吞吐量不到2M/s

如果网络问题排除,则测试机器可能有问题,换一个机器+新装的系统试试。


大量发这种小数据包,nagel算法的对响应的影响是非常大的,楼主自己测试的结果就可以看出来。


是的,nagel影响比较大。主要是响应时间。
我的意思是,nagel不是问题的关键。 我前不久也遇到类似的问题,最后发现是环境问题。
loadrunner压力下,throughout就是上不去,6M/s就再也上不去。
飞鸽和ftp下,都可以到70M/s+, 1G的网卡+网线+交换机。他们都正常,就是java下的socket在loadrunner里上不去。

然后,换了个机器测试就好了。
26 楼 esanone 2011-04-25  
建议LZ用mina吧,很多底层细节不用去考虑。

相关推荐

Global site tag (gtag.js) - Google Analytics