深入浅出Java分布式系统通信
作者:网络转载 发布时间:[ 2015/5/14 14:12:17 ] 推荐标签:开发语言
测试场景:
每个请求的业务处理时间110ms
300个线程300个连接并发测试,每个线程循环请求服务端
测试环境:
客户端服务器:
Cpu为4线程 2400mhz
服务端cpu: 4线程 3000Mhz
测试结果:
在经过10分钟测试之后,稳定情况下的tps
Tps:2332左右
客户端Cpu:90%
服务端cpu:250%
从测试结果可以看出,当连接数足够大的时候,系统性能会降低,开启的tcp连接数越多,那么
系统开销将会越大。
tcp长连接异步通信
通信图:
一个socket连接在同一时间内传输多次请求的信息,输入通道接收多条响应消息,消息是连续发出,连续收回的。
业务处理和发消息是异步的,一个业务线程告诉通道发送消息后,不再占用通道,而是等待响应到达,而此时其它
业务线程也可以往该连接通道发信息,这样可以充分利用通道来进行通信。
实现挑战
但该方案使编码变得复杂,如上图,请求request1,request2,request3顺序发出,但是服务端处理请求并不是
排队的,而是并行处理的,有可能request3先于request1响应给客户端,那么一个request将无法找到他的response,
这时候我们需要在request和response报文中添加标识,如通信序列号,在一个通信通道里面保持,
那么可以根据序列号去获取对应的响应报文。
我的方案是:
1.客户端获取一个tcp连接
2.调用session.write()发送信息,并将消息的序列号存入一个Result对象
result对象存入一个map
3.同步阻塞获取结果,线程在result对象进行同步阻塞
4.接收消息,并通过序列号从map里面获取result对象,并唤醒阻塞在result对象上的线程
客户端发送消息示例代码:
public TransInfo send(TransInfo info) throws InterruptedException {
Result result = new Result();
result.setInfo(info);
//获取socket连接
ConnectFuture connectFuture = ConnectFutureFactory
.getConnection(result);
IoSession session = connectFuture.getSession();
//将result放入ConcurrentHashMap
ConcurrentHashMap<Long, Result> resultMap = (ConcurrentHashMap<Long, Result>)session.getAttribute("resultMap");
resultMap.put(info.getId(), result);
//发送消息
session.write(info);
//同步阻塞获取结果
return result.synGetInfo();
}
同步阻塞和唤醒方法:
public synchronized TransInfo synGetInfo() {
//等待消息返回
//必须要在同步的情况下执行
while (!done) {
try {
wait();
} catch (InterruptedException e) {
log.error(e.getMessage(), e);
}
}
return info;
}
public synchronized void synSetInfo(TransInfo info) {
this.info = info;
this.done = true;
notify();
}
接收消息示例代码:
public void messageReceived(IoSession session, Object message)
throws Exception {
TransInfo info = (TransInfo) message;
//根据序列号从resultMap中获取result
ConcurrentHashMap<Long, Result> resultMap = (ConcurrentHashMap<Long, Result>)session.getAttribute("resultMap");
//移除result
Result result = resultMap.remove(info.getId());
//唤醒阻塞线程
result.synSetInfo(info);
}
测试场景:
每个请求的业务处理时间110ms
300个线程10个连接并发测试,每个线程循环请求服务端
测试环境:
客户端服务器:
Cpu为4线程 2400mhz
服务端cpu: 4线程 3000Mhz
测试结果:
在经过10分钟测试之后,稳定情况下的tps
Tps:2600左右
客户端Cpu:25%
服务端cpu:250%
经测试发现,异步通信可以用更少的tcp连接实现同样高效的通信,极大的减少了系统性能开销。
暂时写到这里。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11