方法調用的默認超時時間為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