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

從 0 到 1 解決超賣問題(從原理到分布式高并發方案)

數據庫 其他數據庫
在電商秒殺、促銷活動等高頻并發場景中,“超賣” 是最棘手的問題之一。比如某商品庫存僅100件,最終卻賣出120件,不僅會引發用戶投訴,還會造成商家信譽損失。

引言

在電商秒殺、促銷活動等高頻并發場景中,“超賣” 是最棘手的問題之一。比如某商品庫存僅100件,最終卻賣出120件,不僅會引發用戶投訴,還會造成商家信譽損失。

為什么會出現超賣?

復現超賣

數據庫表:product_stock(存儲商品庫存)
CREATE TABLE `product_stock` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主鍵',
  `product_id` bigint NOT NULL COMMENT '商品ID',
  `stock` int NOT NULL DEFAULT '0' COMMENT '庫存數量',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品庫存表';

-- 初始化數據:商品ID=1001,庫存=100
INSERT INTO `product_stock` (`product_id`, `stock`) VALUES (1001, 100);
錯誤的庫存扣減邏輯
// Entity實體
@Data
@TableName("product_stock")
public class ProductStock {
    @TableId(type = IdType.AUTO)
    private Long id;
    private Long productId;
    private Integer stock;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
}

// Mapper接口
public interface ProductStockMapper extends BaseMapper<ProductStock> {
    // 按商品ID查詢庫存
    @Select("SELECT * FROM product_stock WHERE product_id = #{productId}")
    ProductStock getByProductId(@Param("productId") Long productId);
    
    // 扣減庫存(僅更新,無判斷)
    @Update("UPDATE product_stock SET stock = stock - 1 WHERE product_id = #{productId}")
    int decreaseStock(@Param("productId") Long productId);
}

// Service實現
@Service
public class StockService {
    @Autowired
    private ProductStockMapper stockMapper;
    
    // 錯誤的扣減邏輯:先查庫存,再扣減(非原子)
    @Transactional
    public boolean decreaseStockWrong(Long productId) {
        // 1. 查詢當前庫存
        ProductStock stock = stockMapper.getByProductId(productId);
        if (stock == null || stock.getStock() <= 0) {
            // 庫存不足,返回失敗
            returnfalse;
        }
        // 2. 扣減庫存(此時可能已有其他線程修改了庫存)
        int rows = stockMapper.decreaseStock(productId);
        return rows > 0;
    }
}

// Controller接口(供壓測調用)
@RestController
@RequestMapping("/stock")
public class StockController {
    @Autowired
    private StockService stockService;
    
    @PostMapping("/decrease/{productId}")
    public Result<?> decrease(@PathVariable Long productId) {
        boolean success = stockService.decreaseStockWrong(productId);
        return success ? Result.ok("扣減成功") : Result.error("庫存不足");
    }
}

解決方案

悲觀鎖

悲觀鎖的核心思路:讀取庫存時直接鎖定行數據,禁止其他線程修改,直到當前事務結束才釋放鎖,確保查 - 扣過程獨占。

// 1. Mapper新增“鎖定查詢”方法(Select For Update)
@Select("SELECT * FROM product_stock WHERE product_id = #{productId} FOR UPDATE")
ProductStock getByProductIdForUpdate(@Param("productId") Long productId);

// 2. Service修改為“鎖定查詢+扣減”(事務必須生效)
@Service
public class StockService {
    @Autowired
    private ProductStockMapper stockMapper;
    
    // 悲觀鎖方案:事務+行鎖
    @Transactional(isolation = Isolation.REPEATABLE_READ) // 事務隔離級別設為可重復讀
    public boolean decreaseStockPessimistic(Long productId) {
        // 1. 鎖定查詢:此時其他線程無法修改該商品的庫存行
        ProductStock stock = stockMapper.getByProductIdForUpdate(productId);
        if (stock == null || stock.getStock() <= 0) {
            returnfalse;
        }
        // 2. 扣減庫存(同一事務內,鎖未釋放,其他線程無法介入)
        int rows = stockMapper.decreaseStock(productId);
        return rows > 0;
    }
}

關鍵注意點:

  • 鎖范圍控制:SELECT ... FOR UPDATE默認是行鎖,但需確保product_id是索引(本文中是唯一索引),否則會升級為表鎖,導致性能驟降。
  • 事務隔離級別:需設置為REPEATABLE_READMySQL默認級別),避免不可重復讀導致的庫存判斷偏差。
  • 性能瓶頸:悲觀鎖是串行化處理請求,并發量過高時會出現線程阻塞,適合秒殺初期庫存充足、后期并發降低的場景。

樂觀鎖

樂觀鎖的核心思路:不主動鎖定數據,而是在扣減庫存時通過版本號庫存當前值判斷數據是否被修改,若被修改則重試,適合中低并發場景(QPS≤3000)。

// 1. Entity新增version字段(@Version注解是MyBatis-Plus的樂觀鎖標識)
@Data
@TableName("product_stock")
public class ProductStock {
    // 原有字段...
    @Version // 樂觀鎖版本號字段
    private Integer version; // 初始值為0
}

// 2. 配置MyBatis-Plus樂觀鎖插件
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 添加樂觀鎖插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

// 3. Mapper修改扣減SQL(加入version判斷)
@Update("UPDATE product_stock SET stock = stock - 1, version = version + 1 " +
        "WHERE product_id = #{productId} AND stock > 0 AND version = #{version}")
int decreaseStockWithVersion(@Param("productId") Long productId, @Param("version") Integer version);

// 4. Service實現(加入重試機制,應對版本沖突)
@Service
public class StockService {
    @Autowired
    private ProductStockMapper stockMapper;
    
    // 樂觀鎖方案:版本號+重試
    public boolean decreaseStockOptimistic(Long productId) {
        int retryCount = 3; // 最大重試次數(避免無限循環)
        while (retryCount > 0) {
            // 1. 查詢當前庫存與版本號
            ProductStock stock = stockMapper.getByProductId(productId);
            if (stock == null || stock.getStock() <= 0) {
                returnfalse;
            }
            // 2. 扣減庫存(僅當version匹配時才生效)
            int rows = stockMapper.decreaseStockWithVersion(productId, stock.getVersion());
            if (rows > 0) {
                // 扣減成功,返回
                returntrue;
            }
            // 版本沖突,重試(重試前可加短暫延遲,減少CPU占用)
            retryCount--;
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        // 重試3次仍失敗,返回false
        returnfalse;
    }
}

Redis 分布式鎖

  • 鎖的獲取:通過RedisSET NX EX命令(不存在則設置值,同時設過期時間),確保同一時間只有一個線程獲取鎖。
  • 鎖的釋放:執行完庫存扣減后,刪除Redis中的鎖鍵(需校驗鎖的持有者,避免釋放別人的鎖)。
  • 庫存預熱:提前將數據庫中的庫存同步到Redis(如秒殺開始前,通過定時任務或接口加載),減少數據庫訪問。
@Service
public class StockService {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ProductStockMapper stockMapper;
    
    // Redis分布式鎖方案
    public boolean decreaseStockRedis(Long productId) {
        // 1. 定義Redis鎖鍵(按商品ID區分,避免鎖沖突)
        String lockKey = "lock:stock:" + productId;
        RLock lock = redissonClient.getLock(lockKey);
        
        try {
            // 2. 獲取鎖(等待時間0秒,鎖過期時間30秒,避免死鎖)
            // 等待時間0:獲取不到鎖直接返回,不阻塞;過期時間30秒:防止線程異常導致鎖無法釋放
            boolean locked = lock.tryLock(0, 30, TimeUnit.SECONDS);
            if (!locked) {
                // 未獲取到鎖,返回“活動太火爆”
                returnfalse;
            }
            
            // 3. 從Redis查詢庫存(原子操作)
            RAtomicLong redisStock = redissonClient.getAtomicLong("stock:" + productId);
            long currentStock = redisStock.get();
            if (currentStock <= 0) {
                // 庫存不足,返回失敗
                returnfalse;
            }
            
            // 4. 扣減Redis庫存(原子操作:decrementAndGet() = 先減1再返回)
            long newStock = redisStock.decrementAndGet();
            System.out.println("Redis庫存扣減后:" + newStock);
            
            // 5. 同步扣減數據庫庫存(最終一致性,可異步處理,此處為簡化用同步)
            // 注意:若Redis扣減成功但數據庫扣減失敗,需有補償機制(如定時任務對賬)
            stockMapper.decreaseStock(productId);
            
            returntrue;
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            returnfalse;
        } finally {
            // 6. 釋放鎖(僅當當前線程持有鎖時才釋放,避免釋放別人的鎖)
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }
}

關鍵優化點:

  • 鎖粒度控制:鎖鍵按lock:stock:{productId}定義,僅鎖定單個商品的庫存操作,避免一把鎖鎖所有商品導致的性能瓶頸。
  • 最終一致性:優先扣減Redis 庫存(高性能),再同步數據庫庫存。若同步失敗,可通過定時任務對賬(對比Redis與數據庫庫存差異,補全扣減),確保數據最終一致。
  • 鎖續期:RedissontryLock會自動為鎖續期(默認每10秒續期一次,續期到30秒),避免業務執行時間超過鎖過期時間導致的鎖提前釋放。

消息隊列異步削峰

  • 請求入隊:用戶請求先發送到消息隊列,而非直接扣減庫存,隊列暫存請求,避免瞬時高并發打垮業務系統。
  • 異步消費:消費者線程從隊列中拉取請求,按順序執行庫存扣減(Redis+ 數據庫),實現削峰填谷。
  • 可靠性保障:通過消息持久化、確認機制、死信隊列,確保請求不丟失、不重復處理。
聲明隊列、交換機與綁定
@Configuration
public class RabbitMQConfig {
    // 隊列名稱(庫存扣減隊列)
    public static final String STOCK_DECREASE_QUEUE = "stock.decrease.queue";
    // 交換機名稱
    public static final String STOCK_EXCHANGE = "stock.exchange";
    // 路由鍵
    public static final String STOCK_DECREASE_ROUTING_KEY = "stock.decrease.key";
    
    // 聲明隊列(持久化,避免消息丟失)
    @Bean
    public Queue stockDecreaseQueue() {
        return QueueBuilder.durable(STOCK_DECREASE_QUEUE)
                .deadLetterExchange("stock.dlx.exchange") // 死信交換機(處理失敗消息)
                .deadLetterRoutingKey("stock.dlx.key")
                .build();
    }
    
    // 聲明交換機(topic類型,支持通配符路由)
    @Bean
    public TopicExchange stockExchange() {
        return ExchangeBuilder.topicExchange(STOCK_EXCHANGE).durable(true).build();
    }
    
    // 綁定隊列與交換機
    @Bean
    public Binding stockDecreaseBinding() {
        return BindingBuilder.bind(stockDecreaseQueue())
                .to(stockExchange())
                .with(STOCK_DECREASE_ROUTING_KEY);
    }
    
    // 聲明死信隊列與交換機(處理消費失敗的消息,如庫存不足、數據庫異常)
    @Bean
    public Queue stockDlxQueue() {
        return QueueBuilder.durable("stock.dlx.queue").build();
    }
    @Bean
    public TopicExchange stockDlxExchange() {
        return ExchangeBuilder.topicExchange("stock.dlx.exchange").durable(true).build();
    }
    @Bean
    public Binding stockDlxBinding() {
        return BindingBuilder.bind(stockDlxQueue())
                .to(stockDlxExchange())
                .with("stock.dlx.key");
    }
}
生產者
@RestController
@RequestMapping("/stock")
public class StockController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedissonClient redissonClient;
    
    // 消息隊列方案:請求先入隊
    @PostMapping("/decrease/mq/{productId}")
    public Result<?> decreaseWithMQ(@PathVariable Long productId) {
        try {
            // 1. 先判斷Redis庫存(快速失敗,避免無效消息入隊)
            RAtomicLong redisStock = redissonClient.getAtomicLong("stock:" + productId);
            if (redisStock.get() <= 0) {
                return Result.error("庫存不足");
            }
            
            // 2. 生成唯一消息ID(避免重復消費,如用戶重復提交)
            String messageId = UUID.randomUUID().toString();
            // 3. 構建消息體(包含商品ID、消息ID)
            Map<String, Object> message = new HashMap<>();
            message.put("productId", productId);
            message.put("messageId", messageId);
            
            // 4. 發送消息到隊列
            rabbitTemplate.convertAndSend(
                    RabbitMQConfig.STOCK_EXCHANGE,
                    RabbitMQConfig.STOCK_DECREASE_ROUTING_KEY,
                    message,
                    msg -> {
                        // 設置消息持久化+消息ID
                        msg.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                        msg.getMessageProperties().setMessageId(messageId);
                        return msg;
                    }
            );
            
            return Result.ok("請求已接收,正在處理");
        } catch (Exception e) {
            return Result.error("請求失敗,請稍后再試");
        }
    }
}
消費者
@Component
public class StockDecreaseConsumer {
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ProductStockMapper stockMapper;
    // 用于記錄已處理的消息ID(避免重復消費,可存Redis或本地緩存)
    private final Set<String> processedMessageIds = Collections.synchronizedSet(new HashSet<>());
    
    @RabbitListener(queues = RabbitMQConfig.STOCK_DECREASE_QUEUE)
    public void consume(Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        String messageId = message.getMessageProperties().getMessageId();
        Map<String, Object> body = (Map<String, Object>) message.getPayload();
        Long productId = (Long) body.get("productId");
        
        try {
            // 1. 防重復消費:判斷消息是否已處理
            if (processedMessageIds.contains(messageId)) {
                // 已處理,手動確認消息
                channel.basicAck(deliveryTag, false);
                return;
            }
            
            // 2. Redis分布式鎖(確保單商品庫存扣減串行化)
            String lockKey = "lock:stock:" + productId;
            RLock lock = redissonClient.getLock(lockKey);
            boolean locked = lock.tryLock(0, 30, TimeUnit.SECONDS);
            if (!locked) {
                // 未獲取到鎖,拒絕確認(消息會重新入隊,等待下次消費)
                channel.basicNack(deliveryTag, false, true);
                return;
            }
            
            try {
                // 3. 扣減Redis庫存
                RAtomicLong redisStock = redissonClient.getAtomicLong("stock:" + productId);
                long currentStock = redisStock.get();
                if (currentStock <= 0) {
                    // 庫存不足,確認消息(避免重復處理)
                    channel.basicAck(deliveryTag, false);
                    return;
                }
                redisStock.decrementAndGet();
                
                // 4. 扣減數據庫庫存
                stockMapper.decreaseStock(productId);
                
                // 5. 標記消息已處理
                processedMessageIds.add(messageId);
                // 6. 確認消息(消息從隊列刪除)
                channel.basicAck(deliveryTag, false);
                System.out.println("異步扣減成功:商品" + productId + ",消息ID" + messageId);
            } finally {
                // 釋放鎖
                if (lock.isHeldByCurrentThread()) {
                    lock.unlock();
                }
            }
        } catch (Exception e) {
            // 消費失敗,拒絕確認并將消息送入死信隊列(避免無限重試)
            channel.basicNack(deliveryTag, false, false);
            System.err.println("異步扣減失敗:商品" + productId + ",錯誤:" + e.getMessage());
        }
    }
}

關鍵保障:

  • 防重復消費:通過messageId+本地緩存(或Redis)記錄已處理消息,避免用戶重復提交導致的重復扣減。
  • 消息不丟失:

隊列與消息均設置為持久化。

生產者開啟publisher-confirm(確認消息已到達交換機)。

消費者手動確認消息(basicAck),消費成功才刪除消息。

  • 失敗處理:消費失敗的消息送入死信隊列,后續可人工排查或通過定時任務重試。

方案選型

超賣問題的本質是并發下操作非原子化,解決思路從保證原子性逐步升級到異步削峰

  • 數據庫方案是基礎,通過悲觀鎖 / 樂觀鎖確保單庫操作原子性,適合低并發。
  • Redis分布式鎖解決了分布式場景的原子性問題,性能提升顯著,是中高并發的首選。
  • 消息隊列 + Redis鎖則通過異步化應對超高并發,適合大型秒殺等極端場景。

場景

推薦方案

優點

缺點

單機 / 低并發

數據庫樂觀鎖

實現簡單,無需額外組件

分布式場景不生效

分布式 / 中高并發

Redis 分布式鎖

性能高,支持分布式

需維護 Redis,需處理一致性

分布式 / 超高并發

消息隊列 + Redis 分布式鎖

抗瞬時高并發,削峰填谷

實現復雜,需維護消息隊列

建議

  • 庫存預熱:秒殺活動前10分鐘,將庫存同步到Redis,避免活動開始時大量請求查詢數據庫。
  • 接口限流:通過Spring Cloud GatewaySentinel對秒殺接口限流(如單IP每分鐘最多請求5次),過濾無效請求。
  • 降級熔斷:當Redis或數據庫異常時,快速返回活動暫時不可用,避免系統雪崩。
  • 對賬機制:定時(如每5分鐘)對比Redis與數據庫庫存,若存在差異,以數據庫為準同步Redis(確保最終一致性)。
責任編輯:武曉燕 來源: 一安未來
相關推薦

2025-04-01 01:04:00

Redis集群緩存

2024-01-08 08:05:08

分開部署數據體系系統拆分

2024-01-09 08:00:58

2021-11-26 06:43:19

Java分布式

2017-09-01 05:35:58

分布式計算存儲

2023-09-14 15:44:46

分布式事務數據存儲

2020-11-26 09:38:19

分布式架構系統

2021-09-23 12:14:50

Redis分布式優化

2022-12-04 22:41:15

IPC分布式機制

2022-05-09 08:35:43

面試產品互聯網

2021-04-29 19:07:33

Redis演進微服務

2016-11-28 16:23:23

戴爾

2017-05-27 09:23:10

IOS框架APP框架代碼

2025-03-12 00:50:00

關系型數據庫MySQL

2017-12-12 14:51:15

分布式緩存設計

2024-06-07 07:41:03

2024-06-12 09:06:48

2022-03-15 09:30:00

美團方案實踐

2021-05-11 07:51:30

React ref 前端

2023-05-18 14:02:00

分布式系統冪等性
點贊
收藏

51CTO技術棧公眾號

国产视频一区二区视频| 欧美裸体网站| 日本一二三区不卡| 丝袜连裤袜欧美激情日韩| 欧美日韩加勒比精品一区| 日韩欧美精品久久| 性中国古装videossex| 中日韩男男gay无套| 中文字幕一区电影| 一区二区在线免费观看视频| 国产福利片在线观看| 欧美激情一区不卡| 国产尤物91| 在线视频 91| 亚洲另类自拍| 久久综合色88| 2019男人天堂| 精品三级av在线导航| 欧美久久久久久蜜桃| 大j8黑人w巨大888a片| 精品孕妇一区二区三区| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 欧美亚洲一级| 欧美国产日韩二区| 青青草华人在线视频| 欧美三级午夜理伦三级小说| 91麻豆精品国产91久久久资源速度| 国产最新免费视频| 女同一区二区免费aⅴ| 国产精品第一页第二页第三页| 国产在线一区二| 国产免费叼嘿网站免费| 日本系列欧美系列| 欧美一级淫片播放口| 久草视频免费在线播放| 久久久久久久久久久久久久| 国产亚洲一区二区在线| 亚洲精品乱码久久久久久久| 免费精品一区| 91麻豆精品国产| 国产视频1区2区3区| 欧美电影免费观看高清完整| 精品福利在线看| www.xxx麻豆| 污视频网站免费在线观看| 国产精品久久久久精k8| 亚洲高清视频一区| 97超碰人人在线| 久久日韩精品一区二区五区| 精品乱码一区二区三区| 日韩中文字幕影院| 成人av在线资源| 国产精品一区免费观看| 国产成人自拍一区| 成人国产精品免费观看视频| 99理论电影网| 六月婷婷综合网| 成人一区二区三区视频| 国产精品国产精品| 色综合免费视频| 99视频国产精品| 久久精品欧美| 国产1区2区3区在线| 国产精品三级av| 免费在线观看污污视频| 国产黄大片在线观看画质优化| 亚洲色图欧美激情| 91成人综合网| 欧美aa在线观看| 欧美性猛交xxxx免费看漫画| 欧美综合在线观看视频| 日韩三区免费| 欧美一级二级在线观看| 欧美久久久久久久久久久| 伦理一区二区| 一色桃子一区二区| 综合 欧美 亚洲日本| 综合久久综合| 97超视频免费观看| 自拍偷拍色综合| 国产美女精品在线| 国产精品一码二码三码在线| 毛片在线能看| 亚洲桃色在线一区| 日本a在线免费观看| 性欧美18一19sex性欧美| 欧美精选午夜久久久乱码6080| 免费不卡av网站| 亚洲精品亚洲人成在线| 色小说视频一区| 国产在线视频二区| 青青草国产精品亚洲专区无| 亚洲aaaaaa| 黄色在线网站| 一区二区高清在线| 91av俱乐部| 涩爱av色老久久精品偷偷鲁| 亚洲免费av电影| 精品国产视频在线观看| 国产亚洲毛片| 91欧美精品成人综合在线观看| 天天操天天射天天舔| 国产精品另类一区| 啊啊啊一区二区| 欧美黄色一级| 一区国产精品视频| 五月天综合激情| 国产在线精品免费| 日本一区二区三区视频免费看| 亚洲性图自拍| 欧美日韩国产免费一区二区| 天堂www中文在线资源| 久久中文视频| 人体精品一二三区| 亚洲精品久久久久久久久久久久久久 | 国产xxx69麻豆国语对白| 国产人妻精品一区二区三区| 久久精品一区蜜桃臀影院| 日韩中文字幕在线不卡| 芒果视频成人app| 欧美v亚洲v综合ⅴ国产v| 少妇高潮惨叫久久久久| 亚洲欧美久久久| 国产精品久久久久久久免费大片 | 国产欧美精品一区二区色综合朱莉 | 国产美女精品视频免费观看| 国产又爽又黄网站亚洲视频123| 亚洲女爱视频在线| 中文字幕永久有效| 日韩精品午夜| 韩日欧美一区二区| 成人午夜免费福利| 亚洲蜜桃精久久久久久久| 动漫av免费观看| 欧美激情在线精品一区二区三区| 97久久伊人激情网| 亚洲精品国偷拍自产在线观看蜜桃| 综合亚洲深深色噜噜狠狠网站| 丰满少妇在线观看| 国产剧情一区| 国产成人综合精品| 国产小视频在线观看| 精品人伦一区二区三区蜜桃网站| 任你躁av一区二区三区| 亚洲手机视频| 国产精品国产三级国产专区53| 羞羞的视频在线看| 日韩欧美亚洲国产另类 | 欧美黄色一区| 91精品天堂| 午夜激情在线| 精品成人一区二区三区| 免费观看一级视频| 成人动漫一区二区三区| 热99这里只有精品| 亚洲精品亚洲人成在线观看| 日韩**中文字幕毛片| 男人天堂综合| 欧美系列日韩一区| 小早川怜子一区二区的演员表| 美女精品自拍一二三四| 在线观看亚洲视频啊啊啊啊| 亚洲午夜国产成人| 久久97久久97精品免视看| 老牛影视av牛牛影视av| 五月天网站亚洲| 中文字幕在线1| 男女男精品视频| 日本道在线视频| 给我免费播放日韩视频| 日本欧美国产在线| 在线观看完整版免费| 日韩视频一区二区三区在线播放| 青娱乐av在线| 91免费在线看| 亚洲人视频在线| 国模吧视频一区| 美女亚洲精品| 99精品美女视频在线观看热舞| 欧美高清自拍一区| 蜜桃视频在线免费| 91精品国产综合久久国产大片 | 成人免费在线观看| 91精品视频网| 影音先锋亚洲天堂| 国产精品久线观看视频| 怡红院一区二区| 日本亚洲一区二区| 2018中文字幕第一页| 免费一区二区三区视频导航| 91亚洲精品一区二区| 日韩av影片| 久久久精品久久久久| 亚洲欧美日韩精品永久在线| 777色狠狠一区二区三区| 影音先锋亚洲天堂| 亚洲欧美视频一区| 自拍偷拍视频亚洲| 成人福利在线看| 国产永久免费网站| 国产免费成人| 三级在线免费观看| 欧美码中文字幕在线| 国产伦精品一区二区三区在线 | 91精品久久久久久久91蜜桃| 一级免费在线观看| 亚洲色图清纯唯美| 亚洲天堂岛国片| 不卡一区二区在线| 欧美精品 - 色网| 久久都是精品| 亚洲人成无码网站久久99热国产 | 国产香蕉久久精品综合网| 潘金莲一级淫片aaaaaaa| 国产精品久久久亚洲一区| 蜜臀av.com| 日韩免费特黄一二三区| 久久精品日产第一区二区三区乱码| 国产亚洲久久| 国产日韩综合一区二区性色av| 亚洲第一av| 国语自产精品视频在线看抢先版图片 | 欧美交换配乱吟粗大25p| 久久高清免费| 日韩影片在线播放| 亚洲人挤奶视频| 精品国产第一页| 成人精品毛片| 国产福利久久精品| 亚洲天堂av资源在线观看| 成人国产在线视频| 视频欧美精品| 国产情人节一区| 99久久伊人| 国产精品白丝jk喷水视频一区| 另类专区亚洲| 日韩美女免费线视频| 久草免费在线视频| 91大神福利视频在线| 国产v日韩v欧美v| 91极品女神在线| 国产精品论坛| 欧美野外猛男的大粗鳮| 色偷偷偷在线视频播放 | 热久久久久久| 国产精品久久久久久久久借妻| 亚洲欧洲美洲av| 全球成人中文在线| 色豆豆成人网| 国产精品爽黄69天堂a| 伦一区二区三区中文字幕v亚洲| 国产精品草莓在线免费观看 | 91麻豆制片厂| 中文字幕欧美一| 91人妻一区二区三区蜜臀| 亚洲欧美日韩电影| 欧美人妻精品一区二区免费看| 亚洲精品一二三| 国产真人真事毛片| 精品久久久久久中文字幕| 国产精品黄色大片| 在线免费视频一区二区| 这里只有久久精品视频| 欧美精品日韩一本| 亚洲国产999| 日韩精品在线观看一区二区| 黄色av网站在线看| 久久精品国产精品亚洲| 丁香花在线电影| 欧美亚洲视频在线观看| 欧美黄页在线免费观看| 亚洲一区二区三区视频| 欧美色图婷婷| 亚洲精品中字| 亚洲视频一区| 色哟哟精品视频| 国产高清亚洲一区| 法国伦理少妇愉情| 一区在线播放视频| 国产成人在线观看网站| 一本色道a无线码一区v| 国产精品人妻一区二区三区| 欧美成人精品3d动漫h| 免费人成黄页在线观看忧物| 久久精品欧美视频| 午夜影院在线播放| 成人久久18免费网站图片| 白嫩白嫩国产精品| 水蜜桃一区二区三区| 欧美午夜a级限制福利片| 日韩欧美xxxx| 粉嫩在线一区二区三区视频| 88久久精品无码一区二区毛片| 亚洲欧美日韩综合aⅴ视频| 欧美一二三区视频| 91精品国产欧美日韩| 蜜芽tv福利在线视频| 九九热这里只有精品6| 性欧美1819sex性高清| 国产精品一区二区三区免费观看| 日韩久久综合| 黄在线观看网站| 国产成人aaa| 国产精品久久国产精麻豆96堂| 亚洲成人动漫精品| 国产精品亚洲lv粉色| 亚洲日韩欧美视频一区| jizz一区二区三区| 成人免费福利在线| 国产免费久久| 六月丁香激情网| 国产成人免费在线视频| jizzjizz日本少妇| 日韩欧美亚洲范冰冰与中字| 亚洲av综合色区无码一二三区| 色婷婷久久一区二区| 成人av观看| 国产欧美一区二区三区另类精品| 久久久国产精品| www.色欧美| 国产精品久久久久久久蜜臀| 亚洲精品男人的天堂| 亚洲国产成人精品久久| 污视频网站免费在线观看| 成人女保姆的销魂服务| 清纯唯美日韩| 黄色一级二级三级| 久久午夜电影网| 毛片视频网站在线观看| 亚洲福利视频网站| 成人福利影视| 国产九色精品| 99亚洲视频| 亚洲天堂资源在线| 亚洲成人免费在线观看| 欧美 日韩 国产 在线| 久久久久久国产三级电影| 欧洲大片精品免费永久看nba| 色呦呦网站入口| 久久国产福利国产秒拍| 一级免费黄色录像| 欧美美女网站色| 美女黄视频在线观看| 国产精品wwww| 久久大综合网| 日批视频在线看| 一区二区三区国产| 黑人乱码一区二区三区av| 久久久日本电影| 羞羞色国产精品网站| 成人在线免费播放视频| 国产女同互慰高潮91漫画| 在线免费观看av片| 美日韩在线视频| 99国产精品免费网站| 欧美,日韩,国产在线| 久久男人中文字幕资源站| 无码人妻丰满熟妇区五十路| 中文字幕日韩欧美在线| 亚洲aⅴ网站| 黄色成人在线免费观看| 菠萝蜜视频在线观看一区| 国产成人无码一区二区三区在线| 亚洲乱亚洲乱妇无码| 91亚洲精品| 老司机午夜网站| 99精品热视频| 国产精品成人久久久| 久久久精品免费视频| 国产人妖ts一区二区| 免费观看精品视频| 国产精品乱码妇女bbbb| 亚洲乱码精品久久久久..| 2021国产精品视频| 久久精品高清| 精品国产免费久久久久久婷婷| 色综合中文字幕国产| 免费黄色在线看| 精品国产区在线| 麻豆精品视频在线观看| 久久免费视频播放| 国产亚洲精品激情久久| 色妞ww精品视频7777| 成人精品小视频| 一区二区三区美女视频| 国产在线视频你懂得| 91黄色国产视频| 日韩精品电影一区亚洲| 久久国产精品二区| 一区二区三区高清国产| 一区二区日韩| 91小视频网站| 精品电影在线观看| 超碰免费公开在线| 欧美xxxx黑人又粗又长密月| 激情欧美一区二区三区在线观看| 亚洲精品www久久久久久| 日韩视频第一页| 精品久久久久久久| 亚洲激情 欧美|