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

SpringBoot與Pulsar整合,實現金融交易場景下的消息有序性保障

開發 前端
用戶發起一筆交易請求,系統需要將該請求發送到交易處理系統,并確保請求按順序被處理。而使用Pulsar的獨占訂閱模式確保交易請求按順序被單一消費者處理,避免亂序導致的賬務錯誤。

Apache Pulsar 設計用于大規模實時數據處理,支持多種消息傳遞模型(發布/訂閱、隊列等),并提供了強大的功能來確保消息的可靠性和性能。

優勢

1. 強大的消息模型

  • 發布/訂閱 (Pub/Sub): 支持多個消費者同時從同一個主題接收消息,適合實時數據分析和通知系統。
  • 獨占訂閱 (Exclusive Subscription): 確保只有一個消費者能夠消費某個分區的消息,從而保證消息的嚴格順序。
  • 共享訂閱 (Shared Subscription): 多個消費者可以負載均衡地消費消息,提高吞吐量。
  • 故障域感知路由: 根據地理位置和網絡拓撲優化消息路由,確保高效的數據傳輸。

2. 持久化與存儲

  • 持久化消息: 所有消息都被持久化到磁盤,確保消息不會丟失。
  • 分層存儲: 使用分層存儲策略,結合內存和磁盤存儲,提高讀寫效率。
  • 自動清理: 定期清理過期或不再需要的消息,節省存儲空間。

3. 事務支持

  • 事務消息: 支持事務性的消息發送和確認機制,確保數據一致性。
  • 兩階段提交: 實現ACID特性,保證消息的一致性和可靠性。

4. 死信隊列

  • 死信隊列 (Dead Letter Queue, DLQ): 對于無法成功處理的消息,將其放入死信隊列以便后續排查和處理。
  • 重試機制: 在消息處理失敗時,進行一定次數的重試(默認最多3次),如果仍然失敗,則將消息放入死信隊列。

應用場景

用戶發起一筆交易請求,系統需要將該請求發送到交易處理系統,并確保請求按順序被處理。而使用Pulsar的獨占訂閱模式確保交易請求按順序被單一消費者處理,避免亂序導致的賬務錯誤。

啟動Pulsar:

bin/pulsar standalone

代碼實操

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Apache Pulsar Client -->
    <dependency>
        <groupId>org.apache.pulsar</groupId>
        <artifactId>pulsar-client</artifactId>
        <version>2.10.1</version>
    </dependency>

    <!-- Lombok for cleaner Java code -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- JUnit for testing -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

配置文件

application.properties文件中配置Pulsar的相關屬性:

# Pulsar broker URL
pulsar.service.url=pulsar://localhost:6650

# Topic name
pulsar.topic.name=finance-transaction-topic

# Dead letter topic name
pulsar.dead-letter.topic.name=dead-letter-topic

# Max redelivery count before sending to dead letter queue
pulsar.max.redeliver.count=3

服務類

創建一個服務類來處理生產和消費消息,包括事務消息和死信隊列的處理邏輯。

import lombok.extern.slf4j.Slf4j;
import org.apache.pulsar.client.api.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.CompletableFuture;

@Service
@Slf4j
public class FinanceTransactionService {

    @Value("${pulsar.service.url}")
    private String serviceUrl;

    @Value("${pulsar.topic.name}")
    private String topicName;

    @Value("${pulsar.dead-letter.topic.name}")
    private String deadLetterTopicName;

    @Value("${pulsar.max.redeliver.count}")
    private int maxRedeliverCount;

    private PulsarClient client;
    private Producer<String> producer;
    private Consumer<String> consumer;

    /**
     * 初始化Pulsar客戶端、生產者和消費者
     */
    @PostConstruct
    public void init() throws Exception {
        // 初始化Pulsar客戶端
        client = PulsarClient.builder()
                .serviceUrl(serviceUrl)
                .build();

        // 創建生產者
        producer = client.newProducer(Schema.STRING)
                .topic(topicName)
                .sendTimeout(0, java.util.concurrent.TimeUnit.SECONDS)
                .enableBatching(false)
                .create();

        // 創建消費者
        consumer = client.newConsumer(Schema.STRING)
                .topic(topicName)
                .subscriptionName("finance-subscription")
                .subscriptionType(SubscriptionType.Exclusive)
                .negativeAckRedeliveryBackoff(MultiplierRedeliveryBackoff.builder()
                        .maxDelayMs(60_000)
                        .minDelayMs(1_000)
                        .multiplier(2)
                        .build())
                .deadLetterPolicy(DeadLetterPolicy.builder()
                        .maxRedeliverCount(maxRedeliverCount)
                        .deadLetterTopic(deadLetterTopicName)
                        .build())
                .subscribe();

        // 開始消費消息
        consumeMessages();
    }

    /**
     * 關閉Pulsar客戶端、生產者和消費者
     */
    @PreDestroy
    public void close() throws Exception {
        if (producer != null) {
            producer.close();
        }
        if (consumer != null) {
            consumer.close();
        }
        if (client != null) {
            client.close();
        }
    }

    /**
     * 發送事務消息
     *
     * @param message 消息內容
     * @return 消息ID的CompletableFuture對象
     */
    public CompletableFuture<MessageId> sendTransactionalMessage(String message) {
        return producer.sendAsync(message);
    }

    /**
     * 消費消息并處理
     */
    private void consumeMessages() {
        new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                try {
                    Message<String> msg = consumer.receive();
                    log.info("Received message: {}", msg.getValue());

                    // 處理消息
                    boolean processSuccess = processMessage(msg.getValue());

                    if (processSuccess) {
                        // 確認消息
                        consumer.acknowledgeAsync(msg.getMessageId());
                    } else {
                        // 負確認消息,觸發重試機制
                        consumer.negativeAcknowledge(msg.getMessageId(), new CustomException("Processing failed"));
                    }
                } catch (Exception e) {
                    log.error("Error processing message", e);
                }
            }
        }).start();
    }

    /**
     * 模擬消息處理邏輯
     *
     * @param message 消息內容
     * @return 處理是否成功
     */
    private boolean processMessage(String message) {
        // 模擬消息處理邏輯
        // 對于每三條消息中的一條模擬處理失敗
        long messageId = Long.parseLong(message.split(":")[1]);
        return messageId % 3 != 0;
    }

    static class CustomException extends Exception {
        public CustomException(String message) {
            super(message);
        }
    }

    // Getter methods for configuration properties (for testing purposes)
    public String getServiceUrl() {
        return serviceUrl;
    }

    public String getTopicName() {
        return topicName;
    }

    public String getDeadLetterTopicName() {
        return deadLetterTopicName;
    }

    public int getMaxRedeliverCount() {
        return maxRedeliverCount;
    }
}

控制器類

創建一個控制器類來暴露API端點用于發送消息。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;

@RestController
public class FinanceTransactionController {

    @Autowired
    private FinanceTransactionService financeTransactionService;

    /**
     * 發送消息到Pulsar主題
     *
     * @param message 消息內容
     * @return 發送結果
     */
    @PostMapping("/send-message")
    public String sendMessage(@RequestParam String message) {
        try {
            financeTransactionService.sendTransactionalMessage(message).get();
            return"Message sent successfully";
        } catch (InterruptedException | ExecutionException e) {
            log.error("Failed to send message", e);
            return"Failed to send message";
        }
    }
}

單元測試

為了驗證上述功能是否正常工作,我們寫了一些測試用例。

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.http.ResponseEntity;

import static org.junit.jupiter.api.Assertions.*;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FinanceTransactionControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private FinanceTransactionService financeTransactionService;

    /**
     * 清空主題中的消息,確保每次測試前環境干凈
     */
    @BeforeEach
    public void setUp() throws Exception {
        clearTopic(financeTransactionService.getTopicName());
        clearTopic(financeTransactionService.getDeadLetterTopicName());
    }

    /**
     * 關閉資源
     */
    @AfterEach
    public void tearDown() throws Exception {
        financeTransactionService.close();
    }

    /**
     * 測試成功發送的消息是否正確地出現在主主題中,并且沒有出現在死信隊列中
     */
    @Test
    public void testSendMessage_Success() {
        ResponseEntity<String> response = restTemplate.postForEntity("/send-message?message=transaction:1", null, String.class);
        assertEquals("Message sent successfully", response.getBody());

        response = restTemplate.postForEntity("/send-message?message=transaction:2", null, String.class);
        assertEquals("Message sent successfully", response.getBody());

        response = restTemplate.postForEntity("/send-message?message=transaction:4", null, String.class);
        assertEquals("Message sent successfully", response.getBody());

        // 驗證消息在主主題中
        assertMessageInTopic("transaction:1");
        assertMessageInTopic("transaction:2");
        assertMessageInTopic("transaction:4");

        // 驗證死信隊列中沒有消息
        assertNoMessagesInTopic(financeTransactionService.getDeadLetterTopicName());
    }

    /**
     * 測試失敗發送的消息是否在達到最大重試次數后進入死信隊列
     */
    @Test
    public void testSendMessage_Failure() {
        ResponseEntity<String> response = restTemplate.postForEntity("/send-message?message=transaction:3", null, String.class);
        assertEquals("Message sent successfully", response.getBody());

        // 驗證消息在死信隊列中(經過多次重試)
        assertMessageInTopicWithRetries("transaction:3", financeTransactionService.getMaxRedeliverCount());
    }

    /**
     * 清空指定主題中的所有消息
     *
     * @param topicName 主題名稱
     */
    private void clearTopic(String topicName) throws Exception {
        PulsarClient client = PulsarClient.builder()
                .serviceUrl(financeTransactionService.getServiceUrl())
                .build();

        Reader<String> reader = client.newReader(Schema.STRING)
                .topic(topicName)
                .startMessageId(MessageId.earliest)
                .create();

        while (reader.hasMessageAvailable()) {
            reader.readNext();
        }

        reader.close();
        client.close();
    }

    /**
     * 驗證指定主題中是否存在特定消息
     *
     * @param expectedMessage 預期消息內容
     */
    private void assertMessageInTopic(String expectedMessage) {
        try (PulsarClient client = PulsarClient.builder()
                .serviceUrl(financeTransactionService.getServiceUrl())
                .build();

             Reader<String> reader = client.newReader(Schema.STRING)
                     .topic(financeTransactionService.getTopicName())
                     .startMessageId(MessageId.earliest)
                     .create()) {

            while (reader.hasMessageAvailable()) {
                Message<String> msg = reader.readNext();
                if (msg.getValue().equals(expectedMessage)) {
                    return;
                }
            }
            fail("Expected message not found in topic: " + expectedMessage);
        } catch (Exception e) {
            fail("Failed to read from topic: " + e.getMessage());
        }
    }

    /**
     * 驗證指定主題中沒有消息
     *
     * @param topicName 主題名稱
     */
    private void assertNoMessagesInTopic(String topicName) {
        try (PulsarClient client = PulsarClient.builder()
                .serviceUrl(financeTransactionService.getServiceUrl())
                .build();

             Reader<String> reader = client.newReader(Schema.STRING)
                     .topic(topicName)
                     .startMessageId(MessageId.earliest)
                     .create()) {

            assertFalse(reader.hasMessageAvailable(), "Unexpected messages found in topic: " + topicName);
        } catch (Exception e) {
            fail("Failed to read from topic: " + e.getMessage());
        }
    }

    /**
     * 驗證指定主題中是否存在特定消息(帶有重試機制)
     *
     * @param expectedMessage 預期消息內容
     * @param maxRetries      最大重試次數
     */
    private void assertMessageInTopicWithRetries(String expectedMessage, int maxRetries) {
        try (PulsarClient client = PulsarClient.builder()
                .serviceUrl(financeTransactionService.getServiceUrl())
                .build();

             Reader<String> reader = client.newReader(Schema.STRING)
                     .topic(financeTransactionService.getDeadLetterTopicName())
                     .startMessageId(MessageId.earliest)
                     .create()) {

            int retryCount = 0;
            while (retryCount < maxRetries) {
                if (reader.hasMessageAvailable()) {
                    Message<String> msg = reader.readNext();
                    if (msg.getValue().equals(expectedMessage)) {
                        return;
                    }
                }
                retryCount++;
                Thread.sleep(1000); // 等待1秒后重試
            }
            fail("Expected message not found in dead letter topic after retries: " + expectedMessage);
        } catch (Exception e) {
            fail("Failed to read from dead letter topic: " + e.getMessage());
        }
    }
}

測試結果

發送消息:

curl -X POST http://localhost:8080/send-message\?message\=transaction\:1
curl -X POST http://localhost:8080/send-message\?message\=transaction\:2
curl -X POST http://localhost:8080/send-message\?message\=transaction\:3
curl -X POST http://localhost:8080/send-message\?message\=transaction\:4

日志:

Received message: transaction:1
Received message: transaction:2
Received message: transaction:3
Received message: transaction:4


責任編輯:武曉燕 來源: Java知識日歷
相關推薦

2025-04-29 08:36:28

SpringCanal數據庫

2025-03-20 08:57:54

Spring日志存儲系統

2021-11-07 15:01:16

區塊鏈金融技術

2020-06-12 12:49:52

數據

2022-01-10 11:58:51

SpringBootPulsar分布式

2021-05-06 19:20:05

Java內存模型

2011-04-29 14:35:53

惠普工作站

2021-01-12 07:39:48

線程線程安全

2021-05-16 17:14:30

線程安全性

2020-03-04 08:25:18

有序性并發結構

2016-03-17 13:39:45

組委會

2024-11-18 16:37:35

JMMJava內存模型

2025-05-09 01:04:00

2025-05-07 03:10:00

RabbitMQSpring訂單

2024-09-27 14:45:30

2024-10-23 20:09:47

2024-02-27 17:46:25

并發程序CPU

2023-09-04 08:00:53

提交事務消息

2023-12-15 13:08:00

RocketMQ中間件消費順序

2025-02-20 09:17:50

點贊
收藏

51CTO技術棧公眾號

99久久综合色| 91精品久久久久久综合五月天| 嫩草在线播放| 亚洲宅男网av| 欧美日韩精品免费观看视频| 蜜桃网站在线观看| 视频二区在线观看| 日韩国产欧美三级| 欧美超级免费视 在线| 最新版天堂资源在线| 蜜桃成人精品| 怡红院av一区二区三区| 久久一区二区三区欧美亚洲| 亚洲熟妇无码久久精品| 一区二区亚洲| 日韩在线观看网站| 亚洲av成人精品一区二区三区| 亚洲人免费短视频| 亚洲最大色网站| 相泽南亚洲一区二区在线播放 | 岛国av午夜精品| 亚洲欧美日韩精品久久久 | 成人爽a毛片免费啪啪| 中文字幕永久在线不卡| 亚洲国产高清视频| 4438亚洲最大| 人妻内射一区二区在线视频| 一色桃子av在线| 日本一二三不卡| 国产乱码精品一区二区三区不卡| 精人妻无码一区二区三区| 欧美jizzhd精品欧美巨大免费| 国产亚洲精品久久久久久牛牛| 少妇伦子伦精品无吗| www.精品国产| 色综合色综合色综合色综合色综合 | 91成人福利社区| 欧美性jizz18性欧美| av在线com| 日本在线人成| 国产视频一区不卡| 九色91视频| 国精品人妻无码一区二区三区喝尿| 美女视频一区二区| 日本亚洲精品在线观看| 国产精品a成v人在线播放| 亚洲一区二区| 美女啪啪无遮挡免费久久网站| 丁香激情五月少妇| 国产日韩欧美一区二区三区| 精品一区二区三区四区| 小毛片在线观看| jizz国产精品| 日韩精品一区二区三区视频播放| 日韩a一级欧美一级| 日韩专区视频网站| 欧美片在线播放| 在线观看免费不卡av| 国产三级一区| 欧美老女人第四色| 最新国产黄色网址| 国产精品xnxxcom| 欧美一区二区视频网站| 九九热视频免费| 亚洲国产高清在线观看| 欧美一区二区三区在线观看 | 成人爽a毛片一区二区免费| 91九色对白| 亚洲精品福利网站| 成人激情小说乱人伦| 国产在线精品一区二区三区》| 人妻精品一区二区三区| 成人一区二区三区视频| 国产在线一区二区三区四区| 日本电影一区二区在线观看| 久久九九国产精品| 亚洲精品一品区二品区三品区| 欧洲不卡av| 亚洲精品国产a久久久久久 | av电影免费在线看| 婷婷综合久久一区二区三区| 无码人妻丰满熟妇区毛片18| 国产一区一一区高清不卡| 欧美日韩国产中文| www.欧美com| 自拍偷拍精品| 久久视频免费观看| 久久精品国产亚洲av麻豆色欲| 国产精品久久久久久模特| 国产成人精彩在线视频九色| 97超碰人人草| fc2成人免费人成在线观看播放| 免费亚洲精品视频| 久久综合网导航| 欧美日韩美女视频| 亚洲国产日韩欧美在线观看| 日韩免费成人| 国产午夜精品一区二区三区 | 亚洲大片精品永久免费| 日本精品免费在线观看| 亚洲精品乱码日韩| 亚洲激情中文字幕| 1024在线看片| 最新国产乱人伦偷精品免费网站| 国产精品99久久久久久久久久久久| 国产又黄又爽视频| 久久―日本道色综合久久| 中文字幕综合在线观看| caoporn视频在线| 欧美麻豆精品久久久久久| 亚洲成人av免费在线观看| 91视频久久| 人妖精品videosex性欧美| 99国产精品99| 久久久不卡网国产精品一区| 国产免费xxx| 国产一区二区三区影视| 亚洲国产古装精品网站| 你懂得在线观看| 国产亚洲高清视频| av一区和二区| 好吊日视频在线观看| 欧美性色xo影院| 亚洲黄色小说在线观看| 亚洲成人精品| 国产精品免费久久久久影院| 五月天久久久久久| 一级特黄大欧美久久久| 欧美一级xxxx| 欧美一区二区麻豆红桃视频| 欧美孕妇与黑人孕交| 丰满岳乱妇国产精品一区| 日韩理论在线观看| 欧美一级特黄a| 国产欧美日韩精品一区二区免费| 久久久亚洲国产| 亚洲va久久久噜噜噜无码久久| 中文字幕免费在线观看视频一区| 一本大道熟女人妻中文字幕在线 | 国产伦精品一区二区三区照片91 | 精品国产99久久久久久宅男i| 国产三级精品三级| 粗暴91大变态调教| 综合亚洲色图| 2019中文字幕在线观看| 人人妻人人玩人人澡人人爽| 亚洲国产中文字幕在线视频综合| 亚洲欧美日韩综合网| 成人综合久久| 国产日韩在线播放| 一区二区高清不卡| 欧美裸体bbwbbwbbw| 97在线观看视频免费| 日本亚洲欧美天堂免费| 日韩高清在线播放| 91成人在线| 精品国内自产拍在线观看| 中国一级片黄色一级片黄| 国产日韩在线不卡| 天天爽天天爽夜夜爽| 不卡在线一区二区| 国产中文字幕日韩| 二区三区在线观看| 日韩三级av在线播放| 欧美日韩精品亚洲精品| 懂色av一区二区三区免费看| 黄页网站大全在线观看| 日本在线中文字幕一区| 日本高清不卡在线| 午夜视频成人| 日韩欧美国产综合在线一区二区三区| 青青草精品在线视频| 成人自拍视频在线| 91av资源网| 日产午夜精品一线二线三线| 国产日韩欧美夫妻视频在线观看 | 2019亚洲男人天堂| 国产一级在线观看| 在线成人av网站| 精品在线视频观看| 久久久高清一区二区三区| 一区二区xxx| 国一区二区在线观看| 免费看成人片| 婷婷久久综合九色综合99蜜桃| 欧美美女15p| 欧洲亚洲精品视频| 欧美精品 日韩| 国产午夜精品无码| 欧美激情在线观看视频免费| 人妻体体内射精一区二区| 99人久久精品视频最新地址| 亚洲高清视频一区二区| 99这里只有精品视频| 国产精品成人aaaaa网站| 黄色在线观看网站| 精品一区二区三区电影| 国产模特av私拍大尺度| 欧美日韩一区二区免费视频| 亚洲aaa视频| 99r国产精品| 在线观看免费视频污| 一本久道久久综合狠狠爱| 伊人久久青草| 一区二区导航| 99re在线| 中文字幕+乱码+中文乱码www| av在线加勒比| 精品国产一区a| 中文字幕在线视频免费| 亚洲成av人综合在线观看| 99久久精品久久亚洲精品| 9久草视频在线视频精品| 五月激情婷婷在线| 久久成人亚洲| 欧美日韩不卡在线视频| 天天插综合网| 三级三级久久三级久久18| 久久精品国产亚洲5555| 亚洲一区二区三区久久| 素人一区二区三区| 日本高清+成人网在线观看| 欧美寡妇性猛交xxx免费| 日韩在线视频二区| 九色在线视频| 日韩av在线网| 蜜桃视频污在线观看| 在线播放国产精品二区一二区四区| 久久久久久不卡| 天天影视涩香欲综合网| 国产在线观看免费视频今夜| 综合分类小说区另类春色亚洲小说欧美| 麻豆av免费观看| eeuss国产一区二区三区| 中国特级黄色大片| 国产精品中文字幕日韩精品| 中文字幕 欧美日韩| 日本v片在线高清不卡在线观看| 男人天堂999| 国产日韩1区| aa在线免费观看| 亚洲一区自拍| 欧美日韩在线一| 国产偷自视频区视频一区二区| 男人添女荫道口女人有什么感觉| 一区二区三区在线电影| 熟女视频一区二区三区| 国产精品久久观看| 亚洲AV无码成人精品一区| 97精品中文字幕| 中文字幕中文字幕99 | 亚洲精品网站在线播放gif| 手机在线不卡av| 亚洲精品99999| 污污网站在线免费观看| 亚洲精品动漫久久久久| 手机看片1024日韩| 日韩av综合网| 男女污视频在线观看| 亚洲欧洲午夜一线一品| 国产一级片在线| 日韩在线视频线视频免费网站| 亚洲麻豆精品| 久久躁日日躁aaaaxxxx| 免费在线国产视频| 97久久精品视频| 欧美日韩123区| 国产精品视频网站| 国产精品久久久久久久久久辛辛| 91久久精品国产91久久性色tv| 一区二区三区免费在线看| 精品久久一区二区三区蜜桃| 久久99性xxx老妇胖精品| 色一情一乱一伦一区二区三区| 成人免费在线观看av| 天天综合中文字幕| 国产精品啊啊啊| 男人揉女人奶房视频60分| 日韩不卡在线观看日韩不卡视频| 一区二区xxx| 丁香网亚洲国际| 日本高清www| 中文字幕一区二区三中文字幕| 三级av在线免费观看| 亚洲成av人片在线观看| 成人一级免费视频| 欧美一区二区福利在线| 污污视频在线免费看| 视频在线观看99| av影视在线看| 国产精品久久久久91| 精品国产亚洲一区二区三区| 精品综合久久久| 久久精品国产99久久| 精品国偷自产一区二区三区| 日韩精品成人一区二区在线| 91人妻一区二区三区| 久久综合九色综合97婷婷| 亚洲AV成人无码精电影在线| 精品国产成人av| 一卡二卡三卡在线观看| 日韩av在线精品| 操你啦视频在线| 国产成人激情小视频| 99re热精品视频| 天堂精品视频| 9国产精品视频| 亚洲一区二区三区四区精品| 久久久影视传媒| 免费在线观看黄视频| 欧美日韩你懂得| 欧美日韩免费做爰大片| 久久69精品久久久久久久电影好| gogo亚洲高清大胆美女人体| 国产精品免费一区二区三区四区 | 97免费观看视频| 亚洲女成人图区| 国产精品偷拍| 91青草视频久久| 激情婷婷综合| 男女激情无遮挡| 国产**成人网毛片九色| 视频国产一区二区| 91福利视频网站| 日韩精品福利| 97国产真实伦对白精彩视频8| 国产精品亚洲欧美一级在线| 视频一区二区精品| 亚洲欧美网站| 在线免费观看污视频| 一区二区三区不卡视频在线观看| 国产在成人精品线拍偷自揄拍| 中文字幕v亚洲ⅴv天堂| 高清av不卡| 久久精品人成| 一本综合精品| 伊人网综合视频| 午夜精品久久久久久久| 午夜老司机福利| 久久99精品久久久久久琪琪 | 在线综合亚洲欧美在线视频| 成人高清免费观看mv| 国产成人a亚洲精品| 美女亚洲一区| 蜜臀av午夜一区二区三区| 91在线视频18| 国产亚洲一区二区三区在线播放 | 99电影网电视剧在线观看| 欧美肥老太太性生活| 人人干人人干人人| 国产精品美女久久久久久2018| 亚洲精品国产精品国自产网站按摩| 亚洲日韩欧美视频| 久久青青视频| 五月天色一区| 另类调教123区| 日本黄色激情视频| 欧美老年两性高潮| 在线观看电影av| 国产精品久久久久久久天堂第1集| 雨宫琴音一区二区三区| 国产精品久久久久野外| 亚洲午夜av在线| 天天干天天操av| 91av在线免费观看| 视频精品在线观看| www.com黄色片| 亚洲乱码国产乱码精品精可以看 | 国产成人精品免费看| 久久高清免费视频| 日韩精品亚洲元码| 欧美一级大黄| 最新国产精品久久| 福利电影一区二区| 中文字幕免费在线观看视频| 伊人青青综合网站| 清纯唯美激情亚洲| 91丨porny丨探花| 国产清纯在线一区二区www| 国产精品毛片一区二区在线看舒淇| 久久6免费高清热精品| 亚洲综合小说图片| 四季av一区二区三区| 亚洲成人7777| 成人性爱视频在线观看| 亚洲精品免费一区二区三区| aa级大片欧美三级| 日韩一卡二卡在线观看| 精品国产一区二区三区忘忧草| 黄色a级片在线观看| 久久精品国产成人一区二区三区| 久草手机视频在线观看| 精品福利av导航| 国产精品亚洲d| 成人性生活视频免费看| 中文乱码免费一区二区| 黄色aaa大片| 国产女人18毛片水18精品| 日韩视频在线一区二区三区| 国精品人伦一区二区三区蜜桃|