JAVA高并发服务器讨论

dfasri 2011-05-27 04:29:00
开发WEB, Buffer几乎必不可少.
但假如采用自增加长度的Buffer, 单纯写4MB的数据, 都要350ms的时间, 效率这么低.
从SOCKET下来的数据, 先是写到Buffer, 然后处理完成后, 再把结果写入Buffer, 然后用SOCKET发送出去.
在这一来一回的过程当中, 存在两次缓冲写入和读取, 就算不计算读出的时间, 单纯流入流出4MB, 就花掉700ms了, 那么1秒内, 只剩下300ms是业务处理的时间, 这么低的效率, 怎样提高并发量啊...

各位写高效WEB时, 都使用什么方法增加数据流量的?
...全文
1389 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
angel6709 2013-07-02
  • 打赏
  • 举报
回复
引用 6 楼 dfasri 的回复:
顶一下....上面的代码到底写错哪里导致缓冲写入那么慢呢..
循环10万次
qingtangq 2013-07-01
  • 打赏
  • 举报
回复
74646466
qp_xxxx_db 2011-06-20
  • 打赏
  • 举报
回复
jvm currentTimeMillis是不准的 好像最小感知时间是15ms左右 纳秒感知时间是800ns左右空转试试就知道 “4M的写入要花掉上百毫秒” 这个明显有问题 硬盘的响应速度也不止这样吧

抛开这些不说 如果在意响应速度多加些线程就就可可以了吧
zhangxianya1 2011-06-19
  • 打赏
  • 举报
回复
帮顶下
dfasri 2011-06-17
  • 打赏
  • 举报
回复
看来在JAVA..没有人去研究怎样写服务器的中间件...而是研究怎样用现成的服务较多...
dfasri 2011-06-13
  • 打赏
  • 举报
回复
依旧慢, 那个是预设缓冲大小用的, 设置大, 不用频繁重复申请内存我想会是最快的.
LoveVV99 2011-06-08
  • 打赏
  • 举报
回复
@dfasri:
我了解你的意图。不过还是要说明,问题可能出在我说的那个地方。建议你测试一下,确定是不是这个问题。

我说的第2种方式,可能没讲清楚,就是希望能通过减小缓冲的方式加快速度,原因如下:
java用什么buffer不太清楚,C里面对char数组的不同使用方法也会导致效率出现严重的区别。
比如用strncpy来拼接字符串,在目标buffer很大时,效率会急剧下降,原因是这个函数对buffer的未使用部分循环做了fill 0。
dfasri 2011-06-07
  • 打赏
  • 举报
回复
getBytes() 这个是必须在循环体里面执行的. 目的是在于测试10万次的字符串写入. 但写入什么字符串, 不是固定的, 只是测试的代码是固定而已.

回 LoveVV99:
话说你这么大的缓冲,用来做什么?瞬间发这么大流量,网卡还不被你撑死,1秒时间700ms网卡都空闲的,有点浪费了,最好能均匀使用网卡:)

这个不是测试网卡的性能, 目的是在于测试内存处理速度而已, 换个角度来说, 就是在于: 按网络1000Mb的速度来算, 换算就是128MB/s的数据传送率. 4M的写入要花掉上百毫秒, 或者采用 tianfang 的方式, 60ms算了, 也就是要是真有128MB的数据过来, 单纯用来接收数据就花掉不止一秒了...那么加上处理的时间, 1S的并发量就得降低了. 而且, 只要写入缓冲的时间越短, 也代表处理的时间可以增加. 假如写入4M的时间只为40ms, 那么这4M的数据里面, 假如存在1000个请求的数据, 并且回复的内容也是4M, 也代表这1000个请求会有 920 ms 的时候进行处理, 即每个请求会有0.92ms是可以用的. 假如4M数据就花掉200ms来写. 那么这1000个请求, 每个请求就只剩余0.6ms的处理时间了..., 缓冲写入慢, 是两倍递减的, 所以才会说慢..

大家都是用什么Buffer的?
tianfang 2011-06-07
  • 打赏
  • 举报
回复
我的笔记本CPU是T8300,运行代码用了170-200ms

先定义 byte[] buf11 = "测试字符串1号".getBytes();再写buf11 ,执行时间是60-70ms


循环中做getBytes()转换,开销相当很高
LoveVV99 2011-06-07
  • 打赏
  • 举报
回复
俺搞c的,没了解过java的ByteArrayOutputStream 是怎么实现的,估计问题在这里。
它的底层实现估计每次都会进行一些诸如strlen或者memset之类的操作,导致对大缓存的性能下降。
可以:
1、看看源码是否有类似的问题
2、搞一个小一点的buffer,加一层循环,比如4K的buffer,再加一个1K的外层循环试试看
如果有问题,可能要考虑换封包的方式,或者换buffer类了
纯属猜测,仅供参考

话说你这么大的缓冲,用来做什么?瞬间发这么大流量,网卡还不被你撑死,1秒时间700ms网卡都空闲的,有点浪费了,最好能均匀使用网卡:)
dfasri 2011-06-07
  • 打赏
  • 举报
回复
上面的连SOCKET都没用, 单纯写个缓冲而已, 就用 ByteArrayOutputStream 这个类来写. 都这么慢...
夜魔009 2011-06-03
  • 打赏
  • 举报
回复
高并发你不能用java自带的socket,自带的socket是阻塞式的,效率低。无法满足WEB类型的高请求服务。必须用非阻塞式TCP/IP通信模式
dfasri 2011-06-01
  • 打赏
  • 举报
回复
顶一下....上面的代码到底写错哪里导致缓冲写入那么慢呢..
dfasri 2011-05-31
  • 打赏
  • 举报
回复
代码如下:

package com.ninetech.be.web.action;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

public class Test1 {

/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
ByteArrayOutputStream bb1 = new ByteArrayOutputStream(4000000);
byte[] buf1 = new byte[1];
byte[] buf2 = new byte[2];
byte[] buf4 = new byte[4];
byte[] buf8 = mew bute[8];
int i = 0;
long s = System.currentTimeMillis();
while (i < 100000) {
bb1.write(buf1);
bb1.write(buf2);
bb1.write(buf4);
bb1.write(buf8);
bb1.write("测试字符串1号".getBytes()); // 不知道怎样强制变换写入ANSI...
bb1.write("测试字符串2号".getBytes());
i++;
}
long e = System.currentTimeMillis();
System.out.println("time: " + (e-s));
}

}


就这样的一段代码, 就要花350ms来完成...
dfasri 2011-05-31
  • 打赏
  • 举报
回复
没有写网络或者硬盘...
就是JAVA里面的内存BUFFER而已.
先是写BYTE大小, 再写WORD大小, 再写DWORD大小, 再写一个18长度的ANSI字符串, 再写一个36长度的UTF-16字符串, 最外层就一个循环10万次, 就这样简单, 直接编译运行, Release就大概250ms...
而且运行的机器也不算差的. 这个总大小就是45MB左右...
阿星777 2011-05-31
  • 打赏
  • 举报
回复
这个350ms的时间,是怎么来的,需要看看瓶颈在哪里,是硬盘IO还是网络IO。
dfasri 2011-05-30
  • 打赏
  • 举报
回复
JAVA区...似乎无人津...
jeky_zhang2013 2011-05-27
  • 打赏
  • 举报
回复
帮顶下~~~

25,988

社区成员

发帖
与我相关
我的任务
社区描述
高性能WEB开发
社区管理员
  • 高性能WEB开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧