参考dubbo用户手册,方法调用的默认超时时间为1s,但是具体的超时时间受限于服务端方法性能、服务端个数、客户端的并发数等因素,所以超时时间需要根据不同的场景进行调试。
基本步骤为:
- 测试服务端的TPS,单位为 任务数或线程个数/S,即每秒能够处理的任务数。TPS能够表示出每秒能够处理的任务个数。
- 根据客户端的并发量要求和服务端的服务能力设置超时时间。例如客户端并发量为R,单个服务端的服务能力为T,服务端的个数为N,那么超时时间 = R/(T*N) 。
具体调试步骤参考如下:
- 使用多线程机制测试服务端接口的TPS。我使用单元测试进行的测试,UserTestInstance可以用作中使用的XXXService可以使用dubbo接口的服务注入,也可以注入服务端的服务。
package tps; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import tps.support.DubboFutureTask; import tps.support.DubboThread; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by admin on 2015-12-27. */ public class UserTestInstance { @Autowired private XXXService xxxService ; private static int num = 500 ; //默认使用和线程个数相同的线程池,避免线程等待的时间 private ExecutorService executorService = Executors.newFixedThreadPool(num); //存储线程任务 private List<DubboFutureTask> futureTasks = new ArrayList<>(num) ; private long startTime ; @Before public void startTime(){ System.out.println() ; System.out.println("初始化调用线程。"); for (int i=0 ; i<num ; i++){ DubboThread dubboThread = new DubboThread() ; dubboThread.setXXXService(xxxService) ; dubboThread.setName("thread->"+(i+1)); //创建异步任务 DubboFutureTask futureTask = new DubboFutureTask(dubboThread) ; futureTasks.add(futureTask) ; } //创建完任务之后,开始计时 startTime = System.currentTimeMillis() ; } @After public void endTime(){ boolean flag = true ; while (flag){ flag = false ; for (DubboFutureTask futureTask : futureTasks) { //如果有一个没完成,则继续执行 if(!futureTask.isDone()){ flag = true ; break ; } } } //等待所有任务完成之后,停止计时 double consumeTime = (System.currentTimeMillis() - startTime)/1000.0 ; System.out.println("线程数:"+futureTasks.size()+" , 共消耗时间:"+consumeTime+"s" +" , 异常数量:"+DubboThread.TIMEOUT_NUM.get()); System.out.println("TPS:"+num/consumeTime); } @Test public void testTPS(){ //提交任务请求到线程池 for (DubboFutureTask futureTask : futureTasks) { executorService.submit(futureTask) ; } } }
package tps.support; import lombok.Getter; import lombok.Setter; import java.util.concurrent.FutureTask; /** * Created by admin on 2015-12-27. */ @Setter @Getter public class DubboFutureTask extends FutureTask<Object> { private DubboThread dubboThread ; public DubboFutureTask(DubboThread dubboThread) { super(dubboThread) ; this.dubboThread = dubboThread ; } }
package tps.support; import com.glodon.framework.common.util.JsonMapper; import lombok.Getter; import lombok.Setter; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; /** * Created by admin on 2015-12-21. */ @Setter @Getter public class DubboThread implements Callable<Object> { public static final AtomicInteger TIMEOUT_NUM = new AtomicInteger(0) ; private XXXService xxxService ; private String name ; @Override public Object call() throws Exception { XXXEntity xxx = null ; try { xxx= xxxService.login("superman" , "123456") ; System.out.println("线程名称-> "+getName()+" -> "+ JsonMapper.toJSONString(xxx)); }catch (Exception e){ //异常数量 TIMEOUT_NUM.incrementAndGet() ; e.printStackTrace(); } return xxx ; } }
- 根据服务端性能、个数和客户端的并发要求,就可以计算出具体的timeout的值了。
注:
- dubbo用户手册 : http://dubbo.io/User+Guide-zh.htm