1. 程式人生 > >使用AsyncRestTemplate進行非同步呼叫

使用AsyncRestTemplate進行非同步呼叫

背景:

    最近專案中需要併發呼叫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有更深入的瞭解繼續更新。。。