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

Redis + MQ:高并發(fā)秒殺的技術(shù)方案與實(shí)現(xiàn)

開(kāi)發(fā) 架構(gòu)
系統(tǒng)可通過(guò)定時(shí)任務(wù)對(duì)比??Redis??流水、??MySQL??庫(kù)存流水與訂單表數(shù)據(jù):若??Redis??流水存在但訂單表無(wú)對(duì)應(yīng)記錄,說(shuō)明訂單生成失敗,需人工介入補(bǔ)單或回滾??Redis??庫(kù)存,避免少賣;若訂單表有記錄但??MySQL??庫(kù)存未扣減,則需觸發(fā)庫(kù)存補(bǔ)扣,避免多賣。

前言

在電商秒殺場(chǎng)景中,瞬間爆發(fā)的海量請(qǐng)求往往成為系統(tǒng)的生死考驗(yàn)。當(dāng)并發(fā)量達(dá)到數(shù)萬(wàn)甚至數(shù)十萬(wàn)QPS時(shí),傳統(tǒng)數(shù)據(jù)庫(kù)單表架構(gòu)難以支撐,而Redis與消息隊(duì)列(MQ)的組合憑借其高性能與可靠性,成為應(yīng)對(duì)高并發(fā)秒殺的黃金方案

方案總覽

用戶請(qǐng)求 → 前端生成Token → Redis執(zhí)行Lua腳本(預(yù)扣減+防重+流水)→ 發(fā)送RocketMQ事務(wù)消息 → 
[本地事務(wù)校驗(yàn)Redis結(jié)果] → MQ消息確認(rèn)(COMMIT/ROLLBACK)→ 消費(fèi)者消費(fèi)消息 → MySQL扣減庫(kù)存+記錄訂單

秒殺系統(tǒng)的核心訴求是抗并發(fā)、防超賣、保一致。Redis+MQ 方案通過(guò) “前端攔截 - 中間緩沖 - 后端落地” 的三層架構(gòu)實(shí)現(xiàn)這一目標(biāo):

  • 前端攔截:Redis通過(guò)Lua腳本原子性處理庫(kù)存預(yù)扣減,過(guò)濾無(wú)效請(qǐng)求;
  • 中間緩沖:MQ(如 RocketMQ)通過(guò)事務(wù)消息削峰填谷,確保流量平穩(wěn)進(jìn)入數(shù)據(jù)庫(kù);
  • 后端落地:MySQL最終存儲(chǔ)庫(kù)存與訂單數(shù)據(jù),通過(guò)事務(wù)消息保障與Redis的一致性。

流程拆解(示例代碼)

Redis 庫(kù)存預(yù)扣減

預(yù)扣減流程

開(kāi)始
  │
  ├─ 生成Token(前端)
  │
  ├─ 前端攜帶Token請(qǐng)求秒殺
  │
  ├─ 執(zhí)行Lua腳本
  │   │
  │   ├─ 檢查T(mén)oken是否存在(Hash結(jié)構(gòu))
  │   │   ├─ 存在 → 返回“重復(fù)提交”
  │   │   └─ 不存在 → 繼續(xù)
  │   │
  │   ├─ 獲取Redis庫(kù)存(String結(jié)構(gòu))
  │   │   ├─ 庫(kù)存不足 → 返回“庫(kù)存不足”
  │   │   └─ 庫(kù)存充足 → 繼續(xù)
  │   │
  │   ├─ 扣減Redis庫(kù)存并更新
  │   │
  │   └─ 記錄流水到Hash結(jié)構(gòu)
  │
  ├─ 返回扣減結(jié)果(成功/失敗)
  │
結(jié)束

Lua 腳本

-- 啟用Redis命令復(fù)制,確保腳本在集群環(huán)境中正確同步
redis.replicate_commands()

-- 1. 防重提交校驗(yàn):通過(guò)用戶ID+Token判斷是否重復(fù)提交
-- KEYS[2]為用戶ID(uid),ARGV[2]為本次請(qǐng)求的Token
if redis.call('hexists', KEYS[2], ARGV[2]) == 1 then
    return redis.error_reply('repeat submit')  -- 重復(fù)提交,返回錯(cuò)誤
end 

-- 2. 庫(kù)存充足性校驗(yàn)
local product_id = KEYS[1]  -- 商品ID
local stock = redis.call('get', KEYS[1])  -- 獲取當(dāng)前庫(kù)存
if not stock then  -- 庫(kù)存不存在(如商品未上架)
    return redis.error_reply('product not found')
end
if tonumber(stock) < tonumber(ARGV[1]) then  -- 庫(kù)存不足
    return redis.error_reply('stock is not enough')
end 

-- 3. 執(zhí)行庫(kù)存扣減
local remaining_stock = tonumber(stock) - tonumber(ARGV[1])
redis.call('set', KEYS[1], tostring(remaining_stock))  -- 更新庫(kù)存

-- 4. 記錄交易流水(用于后續(xù)一致性校驗(yàn))
local time = redis.call('time')  -- 獲取當(dāng)前時(shí)間(秒+微秒)
local currentTimeMillis = (time[1] * 1000) + math.floor(time[2] / 1000)  -- 轉(zhuǎn)換為毫秒時(shí)間戳
-- 存儲(chǔ)流水到Hash結(jié)構(gòu):用戶ID → Token → 流水詳情
redis.call('hset', KEYS[2], ARGV[2], 
    cjson.encode({
        action = '扣減庫(kù)存',
        product = product_id,
        from = stock,  -- 扣減前庫(kù)存
        to = remaining_stock,  -- 扣減后庫(kù)存
        change = ARGV[1],  -- 扣減數(shù)量
        token = ARGV[2],
        timestamp = currentTimeMillis
    })
)

return remaining_stock  -- 返回扣減后庫(kù)存

Java 調(diào)用 Lua

@Service
public class SeckillService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    // 加載Lua腳本
    private DefaultRedisScript<Long> stockScript;

    @PostConstruct
    public void init() {
        stockScript = new DefaultRedisScript<>();
        stockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("seckill.lua")));
        stockScript.setResultType(Long.class);
    }

    /**
     * 執(zhí)行Redis庫(kù)存預(yù)扣減
     * @param productId 商品ID
     * @param uid 用戶ID
     * @param quantity 購(gòu)買數(shù)量
     * @param token 防重Token
     * @return 扣減后庫(kù)存(-1表示失敗)
     */
    public Long preDeductStock(String productId, String uid, Integer quantity, String token) {
        try {
            // 執(zhí)行Lua腳本:KEYS = [商品ID, 用戶ID],ARGV = [數(shù)量, Token]
            return redisTemplate.execute(
                stockScript,
                Arrays.asList(productId, uid),
                quantity.toString(),
                token
            );
        } catch (Exception e) {
            log.error("Redis預(yù)扣減失敗", e);
            return -1L;
        }
    }
}

MySQL 庫(kù)存扣減

扣減流程圖

開(kāi)始
  │
  ├─ 發(fā)送半消息到RocketMQ
  │
  ├─ 執(zhí)行本地事務(wù)
  │   │
  │   ├─ 檢查Redis流水是否存在
  │   │   ├─ 存在 → 提交消息(COMMIT)
  │   │   └─ 不存在 → 回滾消息(ROLLBACK)
  │   │
  │   └─ 未知狀態(tài) → 等待回查
  │
  ├─ RocketMQ回查機(jī)制
  │   ├─ 有流水 → 提交消息
  │   └─ 無(wú)流水 → 回滾消息
  │
  ├─ 消息被消費(fèi)
  │   │
  │   ├─ 查詢數(shù)據(jù)庫(kù)當(dāng)前版本號(hào)(樂(lè)觀鎖)
  │   │
  │   ├─ 執(zhí)行庫(kù)存扣減(WHERE version = 當(dāng)前版本)
  │   │   ├─ 扣減成功 → 記錄數(shù)據(jù)庫(kù)流水
  │   │   └─ 扣減失敗 → 拋出異常(觸發(fā)重試)
  │   │
  ├─ 結(jié)束

發(fā)送半消息

系統(tǒng)首先向RocketMQ發(fā)送一條半消息Half Message)。此時(shí)消息處于不可消費(fèi)狀態(tài),需等待生產(chǎn)者確認(rèn)本地事務(wù)執(zhí)行結(jié)果后,才會(huì)被消費(fèi)者處理。

// 發(fā)送半消息
public void sendHalfMessage(String productId, String uid, String token, Integer quantity) {
    // 構(gòu)建消息
    Message message = new Message(
        "seckill_topic",  // 主題
        "stock_deduct",   // 標(biāo)簽
        JSON.toJSONString(new SeckillMessage(productId, uid, token, quantity)).getBytes()
    );
    // 發(fā)送事務(wù)消息
    TransactionSendResult result = rocketMQTemplate.sendMessageInTransaction(
        "seckill_producer_group",  // 生產(chǎn)者組
        message,
        null  // 本地事務(wù)參數(shù)(可傳遞上下文)
    );
    log.info("半消息發(fā)送結(jié)果:{}", result.getSendStatus());
}

本地事務(wù)校驗(yàn)

本地事務(wù)的核心是判斷Redis預(yù)扣減是否成功:

  • RedisLua腳本執(zhí)行成功(即庫(kù)存預(yù)扣減完成且流水已記錄),則向RocketMQ返回 提交COMMIT)指令,消息變?yōu)榭上M(fèi)狀態(tài);
  • Redis預(yù)扣減失敗(如庫(kù)存不足或重復(fù)提交),則返回回滾ROLLBACK)指令,消息被丟棄。
  • RocketMQ長(zhǎng)時(shí)間未收到本地事務(wù)結(jié)果(如生產(chǎn)者宕機(jī)),會(huì)觸發(fā)消息回查。此時(shí)系統(tǒng)通過(guò)檢查Redis中是否存在對(duì)應(yīng)交易流水,判斷是否需要提交消息:若流水存在,則提交;否則回滾。
@Component
public class SeckillTransactionListener implements TransactionListener {

    @Autowired
    private StringRedisTemplate redisTemplate;

    // 執(zhí)行本地事務(wù)
    @Override
    public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            SeckillMessage message = JSON.parseObject(new String(msg.getBody()), SeckillMessage.class);
            // 檢查Redis中是否存在對(duì)應(yīng)流水(驗(yàn)證預(yù)扣減成功)
            Boolean flag = redisTemplate.opsForHash().hasKey(
                message.getUid(),  // Hash key:用戶ID
                message.getToken()  // Hash field:Token
            );
            return flag ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.ROLLBACK;
        } catch (Exception e) {
            return RocketMQLocalTransactionState.UNKNOWN;  // 未知狀態(tài),觸發(fā)回查
        }
    }

    // 消息回查(解決超時(shí)未確認(rèn)問(wèn)題)
    @Override
    public LocalTransactionState checkLocalTransaction(MessageExt msg) {
        SeckillMessage message = JSON.parseObject(new String(msg.getBody()), SeckillMessage.class);
        // 回查邏輯:再次檢查流水是否存在
        Boolean flag = redisTemplate.opsForHash().hasKey(message.getUid(), message.getToken());
        return flag ? RocketMQLocalTransactionState.COMMIT : RocketMQLocalTransactionState.ROLLBACK;
    }
}

消費(fèi)消息并扣減 MySQL 庫(kù)存

消費(fèi)者監(jiān)聽(tīng)消息,執(zhí)行數(shù)據(jù)庫(kù)扣減(需保證冪等性): 消費(fèi)者接收到可消費(fèi)的消息后,執(zhí)行MySQL庫(kù)存扣減操作,并同步記錄數(shù)據(jù)庫(kù)中的交易流水。為確保消費(fèi)成功,需利用MQ的重試機(jī)制:若消費(fèi)失敗(如數(shù)據(jù)庫(kù)暫時(shí)不可用),MQ會(huì)自動(dòng)重試,直至消費(fèi)成功或達(dá)到最大重試次數(shù)(此時(shí)需人工介入處理)。

@Component
@RocketMQMessageListener(
    topic = "seckill_topic",
    consumerGroup = "seckill_consumer_group",
    messageModel = MessageModel.CLUSTERING
)
public class SeckillConsumer implements RocketMQListener<MessageExt> {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void onMessage(MessageExt message) {
        SeckillMessage msg = JSON.parseObject(new String(message.getBody()), SeckillMessage.class);
        String productId = msg.getProductId();
        int quantity = msg.getQuantity();

        // 數(shù)據(jù)庫(kù)扣減(使用樂(lè)觀鎖防超賣)
        String sql = "UPDATE product_stock " +
                    "SET stock = stock - ?, version = version + 1 " +
                    "WHERE product_id = ? AND stock >= ? AND version = ?";

        // 1. 查詢當(dāng)前版本號(hào)
        Integer version = jdbcTemplate.queryForObject(
            "SELECT version FROM product_stock WHERE product_id = ?",
            Integer.class,
            productId
        );

        // 2. 執(zhí)行扣減(樂(lè)觀鎖保證原子性)
        int rows = jdbcTemplate.update(sql, quantity, productId, quantity, version);
        if (rows > 0) {
            // 扣減成功:記錄數(shù)據(jù)庫(kù)流水
            jdbcTemplate.update(
                "INSERT INTO stock_flow (product_id, quantity, op_type, create_time) " +
                "VALUES (?, ?, 'SECKILL', NOW())",
                productId, quantity
            );
            // 確認(rèn)消費(fèi)成功(返回ACK)
        } else {
            // 扣減失敗:觸發(fā)重試(MQ默認(rèn)重試機(jī)制)
            throw new RuntimeException("數(shù)據(jù)庫(kù)扣減失敗,觸發(fā)重試");
        }
    }
}

一致性保障

為防止RedisMySQL數(shù)據(jù)不一致(如Redis扣減成功但MySQL扣減失敗),需定期對(duì)賬:

@Scheduled(cron = "0 0 */1 * * ?")  // 每小時(shí)執(zhí)行一次
public void reconcileStock() {
    // 1. 掃描Redis中未同步到MySQL的流水
    Set<String> uids = redisTemplate.keys("uid:*");  // 假設(shè)用戶ID前綴為uid:
    for (String uid : uids) {
        Map<Object, Object> tokenMap = redisTemplate.opsForHash().entries(uid);
        for (Map.Entry<Object, Object> entry : tokenMap.entrySet()) {
            String token = (String) entry.getKey();
            String flowJson = (String) entry.getValue();
            SeckillFlow flow = JSON.parseObject(flowJson, SeckillFlow.class);

            // 2. 檢查MySQL是否有對(duì)應(yīng)訂單
            Integer count = jdbcTemplate.queryForObject(
                "SELECT COUNT(1) FROM orders WHERE product_id = ? AND uid = ? AND token = ?",
                Integer.class,
                flow.getProduct(), flow.getUid(), token
            );

            if (count == 0) {
                // 3. 未找到訂單 → 人工介入或自動(dòng)回滾Redis庫(kù)存
                log.warn("發(fā)現(xiàn)不一致:Redis有流水但MySQL無(wú)訂單,product={}, uid={}", flow.getProduct(), uid);
                // redisTemplate.opsForValue().increment(flow.getProduct(), Integer.parseInt(flow.getChange()));
            }
        }
    }
}

系統(tǒng)可通過(guò)定時(shí)任務(wù)對(duì)比Redis流水、MySQL庫(kù)存流水與訂單表數(shù)據(jù):若Redis流水存在但訂單表無(wú)對(duì)應(yīng)記錄,說(shuō)明訂單生成失敗,需人工介入補(bǔ)單或回滾Redis庫(kù)存,避免少賣;若訂單表有記錄但MySQL庫(kù)存未扣減,則需觸發(fā)庫(kù)存補(bǔ)扣,避免多賣

總結(jié)

Redis + MQ 方案通過(guò)預(yù)扣減 + 事務(wù)消息 + 對(duì)賬三重機(jī)制,完美解決了高并發(fā)秒殺的核心痛點(diǎn):

  • Redis承擔(dān)高并發(fā)讀寫(xiě),通過(guò)Lua腳本確保原子性,防止超賣;
  • MQ事務(wù)消息保障RedisMySQL的最終一致性,避免數(shù)據(jù)斷層;
  • 流水對(duì)賬作為最后一道防線,及時(shí)發(fā)現(xiàn)并修復(fù)異常。
責(zé)任編輯:武曉燕 來(lái)源: 一安未來(lái)
相關(guān)推薦

2024-08-01 11:38:40

2019-10-30 16:54:08

golangredis數(shù)據(jù)庫(kù)

2018-09-15 04:59:01

2025-04-08 05:00:00

2025-02-20 00:01:00

2021-08-26 08:24:33

高并發(fā)秒殺系統(tǒng)

2022-03-31 17:38:09

高并發(fā)系統(tǒng)架構(gòu)設(shè)計(jì)負(fù)載均衡

2020-10-14 07:20:53

高并發(fā)

2024-10-08 10:10:00

削峰高并發(fā)流量

2024-07-03 11:01:55

2025-05-28 02:20:00

2025-06-13 07:42:13

2025-01-20 00:00:03

高并發(fā)秒殺業(yè)務(wù)

2025-07-28 02:22:00

2018-08-21 10:32:43

數(shù)據(jù)庫(kù)Redis高可用技術(shù)

2018-08-24 09:26:13

Redis高可用方式

2020-04-01 17:31:03

Redis系統(tǒng)秒殺

2020-04-13 08:33:39

高并發(fā)秒殺系統(tǒng)

2014-11-14 09:42:53

VoLTE
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

桃色av一区二区| 亚洲AV午夜精品| 久久国产成人精品| 欧美一级久久久| 欧美久久久久久久久久久久久 | 日韩精彩视频在线观看| 中文字幕国产亚洲| 黑人性生活视频| 中文在线资源| 亚洲欧美视频在线观看视频| 精品高清视频| 国产欧美日韩综合精品一区二区三区| 在线看片成人| zzjj国产精品一区二区| 国产肉体xxxx裸体784大胆| 激情久久一区二区| 第一福利永久视频精品| 亚洲制服欧美久久| 天堂在线视频网站| 国产在线精品不卡| 国产精品九九久久久久久久| 九九在线观看视频| 成人激情开心网| 亚洲精品福利在线| 超碰91在线播放| 韩国成人在线| 日韩欧美国产高清91| 8x8ⅹ国产精品一区二区二区| 女人偷人在线视频| 成人va在线观看| 亚洲一区二区三| 懂色av蜜臀av粉嫩av喷吹 | 99久久国产宗和精品1上映| 国产在线观看91| 国产目拍亚洲精品99久久精品| 国产一区二区无遮挡| 国产高潮流白浆喷水视频| 日本亚洲视频在线| 国产97免费视| 性无码专区无码| 亚洲三级电影在线观看| 蜜臀久久99精品久久久无需会员| 超碰97av在线| 精品freesex老太交| 国产丝袜一区二区三区免费视频 | 日批视频免费观看| 久久久精品网| 国产91色在线| 一级黄色av片| 日韩av午夜在线观看| 国产999精品久久久| 国产嫩bbwbbw高潮| 天堂影院一区二区| 国产精品福利网站| 中文字幕有码视频| 青青草国产精品亚洲专区无| 国产精品精品视频一区二区三区| 日本黄色中文字幕| 免费在线观看成人| 91精品国产自产在线老师啪| 91丨porny丨在线中文| 日日夜夜精品视频免费| 国产精品日日摸夜夜添夜夜av| 一级黄色在线观看| 麻豆成人免费电影| 91在线免费视频| 精品国产av 无码一区二区三区 | 一区二区日本视频| 日本国产欧美一区二区三区| 无码人妻一区二区三区线| 久久久天天操| 国产精品午夜视频| 国产老妇伦国产熟女老妇视频| 国内精品久久久久影院薰衣草| 91沈先生在线观看| 欧美综合视频在线| 久久精品夜色噜噜亚洲aⅴ| 亚洲高清在线播放| 国产在线更新| 欧美日韩午夜激情| 校园春色 亚洲色图| 国产精品视频一区二区三区综合| 日韩精品中午字幕| 欧美亚一区二区三区| 成人3d动漫在线观看| 欧美成人剧情片在线观看| 国产一二三四在线| 日本不卡高清视频| 操人视频欧美| 青青草在线免费观看| 国产精品网曝门| 大片在线观看网站免费收看| 国产传媒在线| 欧美精品一二三四| 国产精品300页| 国产精品videosex性欧美| 欧美激情视频网| 久久久久久久亚洲| 国产不卡视频在线观看| 日产精品高清视频免费| 18av在线视频| 欧美在线免费播放| 麻豆tv在线观看| 国内成人自拍| 国内精品国产三级国产在线专| 超碰在线观看91| 成人av资源在线观看| 亚洲日本japanese丝袜| 久草在线资源福利站| 欧美精品日韩一区| 中文字幕一区二区三区人妻电影| 欧美xxx在线观看| 国产精品av网站| 国模私拍视频在线| 国产精品久久国产精麻豆99网站| 欧美二区在线视频| 精品视频一区二区三区| 中文字幕精品久久| 久久久久久久久久久久久av| 国产成人免费在线视频| 亚洲精品高清视频| 九九色在线视频| 欧美日韩美少妇| 国产精品无码久久久久一区二区| 激情另类综合| www.av一区视频| 成人福利片网站| 欧美三级视频在线播放| 一级性生活大片| 亚洲电影av| av激情久久| 深夜国产在线播放| 91精品国产综合久久福利| www色com| 日韩一区精品字幕| 欧美裸体网站| 中文在线资源| 亚洲裸体xxxx| 特黄视频免费看| 99精品黄色片免费大全| 国产玉足脚交久久欧美| 99re8这里有精品热视频8在线| 久久综合伊人77777| 一级黄色片免费| 国产精品天干天干在线综合| 99草草国产熟女视频在线| 亚洲区小说区| 国产精品va在线播放我和闺蜜| 性xxxx视频| 日韩欧美亚洲国产一区| a级在线观看视频| 午夜宅男久久久| 久久艳妇乳肉豪妇荡乳av| 日本三级一区| 国产丝袜一区二区| 日韩乱码一区二区三区| 国产亚洲欧美日韩日本| 黄色片在线免费| 日韩一区电影| 成人网欧美在线视频| 看黄网站在线| 日韩精品在线网站| 日韩字幕在线观看| 久久综合久久综合久久综合| 北条麻妃在线一区| 色999国产精品| 亚洲在线观看视频网站| 福利成人导航| 日韩av在线看| 日韩av免费播放| 国产精品电影院| 免费国偷自产拍精品视频| 一区在线播放| 日本成人看片网址| 日韩国产91| 久久久天堂国产精品女人| 亚洲色图欧美视频| 欧美日韩一区二区三区四区五区 | 视频一区二区三区国产| 欧美日韩免费一区| 国产91在线播放九色| 国产精品18久久久久久久网站| 热99这里只有精品| 热久久天天拍国产| 不卡视频一区二区三区| 二吊插入一穴一区二区| 久久久999精品免费| 少妇高潮一区二区三区99小说| 色屁屁一区二区| 波多野结衣家庭教师| 92精品国产成人观看免费 | 免费在线不卡视频| 国产精品丝袜久久久久久app| 一卡二卡三卡四卡五卡| 久久人人精品| 精品视频在线观看一区二区| 蜜桃国内精品久久久久软件9| 91在线网站视频| 特黄毛片在线观看| 欧美成人免费小视频| 国模吧精品人体gogo| 日韩欧美视频一区| 成人黄色免费网| 天天综合网天天综合色| 日韩欧美国产成人精品免费| 久久久美女毛片| 亚洲欧美综合视频| 久久激五月天综合精品| 国产精品宾馆在线精品酒店| 国产精品精品国产一区二区| 久久久久久久久久久久久久久久av| 亚洲黑人在线| 国产成人综合久久| 男人久久天堂| 欧美激情精品久久久久久变态 | 中文字幕在线不卡一区| 国产中文字幕一区二区| 国产成人av一区二区三区在线| 国产a级片免费观看| 亚洲经典在线看| 日韩人妻一区二区三区蜜桃视频| 欧洲激情综合| 麻豆成人小视频| 精品国产午夜肉伦伦影院| 成人黄色免费在线观看| 精品成人免费一区二区在线播放| 欧美在线播放视频| 9999在线视频| 欧美黄色性视频| 日韩成人伦理| 欧美巨猛xxxx猛交黑人97人| av在线资源网| 国产午夜精品一区理论片飘花 | 久久综合色一综合色88| 熟妇高潮一区二区| 国产传媒欧美日韩成人| 日本高清一区二区视频| 免费一级欧美片在线观看| 成人黄色片视频| 久久xxxx精品视频| 妺妺窝人体色www在线小说| 99成人免费视频| 男女视频网站在线观看| 欧美日韩天堂| 久久av高潮av| 伊人精品在线| 性一交一乱一伧国产女士spa| 欧美日韩伊人| 欧洲精品在线播放| 亚洲精品九九| 男人日女人下面视频| 国产精品视频| 欧美成人精品欧美一级乱| 久久久久国产精品一区二区 | 国产精品23p| 午夜a成v人精品| 天天操夜夜操视频| 91成人看片片| 国产精品高潮呻吟av| 91精品国产综合久久精品图片| 99国产精品一区二区三区| 欧美一区二区精品在线| 亚洲第一黄色片| 国产婷婷色综合av蜜臀av| 国产综合视频一区二区三区免费| 在线观看欧美日韩国产| 欧美成人hd| 欧美大片免费观看| 成人免费短视频| 国产精品视频一| 国产精品日本一区二区不卡视频| 国产精华一区二区三区| 日韩免费电影在线观看| 日韩欧美在线电影| 欧美一区精品| 丰满爆乳一区二区三区| 日韩高清中文字幕一区| 91 视频免费观看| 成a人片国产精品| 性高潮久久久久久久| 国产精品卡一卡二| 麻豆视频在线观看| 精品国产乱码久久久久酒店| 中文字幕 人妻熟女| 欧美精品亚洲二区| 神马久久久久久久久久| 国产亚洲一区二区精品| 欧美卡一卡二| 国产精品久久久久久亚洲调教| 国产一区 二区| 欧美日韩一区二区视频在线观看 | 中文字幕一区日韩精品| 日本不卡久久| 亚洲午夜视频| 午夜免费看视频| av电影天堂一区二区在线观看| 18精品爽国产三级网站| 亚洲永久免费视频| www.av88| 亚洲开心激情网| 天堂av在线电影| 国产精品免费看久久久香蕉| 国产精品极品在线观看| 亚洲一区二区精品在线| 亚洲激情综合| av在线网站免费观看| 国产日产欧美一区二区视频| 久久久久久免费观看| 欧美三级资源在线| 亚洲 欧美 自拍偷拍| 欧美精品亚州精品| 日韩欧美专区| 亚洲福利av| 三级精品在线观看| 影音先锋人妻啪啪av资源网站| 亚洲丝袜自拍清纯另类| 自拍偷拍色综合| 亚洲精品一区在线观看香蕉| 三级资源在线| 亚洲一区亚洲二区亚洲三区| 国产一区99| 久久国产亚洲精品无码| 大陆成人av片| 免费人成视频在线| 欧美一区二区三区思思人| a√在线中文网新版址在线| 欧美性一区二区三区| 国产图片一区| www.亚洲视频.com| 国产不卡高清在线观看视频| 国产又粗又硬又长又爽| 欧美久久久久久久久久| 在线播放麻豆| 国产精品视频久久久久| 成人影院天天5g天天爽无毒影院| 毛片一区二区三区四区| xf在线a精品一区二区视频网站| 日本少妇xxxx动漫| 精品国产乱码久久久久久老虎 | 91精品天堂福利在线观看| 精品999在线| 国产精品丝袜在线| 在线观看国产小视频| 日韩在线视频播放| 亚洲精品伊人| 免费在线观看污污视频| 国精产品一区一区三区mba桃花| 日本少妇aaa| 3d动漫精品啪啪一区二区竹菊| 日本中文在线| 亚洲一区二区三区在线免费观看| 一本一道久久a久久精品蜜桃| 男人午夜视频在线观看| 一区二区三区精品视频| 免费a级片在线观看| 8090成年在线看片午夜| 国产传媒欧美日韩成人精品大片| 日本www高清视频| 国产精品激情偷乱一区二区∴| 一级特黄特色的免费大片视频| 不卡毛片在线看| 日韩极品在线| 欧美日韩亚洲自拍| 亚洲卡通动漫在线| 日韩一区免费视频| 国产黑人绿帽在线第一区| 日韩成人精品一区二区| 日本中文字幕精品| 五月婷婷综合激情| 国产黄色免费在线观看| 91精品久久久久久| 亚洲精品三级| 免费一级特黄3大片视频| 91精品国产欧美一区二区| 欧美性video| 欧美日韩国产一二| 国内精品国产成人| 国产精品第5页| 久久中文精品视频| 色天下一区二区三区| 向日葵污视频在线观看| 亚洲最大成人综合| 可以在线观看的黄色| 91香蕉亚洲精品| 亚洲一区视频| 97成人资源站| 亚洲人成电影网站色…| 国产电影一区二区| 国产在线观看福利| 国产精品超碰97尤物18| 天天干天天操av| 成人有码视频在线播放| 亚洲在线成人| 青青草手机在线观看| 亚洲男人天堂网| 图片一区二区| 又粗又黑又大的吊av| 国产精品原创巨作av| 亚洲成人第一网站| 久久久免费观看|