最近有一个问题进行系统性能优化的时候来到。解析分享给大家后,。
我们socket当建立连接,假设我们不能将计算机连接到指定的站点,那么这将导致系统卡socket的connect在此方法。
我们都知道socket它需要三次握手建立连接。计算机server发送消息头,server返回。这时候socket基本连接成功。可是假设连接
不上的话这里会卡一个Timeout的时间。时间一到,方法返回失败,socket默认的timeout好像是20秒,
我们系统如今有一个从可用的ip列表里面检測出一个可用的ip,拿出来作为可用数据保存到内存。
之前我们是串行測试,一个不可用再去尝试下一个,这个操作将业务流程停止在这一步非常长时间。
如今改成并行測试,开启多个线程測试,有可用的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; /** * 资源探測器,从一组资源中检測出一个可用的资源 * * @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; } } /**创建探測一个资源的子线程*/ 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是启动一个服务端监听,大家能够自行实现。代码太多就不复制上去了
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(){ //创建一个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); } }
版权声明:本文博主原创文章,博客,未经同意不得转载。