精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

怡红院av亚洲一区二区三区h| 成人欧美一区二区三区在线湿哒哒 | 亚欧精品在线视频| 五月天激情在线| av亚洲精华国产精华精华| 日韩美女av在线免费观看| 免费在线观看a级片| 美女一区二区在线观看| 欧美少妇bbb| 国产免费黄色一级片| 风间由美一区| 不卡在线观看av| 国产精品综合网站| 日本一区二区不卡在线| 久久资源中文字幕| 日韩大陆欧美高清视频区| 亚洲综合123| 成人福利视频| 亚洲国产视频在线| 亚洲国产精品久久久久婷婷老年| 黄色三级网站在线观看| 精品一区二区在线视频| 欧美在线观看网址综合| 国产大学生自拍| 欧美久久综合网| 亚洲精品在线观看网站| 亚洲网中文字幕| 亚洲www免费| 亚洲成a人在线观看| 亚洲国产欧美日韩| 视频国产在线观看| 国产成人免费视频一区| 国产日韩在线一区| 欧美特级黄色片| 中文一区二区| 国内自拍欧美激情| 国产免费嫩草影院| 欧美美女视频| 亚洲区在线播放| 国产 中文 字幕 日韩 在线| 玖玖玖电影综合影院| 欧美日韩国产一区二区三区地区| 日本精品免费在线观看| 老色鬼在线视频| 亚洲国产日韩一级| 免费网站在线观看视频| 1stkiss在线漫画| 亚洲人成在线观看一区二区| 一区二区av| 在线观看免费网站黄| 欧美国产欧美综合| 日本一区二区视频| 九一国产在线| 久久精品视频一区二区三区| 欧美激情一区二区三区在线视频| 天天干视频在线| 99久久久国产精品免费蜜臀| 国产一区二区中文字幕免费看| www.成人精品| 成人在线一区二区三区| 国产一区二区三区黄| 亚洲av成人精品日韩在线播放| 成人精品鲁一区一区二区| 国产高清精品一区二区| 日批视频免费播放| www.av精品| 你懂的视频在线一区二区| 神马精品久久| 国产欧美日韩一区二区三区在线观看| 日本一区精品| 午夜在线小视频| 亚洲男人的天堂网| 青青青青在线视频| av日韩亚洲| 欧美色精品天天在线观看视频| 在线黄色免费观看| 精品亚洲二区| 亚洲福利视频在线| 人人妻人人藻人人爽欧美一区| 国产成人精品999在线观看| 这里只有视频精品| 欧美卡一卡二卡三| 亚洲激情视频| 国产精品久久久久久超碰| 一级特黄aaa大片| 成人黄色av电影| 日韩精品一线二线三线| 成人福利在线观看视频| 亚洲v日本v欧美v久久精品| 日韩 欧美 高清| www.欧美| 日韩av在线播放资源| 国产性猛交xx乱| 红桃视频亚洲| 国产精品va在线播放| jizz国产视频| 久久亚洲影视婷婷| 大桥未久一区二区三区| 久草在线中文最新视频| 欧美人体做爰大胆视频| 黄色av网址在线观看| 郴州新闻综合频道在线直播| 色综合色综合久久综合频道88| 免费观看成人毛片| 国产在线国偷精品产拍免费yy| 国产一级特黄a大片99| av电影在线观看一区二区三区| 亚洲综合另类小说| 成人性生交免费看| 欧美亚洲大陆| 欧美成人免费大片| 中国精品一区二区| 99久久99久久精品国产片果冻| 欧美日韩视频免费在线观看| av资源在线播放| 91精品国产美女浴室洗澡无遮挡| 在线观看日本中文字幕| 黑人一区二区三区四区五区| 成人免费xxxxx在线观看| 深夜影院在线观看| 亚洲综合免费观看高清完整版 | 麻豆国产91在线播放| 国产综合精品一区二区三区| 国产精品剧情| 欧美色国产精品| 男生草女生视频| 影音先锋一区| 国产精品二区在线| 含羞草www国产在线视频| 欧洲人成人精品| 超碰97人人干| 亚洲乱码久久| 国产精品二区在线| 日本高清成人vr专区| 欧美精品v国产精品v日韩精品 | av永久不卡| 韩国福利视频一区| 97超碰资源站| 国产精品理伦片| 天堂社区在线视频| re久久精品视频| 国产精品一区二区三区毛片淫片 | 夜夜嗨av一区二区三区免费区 | 在线一区视频| 精品九九九九| 午夜av不卡| 日韩黄色高清视频| 国产又黄又猛又粗又爽| 91亚洲大成网污www| 精品无码国模私拍视频| 老司机精品视频在线播放| 午夜精品久久久久久99热软件| 亚洲a视频在线观看| 亚洲精品视频免费看| 制服下的诱惑暮生| 国产精品二区影院| 国产亚洲福利社区| 两个人看的在线视频www| 亚洲精品国产精品自产a区红杏吧 亚洲精品国产精品乱码不99按摩 亚洲精品国产精品久久清纯直播 亚洲精品国产精品国自产在线 | 久久精品中文字幕一区| 国产麻豆免费观看| 亚洲综合在线视频| 欧美成人三级伦在线观看| 亚洲人妖在线| 欧美精品一区二区三区四区五区| 免费欧美电影| 自拍偷拍亚洲欧美| 国产精品无码一区二区桃花视频| 亚洲男人天堂av网| 亚洲av人人澡人人爽人人夜夜| 亚洲少妇自拍| 日韩国产欧美一区| 国产美女视频一区二区| 午夜美女久久久久爽久久| 国家队第一季免费高清在线观看| 欧美视频一区二区三区在线观看| 在线观看黄网址| 国产成a人亚洲精品| 亚洲中文字幕无码专区| 日韩精品一区二区久久| 99国产在线| 亚洲国产欧美日本视频| 久久精品2019中文字幕| 丰满少妇高潮在线观看| 色综合天天综合网天天看片| 欧美巨胸大乳hitomi| 国产91精品免费| 国产成人久久婷婷精品流白浆| 欧美电影一区| 国精产品一区二区| 99久久久成人国产精品| 96精品视频在线| 日本免费中文字幕在线| 精品99999| 国产精品久久久久久久久久久久久久久久| 亚洲精品午夜久久久| 美女爆乳18禁www久久久久久| 黄网站免费久久| aa在线免费观看| 一区二区不卡| 性高潮久久久久久久久| 卡通动漫国产精品| 91亚洲精品一区二区| 26uuu亚洲电影| 欧美情侣性视频| 国产黄色在线| 亚洲电影av在线| 亚洲天堂网在线观看视频| 天天色天天操综合| 小泽玛利亚一区| 欧美激情在线看| 97香蕉碰碰人妻国产欧美| 国产综合久久久久影院| 国产精品69页| 国产欧美一区二区色老头 | 亚久久调教视频| 奇米777四色影视在线看| 欧美美女视频| 秋霞在线观看一区二区三区| 99国产精品久久一区二区三区| 国产精品女主播视频| 成人影院av| 91精品国产91久久久久久不卡| 黄色av免费在线| 这里只有精品丝袜| 男男电影完整版在线观看| 亚洲国产成人精品女人久久久| 国产手机av在线| 欧美人狂配大交3d怪物一区| 中文字幕在线观看视频免费| 精品国产乱码久久久久久虫虫漫画 | 国产乱码一区二区| 欧美日韩不卡一区| 中文字幕一区二区在线视频 | 一区二区国产欧美| 欧美体内she精视频| 无码人妻久久一区二区三区| 欧美日韩午夜激情| 中文字幕一区二区三区精品 | 国产精品露脸视频| 色噜噜狠狠成人中文综合| 亚洲黄色小说图片| 欧美视频一区二区三区…| 日韩精品――中文字幕| 亚洲高清视频的网址| 国产性70yerg老太| 亚洲国产中文字幕在线视频综合| 免费中文字幕在线观看| 夜夜嗨av一区二区三区四季av| 欧美人禽zoz0强交| 一区二区三区在线视频观看58| 丝袜 亚洲 另类 欧美 重口| 亚洲男人的天堂一区二区| 欧美黑人一级片| 亚洲一级二级在线| 久久高清免费视频| 欧美三级免费观看| 国产情侣小视频| 精品视频一区二区不卡| 亚洲综合网av| 91精品免费在线| 亚洲国产av一区二区| 亚洲精品在线网站| 可以在线观看的av| 色午夜这里只有精品| 成人黄色在线电影| 国内偷自视频区视频综合| 男人皇宫亚洲男人2020| 国产精品久久77777| 国产精品18| 国产精品一区二区三区四区五区 | 亚洲a∨精品一区二区三区导航| 国产ts人妖一区二区三区| 亚洲日本在线观看视频| 91香蕉亚洲精品| 欧美激情99| 性欧美精品一区二区三区在线播放 | 精品亚洲一区二区三区四区五区| 国产区高清在线| 久久在线精品视频| 国产精选在线| 国产精品美女免费视频| 国产精品亚洲一区二区在线观看| 好吊色欧美一区二区三区| 精品视频免费在线观看| 成人短视频在线观看免费| 亚洲在线视频| 中文字幕资源在线观看| av福利精品导航| 亚洲精品国产精品国自| 亚洲一二三四久久| 日本精品入口免费视频| 欧美成人一级视频| 精品三级久久久久久久电影聊斋| 久久精品国产欧美激情| 成人免费图片免费观看| 成人字幕网zmw| 香蕉精品久久| www插插插无码免费视频网站| 日本美女一区二区三区| 亚洲av成人片无码| 国产精品不卡一区二区三区| 中文字幕在线字幕中文| 欧美老女人第四色| 免费在线看v| 欧美激情videos| 欧美天堂一区| 欧美连裤袜在线视频| 午夜性色一区二区三区免费视频| 性生交免费视频| 成人国产精品免费| 国产精品视频一区二区三 | 成人免费在线视频观看| 亚洲天堂一区在线观看| 欧美xxxx老人做受| 日本电影在线观看网站| 欧美一区二区.| caoporn成人| 四虎免费在线观看视频| 日韩成人精品在线| 国产传媒第一页| 亚洲h精品动漫在线观看| 国产又大又黑又粗| 社区色欧美激情 | 日韩性xxx| 免费国产在线精品一区二区三区| 韩日在线一区| 俄罗斯女人裸体性做爰| 亚洲免费色视频| 97超碰人人草| www国产91| 欧美性生活一级| 性欧美videosex高清少妇| 久久亚洲欧美| www.av天天| 色综合色综合色综合| 三级做a全过程在线观看| 午夜免费久久久久| 女同一区二区三区| 免费在线a视频| 99精品视频一区| 日韩精品手机在线| 亚洲国产另类久久精品| 99riav视频在线观看| 亚洲最大成人网色| 欧美成人亚洲| 伊人av在线播放| 夜夜嗨av一区二区三区四季av| 亚洲va欧美va| 国产综合在线视频| 欧美人体视频| 久久精品午夜福利| 欧美国产成人在线| 中文字幕一区二区在线视频| xxxx性欧美| 亚洲**毛片| 每日在线观看av| 99re热这里只有精品免费视频| www.日本精品| 亚洲欧洲午夜一线一品| 日本美女久久| 国产日韩第一页| 国产成人午夜高潮毛片| 99热在线观看免费精品| 亚洲欧美色图片| 九九热这里有精品| 9色视频在线观看| 成人免费av网站| 高清乱码免费看污| 中文字幕视频在线免费欧美日韩综合在线看| 久久久免费人体| 色一情一乱一乱一区91| 97久久超碰国产精品| 波多野结衣家庭主妇| 久久人人爽人人爽爽久久| 91成人午夜| 成人羞羞国产免费网站| 国产精品久久久久久久久免费樱桃 | 卡一卡二卡三在线观看| 欧美久久久久久久久久| 久久99亚洲网美利坚合众国| 蜜桃欧美视频| 国内精品免费**视频| 日韩乱码一区二区| 一区二区三区亚洲| 亚洲一区网址| mm1313亚洲国产精品无码试看| 亚洲欧美国产三级| 视频一区二区三区在线看免费看| 91精品国产综合久久香蕉最新版 | 9久久婷婷国产综合精品性色| 自拍视频在线观看一区二区| 欧日韩在线视频| 国产欧美中文字幕| 亚洲人www| 国产大学生自拍| 国产一区二区三区直播精品电影 | 欧美精品一区二区三区高清aⅴ | 欧美精品123区| 深夜av在线|