使用AsyncRestTemplate進行非同步呼叫
阿新 • • 發佈:2019-01-07
背景:
最近專案中需要併發呼叫c++服務的http介面,問題是同時呼叫兩個介面時,會發生嚴重阻塞,導致頁面響應慢,還經常遇到接收資料超時,導致RestTemplate報出ReadTimeout錯誤,一味地增加ReadTimeout時間解決不了根本問題。
原使用的方案:
前一個版本中使用的是Feign,雖然響應速度方面還可以,但是唯一不足是,返回的資料只能以String接收,在每一個方法中進行String轉換成java物件的方法。
我是一個比較懶的程式設計師,不想寫很多無用的重複程式碼。所以在這次版本中決定使用RestTemplate,封裝一個RestClient工具類,所有呼叫第三方介面都通過該工具類提供的方法呼叫,返回的ResponseEntity通過指定的Class型別進行轉換並返回。
解決方案:
使用AsyncRestTemplate非同步呼叫介面,無阻塞進行請求。下面直接貼程式碼。
一、AsyncRestTemplate註冊為Bean,使Spring容器對其進行管理。
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.AsyncRestTemplate; @Configuration public class RestTemplateConfiguration { @Bean public AsyncRestTemplate asyncRestTemplate() { return new AsyncRestTemplate(); } }
此次採用的是AsyncRestTemplate預設的構造方法。會預設使用SimpleAsyncTaskExecutor。
二、編寫測試Controller類
import java.util.Date; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFutureCallback; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.AsyncRestTemplate; @RestController public class WebController { @Autowired private AsyncRestTemplate asyncRestTemplate; @RequestMapping("/demo") public String demo() { try { Thread.sleep(30000); } catch (Exception e) { e.printStackTrace(); } return new Date()+"--->>>30秒。。。。"; } @RequestMapping("/async") public String async() { String url = "http://127.0.0.1:8080/demo"; ListenableFuture<ResponseEntity<String>> forEntity = asyncRestTemplate.getForEntity(url, String.class); //非同步呼叫後的回撥函式 forEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() { //呼叫失敗 @Override public void onFailure(Throwable ex) { System.err.println("-----呼叫介面失敗-------"); } //呼叫成功 @Override public void onSuccess(ResponseEntity<String> result) { System.out.println("--->非同步呼叫成功, result = "+result.getBody()); } }); return new Date()+"--->>>非同步呼叫結束"; } }
三、呼叫async介面
16:15:20先返回非同步呼叫結束
而呼叫的方法時16:15:50,即休眠30秒後返回的。
僅供參考,後期對AsyncRestTemplate有更深入的瞭解繼續更新。。。