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

基于代碼實操SpringBoot、Redis、LUA秒殺系統

開發 前端 Redis
本文主要目的還是用代碼實現一下防止商品超賣的功能,所以像制定秒殺計劃,展示商品等功能就不著重寫了。

[[410299]]

前言

那些吧redis基本的東西學的差不多了,卻沒有做過什么具體的項目實踐的,可以看看這篇文章做一個項目來鞏固知識。

相關需求&說明

一般來說秒殺系統的功能不會很多,有:

  1. 制定秒殺計劃。在某天幾點開始,售賣什么商品,準備賣多少個,持續多久。
  2. 展示秒殺計劃列表。一般都是顯示當天的,8點賣一些,10點賣一些這種。
  3. 商品詳情頁。
  4. 下單購買。
  5. 等等

本文主要目的還是用代碼實現一下防止商品超賣的功能,所以像制定秒殺計劃,展示商品等功能就不著重寫了。

還有電商的商品主要是SPU(例如iPhone 12,iPhone 11就是兩個SPU)及SKU(例如iPhone 12 64G 白色,iPhone 12 128G 黑色就是兩個SKU)的處理,展示的是SPU,購買扣庫存的是SKU,本文為了方便,就直接用product來替代了。

下單購買還會有一些前置條件,比如要經過風控系統,確認你是不是黃牛;營銷系統,有沒有相關的優惠券,虛擬貨幣之類的。

下單完成還要走庫管、物流,還有積分之類的,本文就不涉及了。 本文不涉及數據庫,一切都在Redis上操作,不過還是想說一下數據庫與緩存數據一致性的問題。

如果我們的系統并發不高,數據庫撐得住,則直接操作數據庫即可,為防止超賣,可以采用:

悲觀鎖

  1. select * from SKU表 where sku_id=1 for update

樂觀鎖

  1. update SKU表 set stock=stock-1 where sku_id=1 and update_version=舊版本號; 

果并發高一些,例如商品詳情頁一般并發最高,為了減少數據庫的壓力,都會使用Redis等緩存,為了保證數據庫與Redis的一致性,多是采用“修改后刪除”方案。 但是這個方案在更高并發情況下,如C10K、C10M等,在修改數據庫并刪除Redis內容的一瞬間,大量查詢并發會傳導至數據庫,產生異常。 這種情況,SPU詳情這種接口就堅決不能與數據庫連接起來。 步驟應該是:

  1. B端管理系統操作數據庫(這個并發不會高)。
  2. 數據入庫后,發送消息給MQ。
  3. 相關處理程序在接收到訂閱的MQ的Topic后,從數據庫取出信息,放入Redis。
  4. 相關服務接口只從Redis取數據。

代碼實現

在實際項目中,建議將ToC端的秒殺產品相關接口組合為一個微服務,product-server。售賣接口組合為一個微服務,order-server??梢詤⒖贾暗腟pring Cloud系列文章進行編碼,本文就簡單使用了一個Spring Boot工程。

秒殺計劃實體類

省略get/set

  1. public class SecKillPlanEntity implements Serializable { 
  2.     private static final long serialVersionUID = 8866797803960607461L; 
  3.  
  4.     /** 
  5.      * id 
  6.      */ 
  7.     private Long id; 
  8.  
  9.     /** 
  10.      * 商品id 
  11.      */ 
  12.     private Long productId; 
  13.  
  14.     /** 
  15.      * 商品名稱 
  16.      */ 
  17.     private String productName; 
  18.  
  19.     /** 
  20.      * 價格 單位:分 
  21.      */ 
  22.     private Long price; 
  23.  
  24.     /** 
  25.      * 劃線價 單位:分 
  26.      */ 
  27.     private Long linePrice; 
  28.  
  29.     /** 
  30.      * 庫存數 
  31.      */ 
  32.     private Long stock; 
  33.  
  34.     /** 
  35.      * 一個用戶只買一件商品標識 0否1是 
  36.      */ 
  37.     private int buyOneFlag; 
  38.  
  39.     /** 
  40.      * 計劃狀態 0未提交,1已提交 
  41.      */ 
  42.     private int planStatus; 
  43.  
  44.     /** 
  45.      * 開始時間 
  46.      */ 
  47.     private Date startTime; 
  48.  
  49.     /** 
  50.      * 結束時間 
  51.      */ 
  52.     private Date endTime; 
  53.  
  54.     /** 
  55.      * 創建時間 
  56.      */ 
  57.     private Date createTime; 

說明:

正如前文所說,秒殺的商品應該展示的是SPU,售賣扣庫存的是SKU,本文為了方便,只用product來替代。

用戶購買秒殺商品,有兩種方式:

  • 一個用戶只允許購買一件。
  • 一個用戶可以多次購買多件。

所以本類使用buyOneFlag做標識。

planStatus代表本次秒殺是否真正執行。0不展示給C端,不進行售賣;1展示給C端,進行售賣。

添加秒殺計劃&查詢秒殺計劃

  1. @RestController 
  2. public class ProductController { 
  3.  
  4.     @Resource 
  5.     private RedisTemplate<String, String> redisTemplate; 
  6.  
  7.     // 隨機生成秒殺計劃設置到Redis中 
  8.     @GetMapping("/addSecKillPlan"
  9.     @ResponseBody 
  10.     public DefaultResult<List<SecKillPlanEntity>> addSecKillPlan(@RequestParam("saledate") String saleDate) { 
  11.         DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 
  12.         Random rand = new Random(); 
  13.         Gson gson = new Gson(); 
  14.         List<SecKillPlanEntity> list = Lists.newArrayList(); 
  15.  
  16.         for (int i = 0; i < 10; i++) { 
  17.             long productId = rand.nextInt(100) + 1; 
  18.             long price = rand.nextInt(100) + 1; 
  19.             long stock = rand.nextInt(100) + 1; 
  20.  
  21.             String saleStartTime = " 10:00:00"
  22.             String saleEndTime = " 12:00:00"
  23.             int buyOneFlag = 0; 
  24.             if (i > 4) { 
  25.                 saleStartTime = " 14:00:00"
  26.                 saleEndTime = " 16:00:00"
  27.                 buyOneFlag = 1; 
  28.             } 
  29.  
  30.             SecKillPlanEntity entity = new SecKillPlanEntity(); 
  31.             entity.setId(i + 1L); 
  32.             entity.setProductId(productId); 
  33.             entity.setProductName("商品" + productId); 
  34.             entity.setBuyOneFlag(buyOneFlag); 
  35.             entity.setLinePrice(999999L); 
  36.             entity.setPlanStatus(1); 
  37.             entity.setPrice(price * 100); 
  38.             entity.setStock(stock); 
  39.             entity.setEndTime(Date 
  40.                     .from(LocalDateTime.parse(saleDate + saleEndTime, dtf).atZone(ZoneId.systemDefault()).toInstant())); 
  41.             entity.setStartTime(Date.from
  42.                     LocalDateTime.parse(saleDate + saleStartTime, dtf).atZone(ZoneId.systemDefault()).toInstant())); 
  43.             entity.setCreateTime(new Date()); 
  44.  
  45.             // 商品詳情寫入Redis 
  46.             ValueOperations<String, String> setProduct = redisTemplate.opsForValue(); 
  47.             setProduct.set("product_" + productId, gson.toJson(entity)); 
  48.             // 寫入庫存 
  49.             if (buyOneFlag == 1) { 
  50.                 // 一個用戶只買一件商品 
  51.                 // 商品購買用戶Set 
  52.                 redisTemplate.opsForSet().add("product_buyers_" + productId, ""); 
  53.                 // 商品庫存 
  54.                 for (int j = 0; j < stock; j++) { 
  55.                     redisTemplate.opsForList().leftPush("product_one_stock_" + productId, "1"); 
  56.                 } 
  57.             } else { 
  58.                 // 用戶可買多個 
  59.                 redisTemplate.opsForValue().set("product_stock_" + productId, stock + ""); 
  60.             } 
  61.             list.add(entity); 
  62.             System.out.println(gson.toJson(entity)); 
  63.         } 
  64.         redisTemplate.opsForValue().set("seckill_plan_" + saleDate, gson.toJson(list)); 
  65.  
  66.         return DefaultResult.success(list); 
  67.     } 
  68.  
  69.     @GetMapping("/findSecKillPlanByDate"
  70.     @ResponseBody 
  71.     public DefaultResult<List<SecKillPlanEntity>> findSecKillPlanByDate(@RequestParam("saledate") String saleDate) { 
  72.         Gson gson = new Gson(); 
  73.         String planJson = redisTemplate.opsForValue().get("seckill_plan_" + saleDate); 
  74.         List<SecKillPlanEntity> list = gson.fromJson(planJson, new TypeToken<List<SecKillPlanEntity>>() { 
  75.         }.getType()); 
  76.         // 設置新的庫存 
  77.         for (SecKillPlanEntity entity : list) { 
  78.             if (entity.getBuyOneFlag() == 1) { 
  79.                 long newStock = redisTemplate.opsForList().size("product_one_stock_" + entity.getProductId()); 
  80.                 entity.setStock(newStock); 
  81.             } else { 
  82.                 long newStock = Long 
  83.                         .parseLong(redisTemplate.opsForValue().get("product_stock_" + entity.getProductId())); 
  84.                 entity.setStock(newStock); 
  85.             } 
  86.         } 
  87.         return DefaultResult.success(list); 
  88.     } 

 說明:

  • addSecKillPlan就是隨機生成10個售賣計劃,有僅售一件的,也有售多件的。并將相關數據壓入Redis。
  • seckill_plan_日期,代表某日的所有秒殺計劃,列表展示用。
  • product_商品ID,代表某商品信息,詳情頁使用。
  • product_one_stock_商品ID,代表僅售一件商品的庫存數,值是List,有多少庫存,就往里面push多少個“1”。
  • product_buyers_商品ID,代表僅售一件商品的購買者,已購買過的用戶不允許再買。
  • product_stock_商品ID,代表可售多件商品的庫存數,值是庫存數。

findSecKillPlanByDate,展示某日秒殺售賣計劃。庫存數從庫存相關的兩個KEY取。

LUA腳本

僅售一件buyone.lua:

  1. --商品庫存Key product_one_stock_XXX 
  2. local stockKey = KEYS[1] 
  3. --商品購買用戶記錄Key product_buyers_XXX 
  4. local buyersKey = KEYS[2] 
  5. --用戶ID 
  6. local uid = KEYS[3] 
  7. --校驗用戶是否已經購買 
  8. local result=redis.call("sadd" , buyersKey , uid ) 
  9. if(tonumber(result)==1) 
  10. then  
  11.     --沒有購買過,可以購買 
  12.     local stock=redis.call("lpop" , stockKey ) 
  13.     --除了nil和false,其他值都是真(包括0) 
  14.     if(stock) 
  15.     then  
  16.         --有庫存 
  17.         return 1 
  18.     else 
  19.         --沒有庫存 
  20.         return -1 
  21.     end 
  22. else 
  23.     --已經購買過 
  24.     return -3 
  25. end 

 可售多件buymore.lua:

  1. --商品Key 
  2. local key = KEYS[1] 
  3. --購買數 
  4. local val = ARGV[1] 
  5. --現有總庫存 
  6. local stock = redis.call("GET"key
  7. if (tonumber(stock)<=0)  
  8. then 
  9.     --沒有庫存 
  10.     return -1 
  11. else 
  12.     --獲取扣減后的總庫存=總庫存-購買數 
  13.     local decrstock=redis.call("DECRBY"key, val) 
  14.     if(tonumber(decrstock)>=0) 
  15.     then 
  16.         --扣減購買數后沒有超賣,返回現庫存 
  17.         return decrstock 
  18.     else 
  19.         --超賣了,把扣減的再加回去 
  20.         redis.call("INCRBY"key, val) 
  21.         return -2 
  22.     end 
  23. end 

說明:

1、僅售一件。先把購買者的ID用命令“sadd”進product_buyers_商品ID,如果返回1,代表此用戶之前沒有購買過,否則返回-3,已經購買過。

  • 在從product_one_stock_商品ID中lpop出數值,如果還有庫存,必會返回1,有庫存,否則就是nil,無庫存。

2.、可售多件。之前講過,不再描述。 將兩個lua文件,放在Spring Boot工程的resources目錄下。

售賣接口

  1. @RestController 
  2. public class OrderController { 
  3.  
  4.     @Resource 
  5.     private RedisTemplate<String, String> redisTemplate; 
  6.  
  7.     @GetMapping("/addOrder"
  8.     @ResponseBody 
  9.     public DefaultResult<Void> addOrder(@RequestParam("uid") long userId, @RequestParam("pid") long productId, 
  10.             @RequestParam("quantity"int quantity) { 
  11.         Gson gson = new Gson(); 
  12.         String productJson = redisTemplate.opsForValue().get("product_" + productId); 
  13.         SecKillPlanEntity entity = gson.fromJson(productJson, SecKillPlanEntity.class); 
  14.         //TODO 要校驗售賣計劃是否已提交,是否到了售賣時間 
  15.         long code = 0; 
  16.         if (entity.getBuyOneFlag() == 1) { 
  17.             // 用戶只買一件 
  18.             code = this.buyOne("product_one_stock_" + productId, "product_buyers_" + productId, userId); 
  19.         } else { 
  20.             // 用戶買多件 
  21.             code = this.buyMore("product_stock_" + productId, quantity); 
  22.         } 
  23.         DefaultResult<Void> result = DefaultResult.success(null); 
  24.         // 錯誤代碼的處理應該使用ENUM,本文就節省了 
  25.         if (code < 0) { 
  26.             result.setCode(code); 
  27.             if (code == -1) { 
  28.                 result.setMsg("沒有庫存"); 
  29.             } else if (code == -2) { 
  30.                 result.setMsg("庫存不足"); 
  31.             } else if (code == -3) { 
  32.                 result.setMsg("已經購買過"); 
  33.             } 
  34.         } 
  35.         return result; 
  36.     } 
  37.  
  38.     private Long buyOne(String stockKey, String buysKey, long userId) { 
  39.         DefaultRedisScript<Long> defaultRedisScript = new DefaultRedisScript<Long>(); 
  40.         defaultRedisScript.setResultType(Long.class); 
  41.         defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("buyone.lua"))); 
  42.         // "{pre}:" 
  43.         List<String> keys = Lists.newArrayList(stockKey, buysKey, userId + ""); 
  44.  
  45.         Long result = redisTemplate.execute(defaultRedisScript, keys, ""); 
  46.  
  47.         return result; 
  48.     } 
  49.  
  50.     private Long buyMore(String stockKey, int quantity) { 
  51.         DefaultRedisScript<Long> defaultRedisScript = new DefaultRedisScript<Long>(); 
  52.         defaultRedisScript.setResultType(Long.class); 
  53.         defaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("buymore.lua"))); 
  54.         List<String> keys = Lists.newArrayList(stockKey); 
  55.         Long result = redisTemplate.execute(defaultRedisScript, keys, quantity+""); 
  56.         return result; 
  57.     } 

 說明: 1、主要看buyOne、buyMore兩個私有方法,里面寫的是如何使用RedisTemplate執行lua腳本。

另外我看有資料說如果使用的是Redis集群,則會報錯,因為我沒有Redis的集群環境,所以也沒法測試,大家有環境的可以試一試。

2、addOrder有一些代碼為了節省時間,就寫得很low了,比如一些校驗沒有加,錯誤碼應該使用ENUM等。 測試用例:

  1. A用戶購買僅售一件商品1,成功。
  2. A用戶再購買僅售一件商品1,失敗。
  3. N用戶購買僅售一件商品1,庫存不足。
  4. A用戶購買可售多件商品2,成功。
  5. A用戶購買可售多件商品2,庫存不足。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2024-04-28 10:52:25

CentOS系統RHEL系統

2019-07-23 13:32:13

Java開發代碼

2020-08-04 07:47:59

代碼模板模式

2009-12-23 17:22:18

Linux系統rsyn

2020-04-01 17:31:03

Redis系統秒殺

2010-04-29 12:23:58

Oracle 獲取系統

2010-01-06 10:38:16

Linux安裝JDK

2010-04-12 09:36:29

Oacle merge

2020-09-01 07:47:32

Redis秒殺微信

2010-05-04 14:10:53

Oracle表

2010-05-10 17:00:53

Oracle死鎖進程

2021-09-22 15:36:31

勒索軟件攻擊數據泄露

2010-04-09 10:13:13

Oracle數據字典

2010-04-13 14:00:00

Oracle inse

2010-04-15 14:18:30

Oracle創建

2009-11-30 13:05:00

Suse防火墻

2010-05-18 18:19:40

MySQL修改表結構

2009-12-01 18:03:56

Linux版本

2010-04-27 10:25:28

Oracle Subs

2010-05-18 12:24:16

MySQL binlo
點贊
收藏

51CTO技術棧公眾號

欧美高清videos高潮hd| 色哟哟一区二区在线观看| 91免费看蜜桃| 国产精品变态另类虐交| 亚洲自拍电影| 欧美人与性动xxxx| 日韩黄色片在线| 久久国产精品高清一区二区三区| 蜜臀91精品一区二区三区 | 亚洲欧美日韩综合aⅴ视频| 国产v亚洲v天堂无码| 亚洲成熟少妇视频在线观看| 国产精品久久久久久久久久10秀| 精品国产网站在线观看| 国产嫩草在线观看| 大桥未久在线播放| 日本一区二区三区在线不卡| 91久久大香伊蕉在人线| www.国产一区二区| 国内自拍一区| 自拍偷拍亚洲在线| 国产性生活毛片| 国产激情久久| 一本到高清视频免费精品| 黄色一级视频播放| 国产有码在线| 91在线视频播放地址| 91老司机精品视频| 天天天天天天天干| 国产精品久久久久久久免费软件 | 粉嫩高清一区二区三区精品视频 | 波多野结衣乳巨码无在线观看| 国产午夜亚洲精品理论片色戒 | 粉嫩小泬无遮挡久久久久久| 久久精品72免费观看| 91高清免费在线观看| 国产黄在线免费观看| 少妇精品久久久一区二区三区 | 男人的天堂影院| 在线视频成人| 欧美日韩国产一区二区三区地区| 日韩毛片在线免费看| heyzo高清在线| 亚洲精品久久7777| 中文字幕免费在线不卡| 黄色在线网站| 久久久久高清精品| 久久久影院一区二区三区| 国产高清精品软件丝瓜软件| 黑人巨大精品欧美黑白配亚洲 | 网站一区二区| 91精品在线免费| 亚洲精品成人在线播放| 人人玩人人添人人澡欧美| 在线精品视频免费播放| av天堂永久资源网| 成人影院入口| 日韩欧美亚洲成人| 国产日韩成人内射视频| 日韩成人动漫| 欧美亚洲国产怡红院影院| 亚洲视频在线a| 精品日本视频| 在线不卡a资源高清| 中文字幕线观看| 99久热在线精品视频观看| 欧美日本韩国一区| 午夜免费福利网站| 日韩在线亚洲| 亚洲成av人乱码色午夜| 亚洲欧美日韩偷拍| 欧美一区自拍| 亚洲视频在线观看视频| 日韩免费成人av| 四虎国产精品免费观看| 久久综合伊人77777| 少妇影院在线观看| 99精品视频免费全部在线| 日本国产欧美一区二区三区| 无码人妻精品一区二区蜜桃色欲| 日本中文字幕不卡| 成人黄色免费网站在线观看| 国产黄色小视频在线观看| 成人免费精品视频| 欧美不卡1区2区3区| 97在线观看免费观看高清| 国产精品久久久久久久久搜平片 | 在线观看亚洲| 浅井舞香一区二区| 国产又大又长又粗| 成人黄色在线网站| 日韩电影免费观看高清完整| 爆操欧美美女| 狠狠躁18三区二区一区| 天天干天天综合| 成人资源在线| 中文字幕久精品免费视频| 日韩激情综合网| 国产精品久久久免费| 成人精品网站在线观看| 天天摸天天干天天操| 国产精品视频第一区| 屁屁影院ccyy国产第一页| 欧美成人h版| 欧美va亚洲va| 91香蕉国产视频| 91久久午夜| 国产精品美女呻吟| 日本黄色一区二区三区| 国产精品网友自拍| 青青草视频在线免费播放| 激情亚洲小说| 国产偷亚洲偷欧美偷精品| 手机在线免费看毛片| 久久一区亚洲| 国产精品一区二区av| 免费观看久久久久| 色哟哟亚洲精品| 深夜视频在线观看| 欧美日韩激情| 奇米四色中文综合久久| 亚洲精品无码专区| 亚洲欧美综合色| 久久综合伊人77777麻豆最新章节| 成人h动漫免费观看网站| 精品国产区一区二区三区在线观看 | www.com毛片| 伊人久久影院| 久久影院免费观看| 中文字幕在线日亚洲9| 99视频热这里只有精品免费| 好色先生视频污| 日韩免费在线电影| 中文字幕最新精品| 波多野结衣网站| 久久久五月婷婷| 国产极品尤物在线| 高清日韩欧美| 欧美黑人巨大xxx极品| av免费观看在线| 国产精品久久久久久亚洲伦| 黄色三级视频片| 欧美极品中文字幕| 日韩免费在线播放| 牛牛影视精品影视| 一本在线高清不卡dvd| 亚洲熟女乱综合一区二区三区| 精品成人一区| 国产精品一 二 三| 理论不卡电影大全神| 亚洲精品久久久久久久久久久| 久久久久久久久久久网| 国产盗摄女厕一区二区三区| 国产三级中文字幕| 国产在线不卡一区二区三区| 久热精品在线视频| 国产福利视频导航| 亚洲va在线va天堂| 插吧插吧综合网| 老**午夜毛片一区二区三区| 免费看成人片| 日韩经典一区| 日韩在线不卡视频| xxxx国产精品| 亚洲成精国产精品女| 手机在线看片日韩| 久久婷婷影院| 亚洲欧美电影在线观看| 亚洲伦理网站| 欧美黄色片视频| 青青青草网站免费视频在线观看| 在线视频你懂得一区| 日韩影视一区二区三区| 精品中文av资源站在线观看| 日韩一二区视频| 给我免费播放日韩视频| 日本91av在线播放| 在线免费观看黄色网址| 日韩精品一区二区三区在线观看| 国产午夜久久久| 久久久亚洲欧洲日产国码αv| 午夜激情在线观看视频| 亚洲深深色噜噜狠狠爱网站| 国产精品久久久久久久久婷婷 | 国产亚洲依依| 91精品国产综合久久久久久久| 久艹视频在线观看| 久久精品一区蜜桃臀影院| 五月激情婷婷在线| 樱桃成人精品视频在线播放| 日韩aⅴ视频一区二区三区| 日本亚洲欧洲无免费码在线| 久久久久久国产免费| 免费成人av电影| 欧美一区二区国产| 日韩精品1区2区| 国产精品国产三级国产普通话三级| 日韩高清在线一区二区| 久久久久久久高潮| 穿情趣内衣被c到高潮视频| 全球av集中精品导航福利| 国产一区二区在线免费视频| 啊啊啊久久久| 在线视频欧美日韩精品| 性欧美18一19性猛交| 色欧美日韩亚洲| 一区二区三区免费高清视频| 久久精品无码一区二区三区| 特黄特色免费视频| 麻豆国产精品一区二区三区 | 2019中文字幕在线电影免费| 中文字幕精品视频| 亚洲三级黄色片| 日韩精品一区在线| 91国产免费视频| 欧美日韩在线看| 免费一级黄色大片| 最新久久zyz资源站| 精品人伦一区二区三电影 | 一区二区三区四区免费| 国产91在线|亚洲| 亚洲视频一二三四| 视频在线在亚洲| 午夜免费福利小电影| 中文字幕人成人乱码| 亚洲国产欧美日韩| 亚洲理论电影| 精品高清视频| 激情视频极品美女日韩| 91欧美精品午夜性色福利在线| 精品成人免费一区二区在线播放| 2019中文字幕在线免费观看| 欧美另类tv| 欧美成人在线网站| 免费**毛片在线| 日韩中文字幕精品| 91福利在线视频| 在线观看亚洲区| 成人欧美亚洲| 亚洲丝袜一区在线| 色鬼7777久久| 亚洲精品网址在线观看| 五月天婷婷视频| 亚洲精品电影网在线观看| 国产精品女人久久久| 欧美日韩另类国产亚洲欧美一级| 波多野结衣毛片| 在线视频你懂得一区| 日韩黄色片网站| 欧美羞羞免费网站| 五月激情丁香网| 欧美日韩一级视频| 在线播放精品视频| 欧美日韩精品免费| 国产精品九九九九| 欧美一区二区三区播放老司机| 国产精品无码久久av| 欧美一区二区三区四区高清| 国产农村老头老太视频| 日韩久久精品一区| 欧美自拍偷拍第一页| 日韩av最新在线| 欧美日韩国产中文字幕在线| 国产一区二区三区精品久久久| 国产精品一区在线看| 自拍偷拍亚洲在线| 国产精品va在线观看视色| 精品视频9999| 欧美13videosex性极品| 国产精品jvid在线观看蜜臀| 久久电影天堂| 不卡一区二区三区视频| 九九热播视频在线精品6| 欧美日韩精品中文字幕一区二区| 欧洲杯足球赛直播| 亚洲国产精品成人va在线观看| 日本888xxxx| 美女视频黄久久| wwwxxx色| 91在线云播放| 最新中文字幕av| 亚洲另类在线一区| 99视频在线看| 精品视频在线免费观看| 国产av一区二区三区| 亚洲第一免费网站| 国产高清一区在线观看| 日韩视频免费看| 高清视频在线观看三级| 国产精品海角社区在线观看| 精品国产伦一区二区三区观看说明| 高清视频一区| 精品香蕉视频| 日本a在线天堂| 毛片一区二区| 久久6免费视频| av毛片久久久久**hd| 黄色一级片一级片| 性做久久久久久免费观看| 成人小视频在线播放| 日韩欧美一区在线观看| 蜜桃成人在线视频| 欧美另类极品videosbest最新版本| 中文字幕在线高清| 亚洲自拍偷拍一区| 成人三级视频| 黄色www网站| 国产精品一区二区在线观看不卡 | 国产免费www| 精品动漫一区二区三区在线观看 | 欧美成人网在线| 玛雅亚洲电影| 国产精品视频免费一区| 国产电影一区二区在线观看| 成人免费观看毛片| 国产91在线|亚洲| 国产精品白丝喷水在线观看| 欧美性猛交xxxxx水多| 午夜精品久久久久久久99| 色av吧综合网| 偷拍精品精品一区二区三区| 国产伦精品一区二区三区照片 | 久久综合九色综合欧美98| 欧美黄色免费看| 欧美日韩黄色一区二区| 黄色在线视频观看网站| 久久久视频在线| 日韩高清在线观看一区二区| 一本一道久久a久久综合精品| 久久国产精品毛片| 香港三日本8a三级少妇三级99| 亚洲欧美日韩系列| 伊人成人在线观看| 亚洲午夜精品视频| 欧美亚洲日本精品| 精品乱子伦一区二区三区| 午夜精品免费| 免费欧美一级片| 亚洲素人一区二区| 国产熟女一区二区三区五月婷| 中文字幕在线视频日韩| 国产精品99精品一区二区三区∴| 欧美xxxx黑人又粗又长密月 | 久久99偷拍| 中文字幕剧情在线观看一区| 蜜桃精品视频在线观看| 一级黄色片网址| 在线观看网站黄不卡| 成人在线免费电影| 国产精品pans私拍| 国产日产一区| 天天干天天干天天干天天干天天干| 国产欧美日本一区二区三区| 无码人妻熟妇av又粗又大| 亚洲人av在线影院| 国产经典一区| 异国色恋浪漫潭| 韩国一区二区在线观看| 欧美激情图片小说| 日韩欧美你懂的| 成人在线高清免费| 国产欧美日韩一区| 国产欧美在线| 亚洲国产av一区| 欧美色网站导航| 黄网站在线播放| 91沈先生播放一区二区| 欧美精品一卡| 中文在线观看免费视频| 欧美日韩亚洲一区二区| 国产中文字幕在线观看| 国产精品亚洲综合天堂夜夜| 国产精品久久久乱弄| 香蕉视频色在线观看| 亚洲国产综合色| 欧美日韩国产中文字幕在线| 国产精品白丝jk喷水视频一区| 日韩成人a**站| 午夜诱惑痒痒网| 午夜视频一区二区三区| 日本一二三区在线视频| 国产精品永久在线| 欧美三级不卡| 自拍偷拍视频亚洲| 欧美一区二区三区视频免费播放| av影视在线看| 手机成人在线| 国产高清一区日本| www.国产一区二区| 久久亚洲影音av资源网 | 精品免费国产一区二区三区四区| 9999在线视频| 亚洲国产欧美一区二区三区不卡| 国产一区二区h| 中文字幕免费在线观看视频| 日日噜噜噜夜夜爽亚洲精品| 卡一精品卡二卡三网站乱码| 亚洲第一狼人区| 欧美日韩国产在线看| 免费观看在线黄色网|