国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringCloud升級之路2020.0.x版-40. spock 單元測試封裝的 WebClie

番茄西紅柿 / 3212人閱讀

摘要:本系列代碼地址我們繼續(xù)上一節(jié),繼續(xù)使用測試我們自己封裝的測試針對重試測試針對重試針對響應(yīng)超時,我們需要驗(yàn)證重試僅針對可以重試的方法包括方法以及配置的可重試方法,針對不可重試的方法沒有重試。

本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent

我們繼續(xù)上一節(jié),繼續(xù)使用 spock 測試我們自己封裝的 WebClient

測試針對 readTimeout 重試

針對響應(yīng)超時,我們需要驗(yàn)證重試僅針對可以重試的方法(包括 GET 方法以及配置的可重試方法),針對不可重試的方法沒有重試。我們可以通過 spock 單元測試中,檢查對于負(fù)載均衡器獲取實(shí)例方法的調(diào)用次數(shù)看出來是否有重試

我們通過 httpbin.org 的 /delay/秒 實(shí)現(xiàn) readTimeout,分別驗(yàn)證:

  • 測試 GET 延遲 2 秒返回,超過讀取超時,這時候會重試
  • 測試 POST 延遲 3 秒返回,超過讀取超時,同時路徑在重試路徑中,這樣也是會重試的
  • 測試 POST 延遲 2 秒返回,超過讀取超時,同時路徑在重試路徑中,這樣不會重試

代碼如下:

@SpringBootTest(		properties = [				"webclient.configs.testServiceWithCannotConnect.baseUrl=http://testServiceWithCannotConnect",				"webclient.configs.testServiceWithCannotConnect.serviceName=testServiceWithCannotConnect",				"webclient.configs.testService.baseUrl=http://testService",				"webclient.configs.testService.serviceName=testService",				"webclient.configs.testService.responseTimeout=1s",				"webclient.configs.testService.retryablePaths[0]=/delay/3",				"webclient.configs.testService.retryablePaths[1]=/status/4*",				"spring.cloud.loadbalancer.zone=zone1",				"resilience4j.retry.configs.default.maxAttempts=3",				"resilience4j.circuitbreaker.configs.default.failureRateThreshold=50",				"resilience4j.circuitbreaker.configs.default.slidingWindowType=TIME_BASED",				"resilience4j.circuitbreaker.configs.default.slidingWindowSize=5",				//因?yàn)橹卦囀?3 次,為了防止斷路器打開影響測試,設(shè)置為正好比重試多一次的次數(shù),防止觸發(fā)				//同時我們在測試的時候也需要手動清空斷路器統(tǒng)計(jì)				"resilience4j.circuitbreaker.configs.default.minimumNumberOfCalls=4",				"resilience4j.circuitbreaker.configs.default.recordExceptions=java.lang.Exception"		],		classes = MockConfig)class WebClientUnitTest extends Specification {	@SpringBootApplication	static class MockConfig {	}	@SpringBean	private LoadBalancerClientFactory loadBalancerClientFactory = Mock()	@Autowired	private CircuitBreakerRegistry circuitBreakerRegistry	@Autowired	private Tracer tracer	@Autowired	private ServiceInstanceMetrics serviceInstanceMetrics	@Autowired	private WebClientNamedContextFactory webClientNamedContextFactory	//不同的測試方法的類對象不是同一個對象,會重新生成,保證互相沒有影響	def zone1Instance1 = new DefaultServiceInstance(instanceId: "instance1", host: "www.httpbin.org", port: 80, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	def zone1Instance2 = new DefaultServiceInstance(instanceId: "instance2", host: "www.httpbin.org", port: 8081, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	def zone1Instance3 = new DefaultServiceInstance(instanceId: "instance3", host: "httpbin.org", port: 80, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	RoundRobinWithRequestSeparatedPositionLoadBalancer loadBalancerClientFactoryInstance = Spy();	ServiceInstanceListSupplier serviceInstanceListSupplier = Spy();	//所有測試的方法執(zhí)行前會調(diào)用的方法	def setup() {		//初始化 loadBalancerClientFactoryInstance 負(fù)載均衡器		loadBalancerClientFactoryInstance.setTracer(tracer)		loadBalancerClientFactoryInstance.setServiceInstanceMetrics(serviceInstanceMetrics)		loadBalancerClientFactoryInstance.setServiceInstanceListSupplier(serviceInstanceListSupplier)	}	def "測試針對 readTimeout 重試"() {		given: "設(shè)置 testService 的實(shí)例都是正常實(shí)例"			loadBalancerClientFactory.getInstance("testService") >> loadBalancerClientFactoryInstance			serviceInstanceListSupplier.get() >> Flux.just(Lists.newArrayList(zone1Instance1, zone1Instance3))		when: "測試 GET 延遲 2 秒返回,超過讀取超時"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.get().uri("/delay/2").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientRequestException e) {				if (e.getCause() in  ReadTimeoutException) {					//讀取超時忽略				} else {					throw e;				}			}		then: "每次都會超時所以會重試,根據(jù)配置一共有 3 次"			3 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)		when: "測試 POST 延遲 3 秒返回,超過讀取超時,同時路徑在重試路徑中"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.post().uri("/delay/3").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientRequestException e) {				if (e.getCause() in  ReadTimeoutException) {					//讀取超時忽略				} else {					throw e;				}			}		then: "每次都會超時所以會重試,根據(jù)配置一共有 3 次"			3 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)		when: "測試 POST 延遲 2 秒返回,超過讀取超時,這個不能重試"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.post().uri("/delay/2").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientRequestException e) {				if (e.getCause() in  ReadTimeoutException) {					//讀取超時忽略				} else {					throw e;				}			}		then: "沒有重試,只有一次調(diào)用"			1 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)	}}

測試非 2xx 響應(yīng)碼返回的重試

對于非 2xx 的響應(yīng)碼,代表請求失敗,我們需要測試:

  • 測試 GET 返回 500,會有重試
  • 測試 POST 返回 500,沒有重試
  • 測試 POST 返回 400,這個請求路徑在重試路徑中,會有重試
@SpringBootTest(		properties = [				"webclient.configs.testServiceWithCannotConnect.baseUrl=http://testServiceWithCannotConnect",				"webclient.configs.testServiceWithCannotConnect.serviceName=testServiceWithCannotConnect",				"webclient.configs.testService.baseUrl=http://testService",				"webclient.configs.testService.serviceName=testService",				"webclient.configs.testService.responseTimeout=1s",				"webclient.configs.testService.retryablePaths[0]=/delay/3",				"webclient.configs.testService.retryablePaths[1]=/status/4*",				"spring.cloud.loadbalancer.zone=zone1",				"resilience4j.retry.configs.default.maxAttempts=3",				"resilience4j.circuitbreaker.configs.default.failureRateThreshold=50",				"resilience4j.circuitbreaker.configs.default.slidingWindowType=TIME_BASED",				"resilience4j.circuitbreaker.configs.default.slidingWindowSize=5",				//因?yàn)橹卦囀?3 次,為了防止斷路器打開影響測試,設(shè)置為正好比重試多一次的次數(shù),防止觸發(fā)				//同時我們在測試的時候也需要手動清空斷路器統(tǒng)計(jì)				"resilience4j.circuitbreaker.configs.default.minimumNumberOfCalls=4",				"resilience4j.circuitbreaker.configs.default.recordExceptions=java.lang.Exception"		],		classes = MockConfig)class WebClientUnitTest extends Specification {	@SpringBootApplication	static class MockConfig {	}	@SpringBean	private LoadBalancerClientFactory loadBalancerClientFactory = Mock()	@Autowired	private CircuitBreakerRegistry circuitBreakerRegistry	@Autowired	private Tracer tracer	@Autowired	private ServiceInstanceMetrics serviceInstanceMetrics	@Autowired	private WebClientNamedContextFactory webClientNamedContextFactory	//不同的測試方法的類對象不是同一個對象,會重新生成,保證互相沒有影響	def zone1Instance1 = new DefaultServiceInstance(instanceId: "instance1", host: "www.httpbin.org", port: 80, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	def zone1Instance2 = new DefaultServiceInstance(instanceId: "instance2", host: "www.httpbin.org", port: 8081, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	def zone1Instance3 = new DefaultServiceInstance(instanceId: "instance3", host: "httpbin.org", port: 80, metadata: Map.ofEntries(Map.entry("zone", "zone1")))	RoundRobinWithRequestSeparatedPositionLoadBalancer loadBalancerClientFactoryInstance = Spy();	ServiceInstanceListSupplier serviceInstanceListSupplier = Spy();	//所有測試的方法執(zhí)行前會調(diào)用的方法	def setup() {		//初始化 loadBalancerClientFactoryInstance 負(fù)載均衡器		loadBalancerClientFactoryInstance.setTracer(tracer)		loadBalancerClientFactoryInstance.setServiceInstanceMetrics(serviceInstanceMetrics)		loadBalancerClientFactoryInstance.setServiceInstanceListSupplier(serviceInstanceListSupplier)	}	def "測試非 200 響應(yīng)碼返回" () {		given: "設(shè)置 testService 的實(shí)例都是正常實(shí)例"			loadBalancerClientFactory.getInstance("testService") >> loadBalancerClientFactoryInstance			serviceInstanceListSupplier.get() >> Flux.just(Lists.newArrayList(zone1Instance1, zone1Instance3))		when: "測試 GET 返回 500"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.get().uri("/status/500").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientResponseException e) {				if (e.getStatusCode().is5xxServerError()) {					//5xx忽略				} else {					throw e;				}			}		then: "每次都沒有返回 2xx 所以會重試,根據(jù)配置一共有 3 次"			3 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)		when: "測試 POST 返回 500"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.post().uri("/status/500").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientResponseException e) {				if (e.getStatusCode().is5xxServerError()) {					//5xx忽略				} else {					throw e;				}			}		then: "POST 默認(rèn)不重試,所以只會調(diào)用一次"			1 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)		when: "測試 POST 返回 400,這個請求路徑在重試路徑中"			//清除斷路器影響			circuitBreakerRegistry.getAllCircuitBreakers().forEach({ c -> c.reset() })			try {				webClientNamedContextFactory.getWebClient("testService")											.post().uri("/status/400").retrieve()											.bodyToMono(String.class).block();			} catch (WebClientResponseException e) {				if (e.getStatusCode().is4xxClientError()) {					//4xx忽略				} else {					throw e;				}			}		then: "路徑在重試路徑中,所以會重試"			3 * loadBalancerClientFactoryInstance.getInstanceResponseByRoundRobin(*_)	}}

微信搜索“我的編程喵”關(guān)注公眾號,每日一刷,輕松提升技術(shù),斬獲各種offer

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/124546.html

相關(guān)文章

  • SpringCloud升級之路2020.0.x-40. spock 單元測試封裝 WebClie

    摘要:在上面打開一個微服務(wù)某個實(shí)例的一個路徑的斷路器之后,我們調(diào)用其他的路徑,無論多少次,都成功并且調(diào)用負(fù)載均衡器獲取服務(wù)實(shí)例的次數(shù)等于調(diào)用次數(shù),代表沒有重試,也就是沒有斷路器異常。 本系列代碼地址:??https://github.com/JoJoTec/spring-cloud-parent??我們來測試下前面封裝好的 We...

    番茄西紅柿 評論0 收藏2637
  • SpringCloud升級之路2020.0.x-37. 實(shí)現(xiàn)異步客戶端封裝配置管理意義與設(shè)計(jì)

    摘要:對于異步的請求,使用的是異步客戶端即。要實(shí)現(xiàn)的配置設(shè)計(jì)以及使用舉例要實(shí)現(xiàn)的配置設(shè)計(jì)以及使用舉例首先,我們要實(shí)現(xiàn)的,其包含三個重試重試的要在負(fù)載均衡之前,因?yàn)橹卦嚨臅r候,我們會從負(fù)載均衡器獲取另一個實(shí)例進(jìn)行重試,而不是在同一個實(shí)例上重試多次。 本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent 為何需要封裝異步 HT...

    fxp 評論0 收藏0
  • SpringCloud升級之路2020.0.x-36. 驗(yàn)證斷路器正確性

    摘要:本系列代碼地址上一節(jié)我們通過單元測試驗(yàn)證了線程隔離的正確性,這一節(jié)我們來驗(yàn)證我們斷路器的正確性,主要包括驗(yàn)證配置正確加載即我們在配置例如中的加入的的配置被正確加載應(yīng)用了。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent上一節(jié)我們通過單元測試驗(yàn)證了線程隔離的正確性,這一節(jié)我們來驗(yàn)證我們斷路器的正確性,主要包括:驗(yàn)證配置正確加載:即我們...

    NotFound 評論0 收藏0
  • SpringCloud升級之路2020.0.x-41. SpringCloudGateway 基本

    摘要:將請求封裝成將請求封裝成的接口定義是但是最外層傳進(jìn)來的參數(shù)是和,需要將他們封裝成,這個工作就是在中做的。其實(shí)主要任務(wù)就是將各種參數(shù)封裝成除了和本次請求相關(guān)的和,還有會話管理器,編碼解碼器配置,國際化配置還有用于擴(kuò)展。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent接下來,將進(jìn)入我們升級之路的又一大模塊,即網(wǎng)關(guān)模塊。網(wǎng)關(guān)模塊我們廢棄了...

    不知名網(wǎng)友 評論0 收藏0
  • SpringCloud升級之路2020.0.x-41. SpringCloudGateway 基本

    摘要:在這里,會將上下文中載入的拼接成,然后調(diào)用其方法的,它是的處理請求業(yè)務(wù)的起點(diǎn)。添加相關(guān)依賴之后,會有這個。路由權(quán)重相關(guān)配置功能相關(guān)實(shí)現(xiàn)類,這個我們這里不關(guān)心。本系列代碼地址:https://github.com/JoJoTec/spring-cloud-parent我們繼續(xù)分析上一節(jié)提到的 WebHandler,經(jīng)過將請求封裝成 ServerWebExchange 的 HttpWebHand...

    不知名網(wǎng)友 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<