1. 什么是 okhttp ?
okhttp 是由 square 公司開源的一個 http 客戶端。在 Java 平臺上,Java 標準庫提供了 HttpURLConnection 類來支持 HTTP 通訊。不過 HttpURLConnection 本身的 API 不夠友好,所提供的功能也有限。大部分 Java 程序都選擇使用 Apache 的開源項目 HttpClient 作為 HTTP 客戶端。Apache HttpClient 庫的功能強大,使用率也很高。
2. 為什么要使用 okhttp ?
okhttp 的設計初衷就是簡單和高效,這也是我們選擇它的重要原因之一。它的優勢如下:
- 支持 HTTP/2 協議。
- 允許連接到同一個主機地址的所有請求,提高請求效率。
- 共享Socket,減少對服務器的請求次數。
- 通過連接池,減少了請求延遲。
- 緩存響應數據來減少重復的網絡請求。
- 減少了對數據流量的消耗。
- 自動處理GZip壓縮。
3. 實戰目標
- Feign 中使用 okhttp 替代 httpclient
- Zuul 中使用 okhttp 替代 httpclient
4. 在 Feign 中使用 okhttp
首先介紹一下工程結構,本演示工程包含 provider-server、consumer-server、eureka-server 和 zuul-server 。
4.1 consumer-server 依賴 pom.xml 如下:
代碼清單:chapter19/consumer-server/pom.xml
***
<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.yml
***
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.yml
***
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 : 8000 和 Hello 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
|轉載請注明來源地址:蜘蛛池出租 http://m.gzxyxkj.cn/專注于SEO培訓,快速排名黑帽SEO https://www.heimao.wiki
