spring中WebClient如何設(shè)置連接超時(shí)時(shí)間以及讀取超時(shí)時(shí)間
前言
在Spring WebFlux中,WebClient
提供了一種靈活的方式來(lái)配置連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間。你可以使用 reactor.netty.http.client.HttpClient
來(lái)進(jìn)行這些配置。以下是如何設(shè)置連接超時(shí)和讀取超時(shí)的示例代碼:
import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import java.time.Duration; public class WebClientConfig { public WebClient createWebClient() { HttpClient httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) .responseTimeout(Duration.ofMillis(10000)); // 讀取超時(shí) return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
詳細(xì)說(shuō)明
導(dǎo)入所需包:
org.springframework.web.reactive.function.client.WebClient
reactor.netty.http.client.HttpClient
java.time.Duration
創(chuàng)建HttpClient:
- 使用
HttpClient.create()
創(chuàng)建一個(gè)新的HttpClient
實(shí)例。 - 使用
option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
設(shè)置連接超時(shí)時(shí)間為5000毫秒(5秒)。 - 使用
responseTimeout(Duration.ofMillis(10000))
設(shè)置讀取超時(shí)時(shí)間為10000毫秒(10秒)。
配置WebClient:
- 使用
WebClient.builder()
創(chuàng)建一個(gè)新的WebClient.Builder
實(shí)例。 - 使用
clientConnector(new ReactorClientHttpConnector(httpClient))
將自定義的HttpClient
設(shè)置為WebClient
的客戶端連接器。 - 使用
build()
方法構(gòu)建WebClient
實(shí)例。
完整的示例類
import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.TcpClient; import io.netty.channel.ChannelOption; import java.time.Duration; public class WebClientConfig { public WebClient createWebClient() { TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(10)) .addHandlerLast(new WriteTimeoutHandler(10))); HttpClient httpClient = HttpClient.from(tcpClient); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
解釋
- TcpClient:用于配置底層的TCP連接參數(shù),包括連接超時(shí)。
- ReadTimeoutHandler 和 WriteTimeoutHandler:用于設(shè)置讀取和寫入的超時(shí)時(shí)間(以秒為單位)。
通過(guò)上述配置,你可以成功地設(shè)置 WebClient
的連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間。在生產(chǎn)環(huán)境中,可以根據(jù)需要調(diào)整這些超時(shí)時(shí)間,以適應(yīng)不同的網(wǎng)絡(luò)條件和服務(wù)端性能。
HttpClient httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) .responseTimeout(Duration.ofMillis(10000)); // 讀取超時(shí) 這一段 HttpClient 沒(méi)有這個(gè)方法的啊,尤其是option
對(duì)于 Spring WebFlux 中的 WebClient
配置連接超時(shí)和讀取超時(shí),最新版本的 reactor.netty.http.client.HttpClient
可能不再直接支持 option
方法。你可以通過(guò) TcpClient
來(lái)設(shè)置這些超時(shí)選項(xiàng)。以下是使用 TcpClient
和 HttpClient
來(lái)設(shè)置連接超時(shí)和讀取超時(shí)的完整示例:
import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.TcpClient; import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import java.time.Duration; public class WebClientConfig { public WebClient createWebClient() { // 配置連接超時(shí)和讀取超時(shí) TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(10)) // 讀取超時(shí) .addHandlerLast(new WriteTimeoutHandler(10))); // 寫入超時(shí) // 使用自定義的 TcpClient 創(chuàng)建 HttpClient HttpClient httpClient = HttpClient.from(tcpClient) .responseTimeout(Duration.ofMillis(10000)); // 讀取超時(shí) // 創(chuàng)建 WebClient 并設(shè)置自定義的 HttpClient return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
關(guān)鍵點(diǎn)解釋
TcpClient:
TcpClient.create()
創(chuàng)建一個(gè)新的TcpClient
實(shí)例。option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
設(shè)置連接超時(shí)時(shí)間為 5000 毫秒(5 秒)。doOnConnected
配置在連接建立后添加ReadTimeoutHandler
和WriteTimeoutHandler
,分別設(shè)置讀取超時(shí)和寫入超時(shí)。
HttpClient:
HttpClient.from(tcpClient)
使用配置好的TcpClient
創(chuàng)建一個(gè)HttpClient
實(shí)例。responseTimeout(Duration.ofMillis(10000))
設(shè)置讀取超時(shí)時(shí)間為 10000 毫秒(10 秒)。
WebClient:
- 使用
WebClient.builder()
創(chuàng)建一個(gè)新的WebClient.Builder
實(shí)例。 - 使用
clientConnector(new ReactorClientHttpConnector(httpClient))
將自定義的HttpClient
設(shè)置為WebClient
的客戶端連接器。 - 使用
build()
方法構(gòu)建WebClient
實(shí)例。
完整示例類
import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.TcpClient; import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import java.time.Duration; public class WebClientConfig { public WebClient createWebClient() { // 配置連接超時(shí)和讀取超時(shí) TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(10)) // 讀取超時(shí) .addHandlerLast(new WriteTimeoutHandler(10))); // 寫入超時(shí) // 使用自定義的 TcpClient 創(chuàng)建 HttpClient HttpClient httpClient = HttpClient.from(tcpClient) .responseTimeout(Duration.ofMillis(10000)); // 讀取超時(shí) // 創(chuàng)建 WebClient 并設(shè)置自定義的 HttpClient return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
通過(guò)這種方式,你可以設(shè)置 WebClient
的連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間。注意,這里的讀取超時(shí)是通過(guò) ReadTimeoutHandler
配置的,它會(huì)在指定時(shí)間內(nèi)沒(méi)有數(shù)據(jù)讀取時(shí)觸發(fā)超時(shí)。
SPring 5.2.8 版本,使用WebClient 如何設(shè)置連接超時(shí)時(shí)間,和讀取超時(shí)時(shí)間
在Spring 5.2.8版本中,WebClient
的配置可以通過(guò) TcpClient
和 HttpClient
來(lái)設(shè)置連接超時(shí)和讀取超時(shí)。以下是一個(gè)完整的示例,展示如何在Spring 5.2.8中配置 WebClient
的連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間。
示例代碼
import org.springframework.web.reactive.function.client.WebClient; import reactor.netty.http.client.HttpClient; import reactor.netty.tcp.TcpClient; import io.netty.channel.ChannelOption; import io.netty.handler.timeout.ReadTimeoutHandler; import io.netty.handler.timeout.WriteTimeoutHandler; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import java.time.Duration; public class WebClientConfig { public WebClient createWebClient() { // 配置 TcpClient TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 連接超時(shí) .doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(10)) // 讀取超時(shí) .addHandlerLast(new WriteTimeoutHandler(10))); // 寫入超時(shí) // 配置 HttpClient HttpClient httpClient = HttpClient.from(tcpClient) .responseTimeout(Duration.ofMillis(10000)); // 讀取超時(shí) // 配置 WebClient return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
詳細(xì)說(shuō)明
導(dǎo)入所需的包:
org.springframework.web.reactive.function.client.WebClient
reactor.netty.http.client.HttpClient
reactor.netty.tcp.TcpClient
io.netty.channel.ChannelOption
io.netty.handler.timeout.ReadTimeoutHandler
io.netty.handler.timeout.WriteTimeoutHandler
org.springframework.http.client.reactive.ReactorClientHttpConnector
java.time.Duration
配置 TcpClient:
TcpClient.create()
:創(chuàng)建一個(gè)新的TcpClient
實(shí)例。option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
:設(shè)置連接超時(shí)時(shí)間為5000毫秒(5秒)。doOnConnected
:配置在連接建立后添加ReadTimeoutHandler
和WriteTimeoutHandler
,分別設(shè)置讀取超時(shí)和寫入超時(shí)。
配置 HttpClient:
HttpClient.from(tcpClient)
:使用配置好的TcpClient
創(chuàng)建一個(gè)HttpClient
實(shí)例。responseTimeout(Duration.ofMillis(10000))
:設(shè)置讀取超時(shí)時(shí)間為10000毫秒(10秒)。
配置 WebClient:
WebClient.builder()
:創(chuàng)建一個(gè)新的WebClient.Builder
實(shí)例。clientConnector(new ReactorClientHttpConnector(httpClient))
:將自定義的HttpClient
設(shè)置為WebClient
的客戶端連接器。build()
:構(gòu)建WebClient
實(shí)例。
通過(guò)以上配置,你可以在Spring 5.2.8中成功地設(shè)置 WebClient
的連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間。注意,這里的讀取超時(shí)是通過(guò) ReadTimeoutHandler
配置的,它會(huì)在指定時(shí)間內(nèi)沒(méi)有數(shù)據(jù)讀取時(shí)觸發(fā)超時(shí)。
spring 操作Redis中的Zset ,我要獲取大于某個(gè)分值的所有數(shù)據(jù),如何操作
在Spring Data Redis中,你可以使用RedisTemplate
或ReactiveRedisTemplate
來(lái)操作Redis中的Zset,并獲取大于某個(gè)分值的所有數(shù)據(jù)。下面是如何使用這兩種方式來(lái)實(shí)現(xiàn)這一需求的示例。
使用RedisTemplate
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import java.util.Set; @Service public class RedisZSetService { @Autowired private RedisTemplate<String, String> redisTemplate; public Set<ZSetOperations.TypedTuple<String>> getZSetByMinScore(String key, double minScore) { ZSetOperations<String, String> zSetOps = redisTemplate.opsForZSet(); return zSetOps.rangeByScoreWithScores(key, minScore, Double.MAX_VALUE); } }
使用ReactiveRedisTemplate
如果你使用的是Spring WebFlux,并希望使用反應(yīng)式編程模型,你可以使用ReactiveRedisTemplate
。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; @Service public class ReactiveRedisZSetService { @Autowired private ReactiveRedisTemplate<String, String> reactiveRedisTemplate; public Flux<ZSetOperations.TypedTuple<String>> getZSetByMinScore(String key, double minScore) { ZSetOperations<String, String> zSetOps = reactiveRedisTemplate.opsForZSet(); return zSetOps.rangeByScoreWithScores(key, minScore, Double.MAX_VALUE); } }
使用示例
假設(shè)你有一個(gè)RedisZSetService實(shí)例,以下是如何使用它來(lái)獲取大于某個(gè)分值的所有數(shù)據(jù):
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import java.util.Set; @RestController public class RedisController { @Autowired private RedisZSetService redisZSetService; @GetMapping("/getZSetByMinScore") public Set<TypedTuple<String>> getZSetByMinScore(@RequestParam String key, @RequestParam double minScore) { return redisZSetService.getZSetByMinScore(key, minScore); } }
詳細(xì)解釋
RedisTemplate 和 ZSetOperations:
RedisTemplate<String, String>
是Spring提供的用于與Redis進(jìn)行同步操作的模板類。ZSetOperations<String, String>
是專門用于操作有序集合(ZSet)的接口。rangeByScoreWithScores(key, minScore, Double.MAX_VALUE)
方法用于獲取有序集合中分值在minScore
和Double.MAX_VALUE
之間的所有元素及其分值。
ReactiveRedisTemplate 和 ZSetOperations:
ReactiveRedisTemplate<String, String>
是Spring提供的用于與Redis進(jìn)行異步操作的模板類。rangeByScoreWithScores(key, minScore, Double.MAX_VALUE)
方法返回一個(gè)Flux<ZSetOperations.TypedTuple<String>>
,用于異步流處理。
控制器層的使用:
RedisController
類提供一個(gè)RESTful接口,調(diào)用RedisZSetService
獲取大于某個(gè)分值的所有數(shù)據(jù)。
通過(guò)這些配置和代碼,你可以在Spring應(yīng)用程序中方便地操作Redis中的有序集合,并獲取大于某個(gè)分值的所有數(shù)據(jù)。
return zSetOps.rangeByScoreWithScores(key, minScore, Double.MAX_VALUE); 使用Double.Max 是否影響性能呢,
在使用 Double.MAX_VALUE
作為 Redis ZSet 操作的最大值時(shí),一般情況下性能不會(huì)受到顯著影響。Redis 是一個(gè)高性能的內(nèi)存數(shù)據(jù)庫(kù),處理范圍查詢時(shí)會(huì)利用跳表(skip list)數(shù)據(jù)結(jié)構(gòu)的特性來(lái)快速定位和遍歷元素。因此,對(duì)于大多數(shù)應(yīng)用場(chǎng)景,使用 Double.MAX_VALUE
作為上限并不會(huì)顯著影響性能。
然而,在極端情況下,如果有非常多的元素在這個(gè)范圍內(nèi),查詢的性能可能會(huì)受到影響。為了解決這種潛在的性能問(wèn)題,可以采取以下措施:
分頁(yè)查詢:如果查詢的結(jié)果集可能非常大,可以使用分頁(yè)(通過(guò)
ZRangeByScore
和LIMIT
參數(shù))來(lái)逐步獲取結(jié)果,避免一次性返回大量數(shù)據(jù)。索引優(yōu)化:確保 Redis 服務(wù)器有足夠的內(nèi)存,并且沒(méi)有進(jìn)行其他阻塞操作,可以提升查詢性能。
限制結(jié)果集:如果知道合理的最大值范圍,可以使用一個(gè)具體的最大值而不是
Double.MAX_VALUE
。
具體示例:分頁(yè)查詢
以下是使用分頁(yè)查詢的示例代碼:
使用RedisTemplate進(jìn)行分頁(yè)查詢
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import java.util.Set; @Service public class RedisZSetService { @Autowired private RedisTemplate<String, String> redisTemplate; public Set<ZSetOperations.TypedTuple<String>> getZSetByMinScoreWithPagination(String key, double minScore, long offset, long count) { ZSetOperations<String, String> zSetOps = redisTemplate.opsForZSet(); return zSetOps.rangeByScoreWithScores(key, minScore, Double.MAX_VALUE, offset, count); } }
使用ReactiveRedisTemplate進(jìn)行分頁(yè)查詢
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.ReactiveRedisTemplate; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.stereotype.Service; import reactor.core.publisher.Flux; @Service public class ReactiveRedisZSetService { @Autowired private ReactiveRedisTemplate<String, String> reactiveRedisTemplate; public Flux<ZSetOperations.TypedTuple<String>> getZSetByMinScoreWithPagination(String key, double minScore, long offset, long count) { ZSetOperations<String, String> zSetOps = reactiveRedisTemplate.opsForZSet(); return zSetOps.rangeByScoreWithScores(key, minScore, Double.MAX_VALUE, offset, count); } }
使用示例
假設(shè)你有一個(gè) RedisZSetService
實(shí)例,以下是如何使用它來(lái)進(jìn)行分頁(yè)查詢:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.data.redis.core.ZSetOperations.TypedTuple; import java.util.Set; @RestController public class RedisController { @Autowired private RedisZSetService redisZSetService; @GetMapping("/getZSetByMinScoreWithPagination") public Set<TypedTuple<String>> getZSetByMinScoreWithPagination( @RequestParam String key, @RequestParam double minScore, @RequestParam long offset, @RequestParam long count) { return redisZSetService.getZSetByMinScoreWithPagination(key, minScore, offset, count); } }
關(guān)鍵點(diǎn)解釋
分頁(yè)查詢:
rangeByScoreWithScores(key, minScore, Double.MAX_VALUE, offset, count)
方法用于獲取有序集合中分值在minScore
和Double.MAX_VALUE
之間的所有元素及其分值,并且從offset
開始獲取count
個(gè)元素。
性能優(yōu)化:
- 分頁(yè)查詢避免一次性返回大量數(shù)據(jù),可以提升查詢性能,特別是在數(shù)據(jù)量很大的情況下。
通過(guò)以上方式,可以更有效地處理大數(shù)據(jù)量的查詢,提升應(yīng)用的響應(yīng)速度和性能。
總結(jié)
到此這篇關(guān)于spring中WebClient如何設(shè)置連接超時(shí)時(shí)間以及讀取超時(shí)時(shí)間的文章就介紹到這了,更多相關(guān)spring WebClient設(shè)置連接超時(shí)時(shí)間內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺談java調(diào)用Restful API接口的方式
這篇文章主要介紹了淺談java調(diào)用Restful API接口的方式,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12解決跨域請(qǐng)求,NG返回403(403并不一定是NG問(wèn)題)
這篇文章主要介紹了解決跨域請(qǐng)求,NG返回403(403并不一定是NG問(wèn)題),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Java CompletableFuture 異步超時(shí)實(shí)現(xiàn)深入研究
這篇文章主要為大家介紹了Java CompletableFuture 異步超時(shí)實(shí)現(xiàn)深入研究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02Java獲得一個(gè)數(shù)組的指定長(zhǎng)度排列組合算法示例
這篇文章主要介紹了Java獲得一個(gè)數(shù)組的指定長(zhǎng)度排列組合算法,結(jié)合實(shí)例形式分析了java排列組合相關(guān)數(shù)組遍歷、運(yùn)算操作技巧,需要的朋友可以參考下2019-06-06SpringBoot實(shí)現(xiàn)分布式驗(yàn)證碼登錄方案小結(jié)
驗(yàn)證碼登錄作為一種有效的防護(hù)手段,可以防止惡意gongji、暴力pojie等,本文主要介紹了SpringBoot實(shí)現(xiàn)分布式驗(yàn)證碼登錄方案小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下2024-12-12Java注冊(cè)郵箱激活驗(yàn)證實(shí)現(xiàn)代碼
這篇文章主要介紹了Java注冊(cè)郵箱激活驗(yàn)證實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-12-12第一次使用Android Studio時(shí)你應(yīng)該知道的一切配置(推薦)
這篇文章主要介紹了第一次使用Android Studio時(shí)你應(yīng)該知道的一切配置(推薦) ,需要的朋友可以參考下2017-09-09