精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Spring Boot 集成第三方 API:超時與重試機制設計與實踐

開發 前端
超時機制的核心是為API請求設置最大容忍時間,一旦超過該時間仍未獲得響應,則主動終止請求并拋出異常,釋放線程資源。在Spring Boot中,不同的HTTP客戶端(RestTemplate、WebClient、Feign)對應不同的超時配置方式,需根據實際使用場景選擇。

前言

在分布式系統架構中,集成第三方API已成為業務開發的常態,例如支付接口、地圖服務、短信網關等。然而,第三方API的穩定性受網絡波動、服務負載、維護升級等多種因素影響,極易出現請求超時、響應失敗等問題。若缺乏有效的容錯機制,這些問題可能導致業務中斷、數據不一致甚至系統雪崩。

為什么必須設計超時與重試機制?

在集成第三方API時,以下問題是開發中必然面臨的挑戰,也是超時與重試機制的設計初衷:

  • 網絡不確定性:跨網絡請求可能因DNS解析延遲、路由丟包、防火墻攔截等導致請求卡殼;
  • 服務不穩定:第三方服務可能因峰值負載、數據庫故障、代碼Bug導致響應緩慢或直接返回5xx錯誤;
  • 資源耗盡風險:若未設置超時,長時間阻塞的線程會占用線程池資源,最終導致系統無法處理新請求;
  • 瞬時故障恢復:部分失?。ㄈ缇W絡閃斷、服務臨時過載)屬于瞬時問題,重試一次即可成功,無需人工介入。

因此,超時機制用于及時止損,避免資源浪費;重試機制用于修復瞬時故障,提升請求成功率。二者結合是保障第三方API調用穩定性的核心手段。

如何避免無限等待?

超時機制的核心是為API請求設置最大容忍時間,一旦超過該時間仍未獲得響應,則主動終止請求并拋出異常,釋放線程資源。在Spring Boot中,不同的HTTP客戶端(RestTemplate、WebClient、Feign)對應不同的超時配置方式,需根據實際使用場景選擇。

超時時間的設計原則

設置合理的超時時間是關鍵,需避免兩個極端:

  • 超時過短:正常網絡延遲下也會觸發超時,導致誤殺正常請求;
  • 超時過長:無法及時釋放線程,增加系統資源耗盡風險。

建議設計思路:

  • 參考第三方API的官方文檔(通常會給出平均響應時間和SLA承諾);
  • 結合自身業務容忍度(如支付接口需更敏感,非核心查詢接口可適當放寬);
  • 通過壓測或線上監控統計99%請求的響應時間,在此基礎上增加20%-50%的緩沖(如99%響應時間為500ms,可設置超時時間為700ms-1000ms)。

基于 RestTemplate 的超時配置

RestTemplate是Spring Boot早期常用的同步HTTP客戶端,需通過ClientHttpRequestFactory配置超時參數(默認無超時,存在極大風險)。

@Configuration
public class RestTemplateConfig {

    // 連接超時時間(單位:ms):建立TCP連接的最大時間
    private static final int CONNECT_TIMEOUT = 1000;
    // 讀取超時時間(單位:ms):建立連接后,等待響應數據的最大時間
    private static final int READ_TIMEOUT = 2000;

    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        // 設置連接超時
        factory.setConnectTimeout(CONNECT_TIMEOUT);
        // 設置讀取超時
        factory.setReadTimeout(READ_TIMEOUT);
        return new RestTemplate(factory);
    }
}

調用示例與異常處理

@Service
public class ThirdPartyApiService {

    @Autowired
    private RestTemplate restTemplate;

    public String callPaymentApi(String orderId) {
        String apiUrl = "https://api.thirdparty.com/pay?orderId=" + orderId;
        try {
            // 發起同步請求,超時會拋出ResourceAccessException
            return restTemplate.getForObject(apiUrl, String.class);
        } catch (ResourceAccessException e) {
            // 超時或網絡異常處理(如記錄日志、返回失敗狀態)
            log.error("調用支付API超時,訂單ID:{}", orderId, e);
            throw new BusinessException("支付請求超時,請稍后重試");
        } catch (Exception e) {
            // 其他異常處理(如4xx參數錯誤、5xx服務錯誤)
            log.error("調用支付API失敗,訂單ID:{}", orderId, e);
            throw new BusinessException("支付請求失敗,請檢查訂單信息");
        }
    }
}

基于 WebClient 的超時配置

WebClient是Spring WebFlux提供的異步非阻塞HTTP客戶端,適用于高并發場景,其超時配置通過ClientHttpConnector實現,支持更細粒度的時間控制(如連接超時、讀取超時、寫入超時)。

@Configuration
public class WebClientConfig {

    // 連接超時(ms)
    private static final int CONNECT_TIMEOUT = 1000;
    // 讀取超時(ms)
    private static final int READ_TIMEOUT = 2000;
    // 寫入超時(ms)
    private static final int WRITE_TIMEOUT = 1000;

    @Bean
    public WebClient webClient() {
        // 基于Netty配置超時參數
        HttpClient httpClient = HttpClient.create()
                // 連接超時
                .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT)
                // 讀取超時:指定時間內未讀取到數據則超時
                .doOnConnected(conn -> conn.addHandlerLast(
                        new ReadTimeoutHandler(READ_TIMEOUT, TimeUnit.MILLISECONDS)
                ))
                // 寫入超時:指定時間內未寫入數據則超時
                .doOnConnected(conn -> conn.addHandlerLast(
                        new WriteTimeoutHandler(WRITE_TIMEOUT, TimeUnit.MILLISECONDS)
                ));

        return WebClient.builder()
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .baseUrl("https://api.thirdparty.com") // 第三方API基礎路徑
                .build();
    }
}
異步調用與超時處理

WebClient 的異步調用通過響應式流(Mono/Flux)實現,超時異常需通過onErrorResume或retryWhen處理:

@Service
public class AsyncThirdPartyService {

    @Autowired
    private WebClient webClient;

    public Mono<String> callMapApi(String address) {
        return webClient.get()
                .uri("/map/geocode?address={address}", address)
                .retrieve()
                .bodyToMono(String.class)
                .onErrorResume(ex -> {
                    // 捕獲超時異常(WebClientRequestException包含超時場景)
                    if (ex instanceof WebClientRequestException && ex.getMessage().contains("timeout")) {
                        log.error("調用地圖API超時,地址:{}", address, ex);
                        return Mono.error(new BusinessException("地圖服務超時,請稍后重試"));
                    }
                    // 其他異常處理
                    log.error("調用地圖API失敗,地址:{}", address, ex);
                    return Mono.error(new BusinessException("地圖服務異常,請檢查地址"));
                });
    }
}

基于 Feign 的超時配置

Feign是Spring Cloud生態中常用的聲明式HTTP客戶端,簡化了API調用代碼,其超時配置可通過配置文件(application.yml)直接設置,無需編寫代碼。

feign:
  client:
    config:
      # 全局超時配置(default表示對所有Feign客戶端生效)
      default:
        connect-timeout: 1000  # 連接超時(ms)
        read-timeout: 2000     # 讀取超時(ms)
      # 局部超時配置(指定Feign客戶端名稱,如"payment-client")
      payment-client:
        connect-timeout: 1500
        read-timeout: 3000
Feign 客戶端定義與異常處理

Feign默認會將超時異常封裝為FeignException,可通過全局異常處理器統一處理:

// 1. 定義Feign客戶端
// name:Feign客戶端名稱(需與配置文件中局部配置的key一致)
@FeignClient(name = "payment-client", url = "https://api.thirdparty.com")
public interface PaymentFeignClient {

    @GetMapping("/pay")
    String doPayment(@RequestParam("orderId") String orderId);
}

// 2. 全局異常處理器(統一捕獲Feign超時異常)
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(FeignException.class)
    public Result<?> handleFeignException(FeignException e) {
        // 判斷是否為超時異常(Feign超時會返回504 Gateway Timeout)
        if (e.status() == 504) {
            log.error("Feign調用超時,異常信息:{}", e.getMessage(), e);
            return Result.fail("服務調用超時,請稍后重試");
        }
        // 其他Feign異常(如4xx、5xx)
        log.error("Feign調用失敗,狀態碼:{},異常信息:{}", e.status(), e.getMessage(), e);
        return Result.fail("服務調用異常,狀態碼:" + e.status());
    }
}

如何高效修復瞬時故障

重試機制的核心是對可重試的失敗請求進行自動重試,以修復瞬時故障(如網絡閃斷、服務臨時過載)。但重試并非越多越好,需避免因重試導致雪上加霜(如第三方服務已過載,重試會加劇負載)。

設計原則

  • 明確可重試場景:僅對瞬時故障重試,如網絡超時、5xx 服務錯誤;對確定性故障(如400參數錯誤、401權限不足)不重試,避免無效請求;
  • 控制重試次數:設置最大重試次數(如3次),防止無限重試導致死循環;
  • 采用退避策略:重試間隔逐步增加(如首次間隔100ms,第二次200ms,第三次400ms),減少對第三方服務的沖擊;
  • 保證冪等性:重試前必須確保請求是冪等的(即多次調用產生的效果與一次調用一致),例如支付接口需通過訂單號去重,避免重復扣款。

基于 Spring Retry 的重試實現

Spring Retry是Spring生態中輕量級的重試框架,支持注解式配置,可快速集成到Spring Boot項目中。

注解式配置重試策略
@Service
public class RetryableApiService {

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 調用第三方API并配置重試
     * @param orderId 訂單ID
     * @return API響應結果
     */
    @Retryable(
            value = {ResourceAccessException.class}, // 僅對超時異常(ResourceAccessException)重試
            maxAttempts = 3, // 最大重試次數(包含首次調用,即1次首次+2次重試)
            backoff = @Backoff(delay = 100, multiplier = 2) // 退避策略:首次延遲100ms,后續每次翻倍(100ms→200ms→400ms)
    )
    public String callRetryablePaymentApi(String orderId) {
        String apiUrl = "https://api.thirdparty.com/pay?orderId=" + orderId;
        log.info("第{}次調用支付API,訂單ID:{}", getRetryCount(), orderId);
        return restTemplate.getForObject(apiUrl, String.class);
    }

    /**
     * 重試失敗后的兜底方法(必須與@Retryable方法參數一致,且額外增加Throwable參數)
     * @param ex 重試過程中拋出的異常
     * @param orderId 訂單ID
     * @return 兜底返回結果
     */
    @Recover
    public String recoverPaymentApi(ResourceAccessException ex, String orderId) {
        log.error("支付API重試3次均失敗,訂單ID:{}", orderId, ex);
        // 兜底邏輯:如觸發人工介入、記錄失敗日志、返回默認失敗狀態
        return"PAY_FAILED";
    }

    /**
     * 獲取當前重試次數(通過Spring Retry的上下文)
     */
    private int getRetryCount() {
        org.springframework.retry.support.RetrySynchronizationManagerState state = 
                org.springframework.retry.support.RetrySynchronizationManager.getContext();
        return state != null ? state.getRetryCount() + 1 : 1;
    }
}
Feign 集成 Spring Retry 的重試實現

Feign 本身支持與Spring Retry集成,無需額外編寫重試邏輯,只需在配置文件中啟用重試并配置策略。

feign:
  client:
    config:
      payment-client:
        connect-timeout: 1000
        read-timeout: 2000
  retry:
    enabled: true # 啟用Feign重試
    max-attempts: 3 # 最大重試次數(1次首次+2次重試)
    interval: 100 # 初始重試間隔(ms)
    max-interval: 1000 # 最大重試間隔(ms)
    multiplier: 2 # 間隔倍數(100ms→200ms→400ms,不超過max-interval)

綜合案例:超時 + 重試 + 冪等性保障

在實際項目中,超時與重試需結合冪等性保障,避免重試導致業務異常(如重復支付)。以下以訂單支付場景為例,展示完整的解決方案。

  • 超時配置:Feign 連接超時1s,讀取超時2s;
  • 重試配置:最大重試3次,退避策略100ms→200ms→400ms;
  • 冪等性保障:通過訂單號 + 狀態校驗確保重復調用不會重復扣款(第三方API需支持根據訂單號查詢支付狀態)。
@Service
public class PaymentService {

    @Autowired
    private PaymentFeignClient paymentFeignClient;

    @Autowired
    private OrderRepository orderRepository; // 訂單數據庫DAO

    /**
     * 支付核心方法(超時+重試+冪等性)
     * @param orderId 訂單ID
     * @return 支付結果
     */
    @Retryable(
            value = {FeignException.class}, // 對Feign異常(含超時、5xx)重試
            maxAttempts = 3,
            backoff = @Backoff(delay = 100, multiplier = 2)
    )
    public String processPayment(String orderId) {
        // 1. 冪等性校驗:查詢訂單當前狀態,已支付則直接返回結果
        Order order = orderRepository.findById(orderId)
                .orElseThrow(() -> new BusinessException("訂單不存在"));
        if ("PAID".equals(order.getStatus())) {
            log.info("訂單已支付,無需重復調用,訂單ID:{}", orderId);
            return"PAID";
        }

        // 2. 調用第三方支付API(Feign已配置超時)
        log.info("第{}次調用支付API,訂單ID:{}", getRetryCount(), orderId);
        String paymentResult = paymentFeignClient.doPayment(orderId);

        // 3. 更新訂單狀態(支付成功)
        if ("SUCCESS".equals(paymentResult)) {
            order.setStatus("PAID");
            orderRepository.save(order);
            return"支付成功";
        }

        return"支付中";
    }

    /**
     * 重試失敗兜底:查詢第三方API確認支付狀態(避免因重試失敗導致狀態不一致)
     */
    @Recover
    public String recoverPayment(FeignException ex, String orderId) {
        log.error("支付API重試失敗,查詢最終狀態,訂單ID:{}", orderId, ex);
        try {
            // 調用第三方API查詢支付狀態(單獨配置,避免受重試影響)
            String status = paymentFeignClient.queryPaymentStatus(orderId);
            if ("SUCCESS".equals(status)) {
                Order order = orderRepository.findById(orderId).get();
                order.setStatus("PAID");
                orderRepository.save(order);
                return"支付成功(最終確認)";
            } else {
                return"支付失敗,請稍后查詢";
            }
        } catch (Exception e) {
            log.error("查詢支付狀態失敗,訂單ID:{}", orderId, e);
            return"支付結果未知,請聯系客服";
        }
    }

    private int getRetryCount() {
        org.springframework.retry.support.RetrySynchronizationManagerState state =
                org.springframework.retry.support.RetrySynchronizationManager.getContext();
        return state != null ? state.getRetryCount() + 1 : 1;
    }
}

進階

Spring Retry無法根據API返回的特定業務狀態(如 處理中、臨時限流)進行重試。而在實際第三方API調用中,這類非異常但需重試的場景極為常見(例如支付接口返回PROCESSING、短信接口返回RATE_LIMIT_TEMP)。

特性維度

Spring Retry

Guava Retry

重試觸發條件

僅支持異常觸發(指定異常類型)

支持異常觸發 + 返回值觸發(雙重條件)

停止策略

僅支持 “最大重試次數”

支持 “最大次數 + 最大時間 + 自定義條件” 組合

等待策略

僅支持固定延遲、指數退避(簡單配置)

支持固定延遲、指數退避、隨機延遲等

重試監聽

無原生監聽機制(需自定義切面)

原生支持重試前 / 重試后 / 重試結束監聽

返回值處理

無特殊處理(重試后直接返回結果)

可對重試過程中的返回值做中間處理

Guava Retry

Google的Guava Retry框架恰好彌補了這一短板,它支持基于返回值 + 異常雙重條件觸發重試,同時提供更靈活的停止策略、等待策略與重試監聽能力。

@Configuration
public class GuavaRetryConfig {

    /**
     * 支付API專用重試器
     * 重試觸發條件:1. 拋出IOException/TimeoutException;2. 返回值code為PROCESSING
     * 停止策略:最多重試3次 或 總耗時超5秒
     * 等待策略:指數退避(100ms→200ms→400ms)
     */
    @Bean("paymentApiRetryer")
    public Retryer<PaymentApiResponse> paymentApiRetryer() {
        return RetryerBuilder.<PaymentApiResponse>newBuilder()
                // 1. 異常觸發重試:超時或網絡異常
                .retryIfExceptionOfType(TimeoutException.class)
                .retryIfExceptionOfType(IOException.class)
                // 2. 返回值觸發重試:狀態碼為PROCESSING(處理中)
                .retryIfResult(response -> "PROCESSING".equals(response.getCode()))
                // 3. 停止策略:重試3次 或 總耗時超5秒(二者滿足其一即停止)
                .withStopStrategy(
                        StopStrategies.stopAfterAttemptAndTimeout(
                                3, // 最大重試次數(含首次調用,即1次首次+2次重試)
                                5, // 最大總耗時
                                TimeUnit.SECONDS
                        )
                )
                // 4. 等待策略:指數退避,初始延遲100ms,每次翻倍,最大延遲1秒
                .withWaitStrategy(
                        WaitStrategies.exponentialWait(
                                100, // 初始延遲
                                1,   // 最大延遲
                                TimeUnit.SECONDS
                        )
                )
                // 5. 重試監聽器:記錄重試日志
                .withRetryListener(new PaymentApiRetryListener())
                .build();
    }
}
實現重試監聽器(日志與監控)

通過RetryListener監聽重試事件,記錄每次重試的關鍵信息(如重試次數、觸發原因、耗時),便于后續排查問題:

/**
 * 支付API重試監聽器
 */
public class PaymentApiRetryListener implements RetryListener {
    private static final Logger log = LoggerFactory.getLogger(PaymentApiRetryListener.class);

    /**
     * 每次重試前觸發
     */
    @Override
    public <V> void onRetry(Attempt<V> attempt) {
        // 1. 獲取重試次數(首次調用為0,第1次重試為1,以此類推)
        long retryCount = attempt.getAttemptNumber() - 1;
        // 2. 判斷重試觸發原因(異常/返回值)
        String triggerReason = attempt.hasException() ? 
                "異常觸發(" + attempt.getExceptionCause().getMessage() + ")" : 
                "返回值觸發(" + attempt.getResult() + ")";
        // 3. 獲取本次嘗試耗時(毫秒)
        long costTime = attempt.getDelaySinceFirstAttempt().toMillis();

        // 4. 記錄重試日志
        log.info("支付API第{}次重試,觸發原因:{},累計耗時:{}ms", 
                retryCount, triggerReason, costTime);
    }
}
業務層:使用重試器調用第三方 API

在Service層注入Retryer,通過retryer.call()執行帶重試邏輯的API調用,核心代碼如下:

@Service
public class GuavaRetryPaymentService {
    private static final Logger log = LoggerFactory.getLogger(GuavaRetryPaymentService.class);

    @Autowired
    private RestTemplate restTemplate;

    // 注入支付API專用重試器
    @Autowired
    @Qualifier("paymentApiRetryer")
    private Retryer<PaymentApiResponse> paymentApiRetryer;

    /**
     * 調用第三方支付API(帶Guava Retry重試邏輯)
     */
    public PaymentApiResponse callPaymentApi(String orderId, String amount) 
            throws ExecutionException, RetryException {
        // 第三方API地址(模擬)
        String apiUrl = "https://api.thirdparty.com/pay?orderId={1}&amount={2}";

        try {
            // 執行帶重試的API調用:retryer會自動根據配置的策略重試
            return paymentApiRetryer.call(() -> {
                // 1. 發起API請求(此處模擬不同場景的返回結果)
                PaymentApiResponse response = mockThirdPartyPaymentApi(orderId, amount);
                
                // 2. 模擬可能拋出的異常(超時/網絡異常)
                if ("TIMEOUT".equals(response.getCode())) {
                    throw new TimeoutException("支付API超時,訂單ID:" + orderId);
                }
                if ("NETWORK_ERROR".equals(response.getCode())) {
                    throw new IOException("支付API網絡異常,訂單ID:" + orderId);
                }

                // 3. 返回正常響應(Retryer會根據返回值判斷是否重試)
                return response;
            });
        } catch (ExecutionException e) {
            // 封裝異常信息(ExecutionException是Guava Retry的外層異常,需解析原始異常)
            log.error("支付API重試后仍失敗,訂單ID:{},原始異常:{}", 
                    orderId, e.getCause().getMessage(), e);
            throw e; // 向上拋出,由全局異常處理器處理
        } catch (RetryException e) {
            // 重試達到停止條件(次數/時間)仍失敗
            log.error("支付API達到最大重試限制,訂單ID:{},重試次數:{}", 
                    orderId, e.getNumberOfFailedAttempts());
            throw e;
        }
    }

    /**
     * 模擬第三方支付API的返回結果(用于測試不同場景)
     * 實際項目中替換為真實的restTemplate.getForObject()/postForObject()
     */
    private PaymentApiResponse mockThirdPartyPaymentApi(String orderId, String amount) {
        // 場景1:第1次調用返回PROCESSING(觸發返回值重試)
        // 場景2:第2次調用拋出TimeoutException(觸發異常重試)
        // 場景3:第3次調用返回SUCCESS(成功,不重試)
        long retryCount = paymentApiRetryer.toString().contains("attempt=1") ? 1 : 
                          paymentApiRetryer.toString().contains("attempt=2") ? 2 : 3;

        if (retryCount == 1) {
            return new PaymentApiResponse("PROCESSING", "支付處理中", orderId);
        } elseif (retryCount == 2) {
            return new PaymentApiResponse("TIMEOUT", "支付超時", orderId);
        } else {
            return new PaymentApiResponse("SUCCESS", "支付成功", orderId);
        }
    }
}


責任編輯:武曉燕 來源: 一安未來
相關推薦

2023-10-11 09:54:59

Java開發

2017-07-02 16:50:21

2017-06-16 15:16:15

2025-05-09 08:28:22

2011-05-07 14:20:25

加密方案Transcoder BlackBerry

2024-04-03 12:57:29

2015-11-05 16:44:37

第三方登陸android源碼

2023-06-20 11:34:48

2025-04-01 05:00:00

OAuth2服務器身份驗證

2021-09-26 10:43:08

注冊Istio集成

2025-09-30 01:55:00

SpringWebClientHTTP

2024-08-27 09:05:45

2015-04-27 19:32:16

Moxtra

2019-07-30 11:35:54

AndroidRetrofit

2014-07-23 08:55:42

iOSFMDB

2009-02-10 10:36:08

FacebookAPIOpen API

2022-05-06 07:44:10

微服務系統設計重試機制

2011-10-12 14:47:24

SiriiOS5蘋果

2015-03-10 10:45:58

AppleWatch開發App

2024-03-04 15:50:39

點贊
收藏

51CTO技術棧公眾號

国产在线不卡av| 樱空桃在线播放| 天天射天天干天天| 五月天激情综合网| 日韩欧美一区二区三区在线| 亚洲熟妇av日韩熟妇在线 | 日韩午夜激情视频| 欧美性大战久久久久xxx| 蜜桃av在线免费观看| 成人蜜臀av电影| 国产精品一久久香蕉国产线看观看| 免费一级a毛片夜夜看 | 国产黄色一区| 亚洲国产一区二区三区青草影视| 日韩精品欧美在线| 国精产品一品二品国精品69xx| 久久免费国产| 久久久久久久久久av| 色欲狠狠躁天天躁无码中文字幕 | 希岛爱理中文字幕| 亚洲综合福利| 亚洲电影av在线| 福利视频999| japanese23hdxxxx日韩 | 久久精品视频2| 中文字幕精品无码一区二区| 亚洲国产中文字幕在线| 日韩专区欧美专区| 午夜精品久久久久久久99黑人 | 亚洲你懂的在线视频| 欧美重口乱码一区二区| 色综合久久久久久| 国产馆精品极品| 91精品视频网站| 在线免费观看一级片| 国产欧美日韩一区二区三区在线| 欧美多人乱p欧美4p久久| 天堂网av2018| 国内成人自拍| 国产丝袜视频一区| yjizz视频| 911亚洲精品| 欧美一区二区三区在线| 国产视频1区2区3区| 日韩中文在线播放| 一本久久a久久精品亚洲| 国产一区二区在线视频播放| av丝袜在线| 亚洲第一主播视频| 僵尸世界大战2 在线播放| 亚洲男同gay网站| 亚洲一区在线观看网站| 17c丨国产丨精品视频| 拍真实国产伦偷精品| 国产精品久久久久久久久搜平片| 日韩精品大片| 伊人在线视频| 亚洲欧洲成人自拍| 中文字幕欧美日韩一区二区三区| 三区四区在线视频| 亚洲天堂2016| 高清无码一区二区在线观看吞精| 五月天激情在线| 亚洲图片欧美一区| 成熟了的熟妇毛茸茸| 国产精品粉嫩| 欧美日韩午夜在线| xxx中文字幕| 成人性生交大片免费看96| 亚洲精品按摩视频| 中日韩精品一区二区三区| 国产影视一区| 久久精品国产久精国产一老狼| 美国黄色小视频| 亚洲第一在线| 国产精品黄视频| 国产免费叼嘿网站免费| 国产成人av影院| 久久亚洲精品欧美| 在线视频婷婷| 亚洲尤物在线视频观看| av片中文字幕| 国产成年精品| 亚洲国语精品自产拍在线观看| 精品人妻一区二区三区视频| 大色综合视频网站在线播放| 欧美久久精品一级黑人c片 | 最新成人av网站| 国产精品2018| 国产不卡av在线播放| 99精品国产热久久91蜜凸| 五月天久久狠狠| 女人天堂av在线播放| 欧美日韩亚洲91| 欧美xxxxx在线视频| 国产成人毛片| 亚洲经典中文字幕| 夫妻性生活毛片| 一本一本久久| 7777精品久久久大香线蕉小说| 视频一区二区在线播放| 亚洲日韩欧美一区二区在线| 成人毛片视频网站| 亚洲1区在线| 亚洲小视频在线观看| 久艹视频在线观看| 奇米影视一区二区三区小说| 国产精品免费看一区二区三区| 免费在线性爱视频| 亚洲亚洲精品在线观看| 国产探花在线看| 久久不见久久见免费视频7| 久久国产精品久久精品| 波多野结衣一区二区三区在线| 国产高清久久久久| 亚洲欧美日产图| 国产高清不卡| 亚洲成人久久一区| 侵犯稚嫩小箩莉h文系列小说| 日韩高清一区在线| 九九九九九九精品| 在线观看h网| 4hu四虎永久在线影院成人| 女人又爽又黄免费女仆| 99精品国产在热久久下载| 91福利视频导航| www在线视频| 精品视频在线免费看| 天天躁日日躁aaaxxⅹ | 9久久婷婷国产综合精品性色| 精品伊人久久久| 久久久久久久久爱| 亚洲第一成年人网站| 亚洲欧美视频在线观看| 国内国产精品天干天干| 四虎国产精品免费观看| 国产精品久久久久免费a∨大胸| 天堂av网在线| 欧美日韩美女在线| 性囗交免费视频观看| 亚洲视频高清| 国产伦理一区二区三区| 国产盗摄精品一区二区酒店| 日韩欧美国产不卡| 精品人妻在线播放| 成人午夜视频在线观看| 亚洲色成人www永久在线观看| 日韩三级网址| 欧美激情xxxxx| 亚洲第一色网站| 亚洲一区二区三区免费视频| 黄色av电影网站| 亚洲精一区二区三区| 国产一区精品视频| av电影一区| 亚洲天堂网站在线观看视频| 超碰在线观看91| 日本一区二区免费在线观看视频| 欧美三级午夜理伦三级富婆| 欧美r级电影| 3d动漫啪啪精品一区二区免费| 黑人另类精品××××性爽| 亚洲黄页视频免费观看| 中文字幕手机在线视频| 国产精品第四页| 中文字幕人妻无码系列第三区| 国产精品分类| 九九热久久66| 国产精品第一| 欧美福利小视频| 亚洲欧美丝袜中文综合| 在线观看免费亚洲| 精品自拍偷拍视频| 成人av手机在线观看| 国产麻花豆剧传媒精品mv在线| 91影院成人| 国产精品v欧美精品∨日韩| 蜜桃视频www网站在线观看| 一区二区三区天堂av| 国产精品亚洲欧美在线播放| 亚洲成人精品影院| 亚洲女优在线观看| 国产精品69久久久久水密桃| 欧美国产亚洲一区| 国产精品毛片久久| 精品国产一区二区三区免费| 成人亚洲网站| 午夜欧美大片免费观看| melody高清在线观看| 精品国产乱码久久久久久浪潮 | 国产一区二区三区在线观看精品 | 韩国av一区二区三区四区| 成年人网站国产| 欧美日韩性在线观看| av成人观看| 日韩国产网站| 午夜伦理精品一区| 男人的天堂在线视频免费观看| 亚洲国产精品成人一区二区| 伊人网视频在线| 欧美日韩精品二区| 亚洲国产美女视频| 国产三级欧美三级日产三级99| 18深夜在线观看免费视频| 日韩电影在线看| 青青草国产精品视频| 99久久99热这里只有精品 | 日本v片在线免费观看| 欧美乱妇15p| 国产精品乱码一区二区视频| 午夜精品久久久久久| 免费成人深夜夜行网站| 国产午夜三级一区二区三| 高清中文字幕mv的电影| 激情偷乱视频一区二区三区| 日本www.色| 国产欧美精品久久| 欧美日韩不卡在线视频| 91成人精品| 在线观看亚洲视频啊啊啊啊| 欧洲专线二区三区| 久久riav二区三区| www.亚洲一二| 99久久伊人精品影院| 亚洲网站三级| 国产精品网红福利| 深夜视频一区二区| 欧美专区在线观看| free性欧美| 久久精品国产亚洲| 欧美被日视频| 日韩在线一区二区三区免费视频| 国产一二三区在线视频| 精品一区电影国产| 亚洲色图 校园春色| 亚洲国产成人爱av在线播放| 超碰在线人人干| 日韩欧美色综合| 国产成a人亚洲精v品无码| 欧美一区二区三区视频免费播放| 国产又大又黄的视频| 欧美日本国产一区| 亚洲资源在线播放| 欧美剧在线免费观看网站 | 亚洲伊人婷婷| 久久精品高清| 男女啪啪的视频| 91精品一区二区三区综合在线爱| 伊人久久大香线蕉精品| 欧美h版在线| 色哟哟免费网站| 午夜久久美女| cao在线观看| 一本一本久久| 久久久精品三级| 久久精品国内一区二区三区| 999热精品视频| 国产成人啪午夜精品网站男同| 国产大学生av| 91色porny在线视频| 性欧美精品男男| 中文字幕一区二区5566日韩| www.av免费| 亚洲成人激情综合网| 精品91久久久| 欧美自拍丝袜亚洲| 国产精品自产拍| 欧美成人福利视频| 日韩欧美在线观看一区二区| 国产亚洲成精品久久| 男人和女人做事情在线视频网站免费观看 | 国产成人综合精品在线| 欧美一级免费| 国产欧美亚洲日本| 国产精品一在线观看| 中文字幕人成一区| 亚洲精品激情| 69久久久久久| 成人丝袜18视频在线观看| 亚洲AV无码国产精品| 中文字幕一区二区三区在线不卡 | jizz性欧美10| 欧美一区第一页| 青青青国产精品| 国产一级二级三级精品| 欧美日韩水蜜桃| 久久国产午夜精品理论片最新版本| 久久成人国产| 国产大片一区二区三区| 26uuu另类欧美| 亚洲xxxx3d动漫| 欧美午夜美女看片| 精品国产亚洲AV| 国产亚洲人成网站在线观看| 欧美亚洲系列| 国产精品免费一区| 欧美日日夜夜| 视色,视色影院,视色影库,视色网 日韩精品福利片午夜免费观看 | 欧美一级网址| 久久久久久国产精品一区| 91精品电影| 一区二区三区入口| 99久久夜色精品国产网站| 乱老熟女一区二区三区| 欧美日韩综合视频网址| 国产国语亲子伦亲子| 国产亚洲精品久久久| a级片免费在线观看| 91久久久久久| 欧美一级精品| 蜜臀久久99精品久久久酒店新书| 国产91精品免费| 欧美美女性生活视频| 色综合久久久久久久久| 色屁屁草草影院ccyycom| 久久国产精品99国产精| 亚洲a成人v| 午夜精品福利一区二区| 免费在线播放第一区高清av| 久久久久亚洲av成人网人人软件| 亚洲欧洲成人av每日更新| 中文字幕第2页| 亚洲欧洲午夜一线一品| 麻豆蜜桃在线观看| 国产精品久久久久久久小唯西川| 婷婷亚洲综合| 国产美女18xxxx免费视频| 国产欧美日韩在线视频| 国产女主播喷水视频在线观看 | 青青草视频成人| 亚洲成人免费在线观看| 亚洲国产精品suv| 欧美日韩成人在线播放| 高清久久精品| 国产在线拍揄自揄拍无码| 国内国产精品久久| 亚洲色偷偷综合亚洲av伊人| 欧美二区在线观看| 尤物网在线观看| 91精品免费视频| 女人色偷偷aa久久天堂 | 久久女同互慰一区二区三区| 丁香六月婷婷综合| 亚洲毛片在线观看| 台湾佬成人网| 日韩成人av电影在线| 日日摸夜夜添夜夜添国产精品 | 精品国产户外野外| 日本精品久久久久| 91精品国产高清久久久久久91 | 亚洲毛片一区二区三区| 国产亚洲视频在线| 国产乱子精品一区二区在线观看| 亚洲亚洲精品三区日韩精品在线视频| 免费在线观看精品| 亚洲欧美精品久久| 日韩一区二区三区免费观看| 七七成人影院| 精品视频免费观看| 日韩av中文在线观看| 激情高潮到大叫狂喷水| 欧美一二区视频| 蜜桃视频动漫在线播放| 日韩精品资源| 国产在线视频一区二区| 四虎成人精品永久免费av| 精品视频在线导航| 国产精品一区二区免费福利视频| 中文字幕第一页亚洲| 成人高清在线视频| 夜夜爽妓女8888视频免费观看| 中文国产成人精品久久一| 9.1麻豆精品| 丁香花在线影院观看在线播放| 国产无一区二区| 99国产精品久久久久久久成人 | www.久久视频| 欧美成人免费va影院高清| 哺乳挤奶一区二区三区免费看 | 日本特黄特色aaa大片免费| 亚洲区免费影片| 国产一区二区三区免费观看在线| 国产自产在线视频| 欧美国产一区二区在线观看| 性一交一乱一色一视频麻豆| 欧美最猛性xxxxx免费| 天天做天天爱天天爽综合网| 免费黄色三级网站| 欧美丰满美乳xxx高潮www| 高清电影在线免费观看| 日韩欧美视频第二区| 成人小视频在线| 中文字幕人妻互换av久久| 久久久免费精品| 91欧美在线| 色欲av无码一区二区三区| 欧美一区二区在线播放| 精品国产免费人成网站| 成人国产一区二区三区| 国产欧美一二三区|