跟我學SpringCloud | 第二十篇:Spring Cloud 之 okhttp

1. 什麼是 okhttp ?

okhttp 是由 square 公司開源的一個 http 客戶端。在 Java 平臺上,Java 標準庫提供了 HttpURLConnection 類來支持 HTTP 通信。不過 HttpURLConnection 自己的 API 不夠友好,所提供的功能也有限。大部分 Java 程序都選擇使用 Apache 的開源項目 HttpClient 做爲 HTTP 客戶端。Apache HttpClient 庫的功能強大,使用率也很高。java

2. 爲何要使用 okhttp ?

okhttp 的設計初衷就是簡單和高效,這也是咱們選擇它的重要緣由之一。它的優點以下:git

  • 支持 HTTP/2 協議。
  • 容許鏈接到同一個主機地址的全部請求,提升請求效率。
  • 共享Socket,減小對服務器的請求次數。
  • 經過鏈接池,減小了請求延遲。
  • 緩存響應數據來減小重複的網絡請求。
  • 減小了對數據流量的消耗。
  • 自動處理GZip壓縮。

3. 實戰目標

  • Feign 中使用 okhttp 替代 httpclient
  • Zuul 中使用 okhttp 替代 httpclient

4. 在 Feign 中使用 okhttp

首先介紹一下工程結構,本演示工程包含 provider-server、consumer-server、eureka-server 和 zuul-server 。github

4.1 consumer-server 依賴 pom.xml 以下:

代碼清單:chapter19/consumer-server/pom.xmlspring


<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-okhttp</artifactId>
    </dependency>
</dependencies>
  • feign-okhttp 這裏無需指定版本,目前引入的 feign-okhttp 版本爲 10.2.3 ,而 okhttp 的版本爲 3.8.1 ,如圖:

4.2 配置文件 application.yml

代碼清單:chapter19/consumer-server/src/main/resources/application.ymldocker


feign:
  httpclient:
    enabled: false
  okhttp:
    enabled: true
  • 在配置文件中需關閉 feign 對 httpclient 的使用並開啓 okhttp 。

4.3 配置類 OkHttpConfig.java

代碼清單:chapter19/consumer-server/src/main/java/com/springcloud/consumerserver/config/OkHttpConfig.java瀏覽器


@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class OkHttpConfig {

    @Bean
    public OkHttpClient okHttpClient(){
        return new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .retryOnConnectionFailure(true)
                .connectionPool(new ConnectionPool(10 , 5L, TimeUnit.MINUTES))
                .addInterceptor(new OkHttpLogInterceptor())
                .build();
    }
}
  • 在配置類中將 OkHttpClient 注入 Spring 的容器中,這裏咱們指定了鏈接池的大小,最大保持鏈接數爲 10 ,而且在 5 分鐘不活動以後被清除。
  • 筆者這裏配置了一個 okhttp 的日誌攔截器。

4.4 日誌攔截器 OkHttpLogInterceptor.java

代碼清單:緩存


@Slf4j
public class OkHttpLogInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        log.info("OkHttpUrl : " + chain.request().url());
        return chain.proceed(chain.request());
    }
}
  • 這裏實現的接口是 okhttp3.Interceptor ,並非 Spring Boot 中的 Interceptor。
  • 筆者這裏僅簡單打印了 okhttp 請求的路徑,若是有業務校驗權限等需求能夠放在攔截器中實現。

遠程 Feign 調用代碼略過,有須要的讀者能夠訪問 Github 倉庫獲取。服務器

5. 在 Zuul 中使用 okhttp

5.1 pom.xml 加入 okhttp 依賴

代碼清單:chapter19/zuul-server/pom.xml網絡


<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

5.2 配置文件開啓 okhttp

代碼清單:chapter19/zuul-server/src/main/resources/application.ymlapp


ribbon:
  http:
    client:
      enabled: false
  okhttp:
    enabled: true
  • 由於 Zuul 的負載均衡實現是經過 Ribbon 實現的,因此 Http 客戶端的配置天然也是對 Ribbon 組件的配置。

6. 測試

咱們修改 idea 啓動配置,分別在 8000 和 8001 端口啓動 provider-server ,而且順次啓動其他工程,打開瀏覽器訪問連接:http://localhost:8080/consumer/hello ,屢次刷新,能夠看到 Hello Spring Cloud! Port : 8000Hello Spring Cloud! Port : 8001 交替書出現,能夠證實負載均衡已經成功,能夠查看 consumer-server 的日誌,以下:

2019-09-23 23:15:27.097  INFO 10536 --- [nio-9000-exec-5] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8001/hello
2019-09-23 23:15:27.593  INFO 10536 --- [nio-9000-exec-6] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8000/hello
2019-09-23 23:15:27.942  INFO 10536 --- [nio-9000-exec-7] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8001/hello
2019-09-23 23:15:28.251  INFO 10536 --- [nio-9000-exec-9] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8000/hello
2019-09-23 23:15:47.877  INFO 10536 --- [nio-9000-exec-8] c.s.c.intercepter.OkHttpLogInterceptor   : OkHttpUrl : http://host.docker.internal:8001/hello

能夠看到咱們剛纔自定義的日誌正常打印,證實如今訪問確實是經過 okhttp 來進行訪問的。

7. 示例代碼

示例代碼-Github

示例代碼-Gitee

相關文章
相關標籤/搜索