最近做系统性能优化的时候遇到的1个问题,解决以后分享给大家。
我们通过socket建立连接的时候,如果我们计算机不能与指定的站点连接上,那末这将会致使系统卡在socket的connect这个方法上,
我们都知道socket建立连接需要3次握手,计算机向http://www.wfuyu.com/server/发送消息头,http://www.wfuyu.com/server/返回,这时候候socket基本连接成功,但是如果连接
不上的话这里会卡1个Timeout的时间,时间1到,方法返回失败,socket默许的timeout好像是20秒,
我们系统现在有1个从可用的ip列表里面检测出1个可用的ip,拿出来作为可用数据保存到内存。
之前我们是串行测试,1个不可用再去尝试下1个,这个操作将业务流程停止在这1步很长时间。
现在改成并行测试,开启多个线程测试,有可用的ip以后直接返回,这个检测操作的时间缩减到毫秒级,大大提升了系统性能。
具体代码以下:
资源接口:
package com.sunyard.frame.resource.base;
/**
* 可初始化的资源
*
* @author zhangWei
* @since 2014年10月29日 下午6:58:55
* @version zhw_1.1
*/
public abstract class InitAble {
/**
* 初始化
* @return true 初始化成功
*/
public abstract boolean init();
/**
* 烧毁该资源,如关闭连接等
*/
public abstract void destory();
}
探测器:
package com.sunyard.frame.resource;
import java.util.List;
import com.sunyard.frame.resource.base.InitAble;
import com.sunyard.frame.thread.ThreadPool;
import com.sunyard.frame.utils.ListUtils;
/**
* 资源探测器,从1组资源中检测出1个可用的资源
*
* @author zhangWei
* @since 2014年10月29日 下午7:00:45
* @version zhw_1.1
*/
public class ResourceDetector {
/**待检测的资源*/
private List<? extends InitAble> resources;
/**创建该对象的线程*/
private Thread mainThread;
/**探测结果*/
private InitAble result;
/**用于并发探测可用资源的线程池,可以用java的ExecutorService代替*/
private ThreadPool pool = new ThreadPool(10);
/**探测失败的记录数*/
private Integer failCount = 0;
public ResourceDetector(List<? extends InitAble> resources) {
super();
this.resources = resources;
this.mainThread = Thread.currentThread();
}
/**
* 探测器开始探测可用的资源
*
* @author zhangWei
* @since 2014年10月29日 下午7:20:21
*/
public InitAble detect(){
if(ListUtils.isNotEmpty(resources)){
for(InitAble i:resources){
pool.execute(createDetectTask(i));
}
synchronized (mainThread) {
try {
mainThread.wait();
} catch (InterruptedException e) {
}
}
return result;
} else {
return null;
}
}
/**创建探测1个资源的子线程*/
private Runnable createDetectTask(final InitAble i){
return new Runnable() {
@Override
public void run() {
try{
if(i.init()){
result = i;
synchronized (mainThread) {
mainThread.notify();
}
} else {
synchronized (failCount) {
if(++failCount == resources.size()){
synchronized (mainThread) {
mainThread.notify();
}
}
}
}
} finally {
i.destory();
}
}
};
}
}
测试类:
这里的 SocketDecorate是 InitAble的子类,ServerSocketProxy是启动1个服务端监听,大家可以自行实现,代码太多就不复制上去了
package test.resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import test.socket.ServerServiceImpl;
import junit.framework.TestCase;
import com.sunyard.frame.resource.ResourceDetector;
import com.sunyard.frame.socket.client.SocketDecorate;
import com.sunyard.frame.socket.server.ServerSocketProxy;
public class TestResource extends TestCase {
public void testDetect(){
//创建1个ServerSocket
ServerSocketProxy ss;
try {
ss = new ServerSocketProxy(1000, ServerServiceImpl.class, true);
ss.startServer();
} catch (IOException e) {
}
SocketDecorate d1 = new SocketDecorate("168.1.1.1", 1000);
SocketDecorate d2 = new SocketDecorate("168.1.1.2", 1000);
SocketDecorate d3 = new SocketDecorate("168.1.1.3", 1000);
SocketDecorate d4 = new SocketDecorate("168.1.1.4", 1000);
SocketDecorate d5 = new SocketDecorate("168.1.1.5", 1000);
SocketDecorate d6 = new SocketDecorate("168.1.1.6", 1000);
SocketDecorate d7 = new SocketDecorate("168.1.1.7", 1000);
SocketDecorate d8 = new SocketDecorate("127.0.0.1", 1000);
List<SocketDecorate> resources = new ArrayList<SocketDecorate>();
resources.add(d1);
resources.add(d2);
resources.add(d3);
resources.add(d4);
resources.add(d5);
resources.add(d6);
resources.add(d7);
resources.add(d8);
ResourceDetector detector = new ResourceDetector(resources);
SocketDecorate s = (SocketDecorate) detector.detect();
System.out.println(s);
}
}