說明:
feign默認情況下使用的是JDK原始的URLConnection發送的HTTP請求,沒有使用到連接池,但是對每個地址會保持長連接,即HTTP的persistence connection。我們可以利用Apache的HTTP client替換原始的HTTP client,通過設置連接池,超時時間等,對服務調用進行調優。spring cloud從Brixtion.SR5版本之后支持這種替換操作。
1、使用Apache的HTTP client替換feign默認的client
a、項目依賴:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.3.RELEASE</version> <relativePath/> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Spring Cloud OpenFeign的Starter的依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- 使用Apache HttpClient替換Feign原生httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-httpclient</artifactId> <version>8.17.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
b、項目啟動類:
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.openfeign.EnableFeignClients; @SpringBootApplication @EnableFeignClients public class SpringCloudFeignApplication { public static void main(String[] args) { SpringApplication.run(SpringCloudFeignApplication.class, args); } }
c、編寫測試代碼:
client接口:
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; //https://api.caiyunapp.com/v2/TAkhjf8d1nlSlspN/121.6544,25.1552/forecast.json 彩雲天氣API @FeignClient(name = "caiyunapp", url = "https://api.caiyunapp.com/v2/TAkhjf8d1nlSlspN/121.6544,25.1552") public interface HelloFeignService { @RequestMapping(value = "/forecast.json", method = RequestMethod.GET) ResponseEntity<byte[]> searchRepo(); }
controller類:
import cn.springcloud.book.feign.service.HelloFeignService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloFeignController { @Autowired private HelloFeignService helloFeignService; // 服務消費者對位提供的服務 @GetMapping(value = "/search") public ResponseEntity<byte[]> searchGithubRepoByStr() { return helloFeignService.searchRepo(); } }
d、工程配置文件:
server:
port: 8011
spring:
application:
name: httpclient-demo
feign:
httpclient:
enabled: true
e、啟動工程,瀏覽器訪問接口:
說明替換默認client成功,接口正常訪問。
2、使用OKHTTP替換feign默認的client
OKHTTP是目前比較火的一個HTTP客戶端,具有以下優點:
- 支持SPDY,可以合並多個到同一主機的請求。
- 使用連接池技術減少請求延遲。
- 使用GZIP壓縮減少傳輸數據量。
- 緩存響應避免重復請求。
a、項目依賴:
跟上面的依賴類似,排除下面的依賴:
<!-- 使用OKHTTP無需這2個依賴 -->
<!-- 使用Apache HttpClient替換Feign原生httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-httpclient</artifactId> <version>8.17.0</version> </dependency>
加上下面的配置:
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency>
b、在上面的代碼編寫基礎上,編寫一個配置類,如下:
import feign.Feign; import okhttp3.ConnectionPool; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.cloud.openfeign.FeignAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.concurrent.TimeUnit; @Configuration @ConditionalOnClass(Feign.class) @AutoConfigureBefore(FeignAutoConfiguration.class) public class FeignOkHttpConfig { @Bean public okhttp3.OkHttpClient okHttpClient(){ return new okhttp3.OkHttpClient.Builder() //設置連接超時 .connectTimeout(60, TimeUnit.SECONDS) //設置讀超時 .readTimeout(60, TimeUnit.SECONDS) //設置寫超時 .writeTimeout(60,TimeUnit.SECONDS) //是否自動重連 .retryOnConnectionFailure(true) .connectionPool(new ConnectionPool()) //構建OkHttpClient對象 .build(); } }
c、配置文件:
server:
port: 8011
spring:
application:
name: okhttp-demo
feign:
httpclient:
enabled: false
okhttp:
enabled: true
d、啟動項目,訪問接口,即可正常獲取到數據,表明替換成功。