国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

實(shí)現(xiàn)秒殺功能設(shè)計(jì)

這篇具有很好參考價(jià)值的文章主要介紹了實(shí)現(xiàn)秒殺功能設(shè)計(jì)。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

頁面

  • 登錄頁面

    • 登錄成功后,跳轉(zhuǎn)商品列表
  • 商品列表頁

    • 加載商品信息
  • 商品詳情頁

    • 根據(jù)商品id查出商品信息
    • 返回VO(包括rmiaoshaStatus、emainSeconds)
    • 前端根據(jù)數(shù)據(jù)展示秒殺按鈕,點(diǎn)擊開始秒殺
  • 訂單詳情頁

秒殺頁面設(shè)置

后端返回秒殺狀態(tài)miaoshaStatus,前端根據(jù)秒殺狀態(tài),設(shè)置頁面:

  • 狀態(tài)碼 0, 未開始,倒計(jì)時(shí)
  • 狀態(tài)碼 1, 已開始,顯示秒殺按鈕
  • 狀態(tài)碼 2 ,已結(jié)束

剩余時(shí)間?remainSeconds

頁面加載時(shí),獲取remainSeconds 的值

  • 未開始,remainSeconds = 開始時(shí)間-當(dāng)前時(shí)間
    • 禁用秒殺按鈕,顯示倒計(jì)時(shí)
    • 設(shè)置定時(shí)器,回調(diào)函數(shù),一秒一次,修改remainSeconds 值
    • 直到 remainSeconds = 0
    • 清除設(shè)置定時(shí)器,則修改頁面,啟用秒殺按鈕
  • 已開始,remainSeconds = -1,啟用秒殺按鈕
  • 已結(jié)束 ,remainSeconds = 0,禁用秒殺按鈕

倒計(jì)時(shí)功能

<span th:if="${user eq null}"> 您還沒有登錄,請登陸后再操作<br/></span>

        	<input type="hidden" id="remainSeconds" th:value="${remainSeconds}" />
        	<span th:if="${miaoshaStatus eq 0}">秒殺倒計(jì)時(shí):<span id="countDown" th:text="${remainSeconds}"></span>秒</span>
        	<span th:if="${miaoshaStatus eq 1}">秒殺進(jìn)行中</span>
        	<span th:if="${miaoshaStatus eq 2}">秒殺已結(jié)束</span>

秒殺業(yè)務(wù)邏輯

點(diǎn)擊秒殺按鈕,傳遞商品ID, 秒殺商品,form表單提交到后端

  1. 判斷庫存

  2. 是否重復(fù)秒殺

    1. 查詢訂單信息。如存在,則表示已經(jīng)秒殺過了
  3. 減庫存、下訂單、寫入秒殺訂單(事務(wù))

    1. 傳入?yún)?shù)(user,goods)用戶秒殺商品
    2. 秒殺成功后,生成訂單信息,包含兩個(gè)
      1. 訂單詳細(xì)信息
      2. 秒殺訂單信息,包括user_id、order_id、goods_id,便于設(shè)置唯一索引(user_id、goods_id)
  4. 支付模塊

頁面優(yōu)化

  • 頁面緩存+URL緩存(Thymeleaf)
  • 對象緩存
  • 頁面靜態(tài)化,前后端分離
  • 靜態(tài)資源優(yōu)化
  • CDN優(yōu)化

緩存

頁面緩存

  • 從緩存中取html源代碼,非空返回(緩存命中)
  • 若緩存為空(緩存失效)
    • 手動渲染
      • thymeleafViewResolver.getTemplateEngine,模板引擎
      • WebContext,包含業(yè)務(wù)數(shù)據(jù)
    • 同時(shí)添加頁面緩存,頁面緩存有效期(比如60秒)
    • 返回html源代碼
  • 頁面緩存,一般有效期比較短,保證數(shù)據(jù)及時(shí)性
    @RequestMapping(value = "/to_list", produces = "text/html")
    @ResponseBody
    public String list(HttpServletRequest request, HttpServletResponse response, Model model, MiaoshaUser user) {
        model.addAttribute("user", user);
        // 取緩存
        String html = redisService.get(GoodsKey.getGoodsList, "", String.class);
        // 緩存非空,返回
        if (!StringUtils.isEmpty(html)) {
            return html;
        }
        // 緩存為空
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        // return "goods_list";
        model.addAttribute("goodsList", goodsList);
		// 業(yè)務(wù)數(shù)據(jù)
        WebContext ctx = new WebContext(request, response,
                request.getServletContext(), request.getLocale(), model.asMap());
        //手動渲染
        html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
        if (!StringUtils.isEmpty(html)) {
            redisService.set(GoodsKey.getGoodsList, "", html);
        }
        // 返回html
        return html;
    }
    }

URL緩存

  • 和頁面緩存類似,例如

    • 頁面緩存商品列表,無參數(shù)
    • URL緩存商品詳情,接口有ID參數(shù),ID不同商品詳情不同
  • 參數(shù)不同,頁面信息不同

  • 頁面緩存、url緩存有效期比較短,適用于頁面變化不大的場景(如商品列表,商品列表有分頁,只緩存前幾頁)

對象級緩存

  • 更細(xì)顆粒度的緩存,比如:

    • 登錄成功時(shí),用戶信息寫入緩存

      • 服務(wù)端通過token獲取
    • 秒殺成功生成訂單時(shí),訂單信息寫入緩存

      • 查詢是否已經(jīng)秒殺過時(shí),查緩存,不查數(shù)據(jù)庫,減少負(fù)載
  • 數(shù)據(jù)更新時(shí),也要處理緩存

    1. 先更新數(shù)據(jù)庫
    2. 再讓緩存失效(刪除、更新)

Cache Aside Pattern

  • 失效:應(yīng)用程序先從cache取數(shù)據(jù),沒有得到,則從數(shù)據(jù)庫中取數(shù)據(jù),成功后,放到緩存中。
  • 命中:應(yīng)用程序從cache中取數(shù)據(jù),取到后返回。
  • 更新:先把數(shù)據(jù)存到數(shù)據(jù)庫中,成功后,再讓緩存失效。
    • 試想,兩個(gè)并發(fā)操作,一個(gè)是更新操作,另一個(gè)是查詢操作
    • 更新操作刪除緩存后,查詢操作沒有命中緩存,先把老數(shù)據(jù)讀出來后放到緩存中,然后更新操作更新了數(shù)據(jù)庫。
    • 于是,在緩存中的數(shù)據(jù)還是老的數(shù)據(jù),導(dǎo)致緩存中的數(shù)據(jù)是臟的。

前后端分離

  1. 常用技術(shù):AngularJS、Vue.js、React
  2. 優(yōu)點(diǎn):利用瀏覽器的緩存

前后端分離

  • 靜態(tài)數(shù)據(jù)緩存,動態(tài)數(shù)據(jù)調(diào)接口
  • 頁面靜態(tài)化,html、css、js、image緩存到瀏覽器端
  • 動態(tài)數(shù)據(jù)通過服務(wù)端獲取
  • 不需要使用頁面緩存和URL緩存了,瀏覽器端已經(jīng)進(jìn)行了緩存,再用頁面緩存和URL緩存沒有什么意義
  • 對象緩存可以繼續(xù)使用
  • 前后端分離后,不經(jīng)過服務(wù)端,客戶端直接跳轉(zhuǎn)到商品詳情頁面,然后商品詳情頁面Ajax請求動態(tài)數(shù)據(jù)

商品詳情靜態(tài)化、訂單詳情靜態(tài)化

  • 使用jquery模擬,不使用thymeleaf

  • 商品詳情使用原生html,頁面跳轉(zhuǎn)時(shí),直接跳轉(zhuǎn)到html頁面

  • 然后Ajax請求動態(tài)數(shù)據(jù),jquery填充頁面

  • 同時(shí)根據(jù)miaoshaStatus、remainSeconds,修改頁面

秒殺接口前后端分離

后端僅返回給前端所需的數(shù)據(jù),不再渲染 HTML 頁面,不再控制前端的效果。

前端得到數(shù)據(jù),自己渲染。

前端和后端只關(guān)注于自己的邏輯判斷和控制。后端僅需提供給前端 API 即可。

  • 不需要表單提交
  • 直接按鈕?onclick?,ajax請求數(shù)據(jù)
  • post請求

靜態(tài)文件配置

  • 配置靜態(tài)文件路徑
  • 不配置,304(前后端仍然交互了一次)
  • 配置后,200(靜態(tài)文件直接從瀏覽器取緩存,不需要訪問服務(wù)器,減少交互)
  • 配置后,減少前后端交互
  • Cache-Control:max-age=3600,緩存時(shí)間

靜態(tài)資源優(yōu)化

  • JS/CSS壓縮,減少流量

  • 多個(gè)JS/CSS組合,減少連接數(shù)

  • CDN就近訪問

tengine

  • 組合多個(gè)CSS、JS文件的訪問請求變成一個(gè)清求
  • 自動去除空白字符和注釋從而減小頁面的體積(webpack工具,打包)

CDN

全稱是Content Delivery Network,**內(nèi)容分發(fā)網(wǎng)絡(luò)。**根據(jù)用戶位置等,訪問最近的鏡像

  • 可以將網(wǎng)站的靜態(tài)資源(如圖片、CSS、JavaScript 等文件)緩存到全球各地的服務(wù)器上
  • 當(dāng)用戶請求這些資源時(shí),可以從離用戶最近的服務(wù)器上獲取資源,從而提高資源的訪問速度和用戶的訪問體驗(yàn)

CDN 的主要作用是:

  • 提高網(wǎng)站的訪問速度
  • 降低帶寬成本
  • 提高可用性

同樣,在高并發(fā)場景下,CDN 可以發(fā)揮重要的作用。

由于高并發(fā)場景下會有大量的用戶同時(shí)訪問網(wǎng)站,如果所有的請求都直接訪問源站,就會導(dǎo)致源站的帶寬和服務(wù)器資源受到過大的壓力,從而導(dǎo)致網(wǎng)站的訪問速度變慢或者出現(xiàn)宕機(jī)等問題。

因此,在高并發(fā)場景下,使用 CDN 可以將流量分散到全球各地的服務(wù)器上,從而減輕源站的壓力,提高網(wǎng)站的訪問速度和可用性。

接口優(yōu)化

并發(fā)大問題,瓶頸在于數(shù)據(jù)庫,思路:減少數(shù)據(jù)庫訪問。解決:

  • 各種緩存,減少數(shù)據(jù)庫負(fù)載

  • 接口優(yōu)化:減少數(shù)據(jù)庫訪問

  • 數(shù)據(jù)庫分庫分表(mycat中間件)

方案

  1. Redis預(yù)減庫存減少數(shù)據(jù)庫訪問
  2. 內(nèi)存標(biāo)記減少Redis訪問
  3. 請求先入隊(duì)緩沖,異步下單,增強(qiáng)用戶體驗(yàn)
  4. Nginx水平擴(kuò)展

思路

  1. 系統(tǒng)初始化,把商品庫存數(shù)量加載到Redis
  2. 收到請求,Redis預(yù)減庫存,庫存不足,直接返回,否則進(jìn)入3
  3. 請求入隊(duì),立即返回排隊(duì)中
  4. 請求出隊(duì),生成訂單,減少庫存
  5. 客戶端輪詢,是否秒殺成功

加載庫存

  • 實(shí)現(xiàn)?InitializingBean接口,覆寫afterPropertiesSet()方法
  • 系統(tǒng)初始化調(diào)用此方法,加載庫存、內(nèi)存標(biāo)記到緩存

內(nèi)存標(biāo)記

  • 減少redis負(fù)載
  • 訪問秒殺接口時(shí),先訪問redis內(nèi)存標(biāo)記,若為true,則直接返回,商品賣完啦
  • 設(shè)置redis內(nèi)存標(biāo)記
  • 初始化為?false,放到緩存中
  • redis庫存小于0時(shí),設(shè)置為true

入隊(duì)緩沖

  • 庫存足夠,沒有秒殺過,進(jìn)入下個(gè)步驟,入隊(duì)
  • 用戶,商品id(用戶秒殺商品)作為消息,發(fā)送消息到隊(duì)列
  • 消息接受者監(jiān)聽接收消息,異步下單
    1. 判斷數(shù)據(jù)庫庫存(是否庫存大于0)
    2. 判斷是否已經(jīng)秒殺到了(是否存在秒殺訂單)
    3. 減庫存(成功才下單)
    4. 下訂單
    5. 寫入秒殺訂單(唯一索引)

輪詢

  • 秒殺成功后,返回排隊(duì)中,前端開始輪詢(類比12306買票,不馬上返回是否搶票成功,顯示正在排隊(duì)中)

  • 先判斷是否存在訂單 order,存在,表示秒殺成功,返回 orderId

  • 若order==null,判斷緩存標(biāo)記

  • 緩存標(biāo)記 == false,表示沒有賣完,繼續(xù)輪詢,返回 0

  • 緩存標(biāo)記 == true,表示賣完啦,返回 -1

    • orderId:成功

    • 0: 排隊(duì)中

    • -1:秒殺失敗

      • 設(shè)置一個(gè)緩存標(biāo)記(false)
      • 減庫存時(shí),若庫存為0時(shí),設(shè)置緩存表示已經(jīng)秒殺完畢,修改緩存標(biāo)記(true)
      • 輪詢時(shí),若緩存標(biāo)記為true,則賣完啦,返回秒殺失敗 -1

RabbitMQ

  • 同步直接調(diào)用轉(zhuǎn)換成異步間接推送,把瞬時(shí)并發(fā)的大量請求平推出去,削弱峰值

  • 秒殺請求過來時(shí),先入隊(duì)緩沖瞬時(shí)流量,直接返回客戶端正在排隊(duì)中

  • 然后出隊(duì),生成訂單,修改庫存

  • 同時(shí)客戶端定時(shí)輪詢,定時(shí)查詢是否秒殺成功

  • 出隊(duì)和輪詢同時(shí)進(jìn)行

配置

  • 創(chuàng)建隊(duì)列
  • 創(chuàng)建交換機(jī)
  • 隊(duì)列和交換機(jī)綁定(routingKey)

創(chuàng)建消息發(fā)送者

  • 發(fā)送消息到隊(duì)列或交換機(jī)

創(chuàng)建消息接受者

  • @RabbitListener(queues=隊(duì)列名字/交換機(jī)名字)
  • 監(jiān)聽隊(duì)列或交換機(jī),接受消息

消息傳播消息->交換機(jī)->隊(duì)列

Exchange

交換機(jī)和隊(duì)列綁定(Key、無key、key-value)

發(fā)送消息到交換機(jī),匹配成功,隊(duì)列才會收到消息

四種交換機(jī)模式:

  • Direct Exchange:按照routingkey分發(fā)到指定隊(duì)列
  • Topic Exchange,多關(guān)鍵字匹配,發(fā)給多個(gè)隊(duì)列,交換機(jī)和隊(duì)列通過routingkey綁定
    • 發(fā)送消息到交換機(jī)時(shí),交換機(jī)key和隊(duì)列key若匹配,則消息發(fā)送到隊(duì)列
  • Fanout Exchange,廣播模式,無routingkey的概念,和交換機(jī)綁定的隊(duì)列都能獲得消息
  • Headers Exchange ,交換機(jī)和隊(duì)列通過key-value綁定
    • 發(fā)送消息時(shí),key-value匹配,隊(duì)列全部滿足或者滿足任何一個(gè),隊(duì)列才會收到消息

安全優(yōu)化

方案

  1. 秒殺接口地址隱藏(防止明文暴露,提前搶票、黃牛機(jī)器人搶票)
  2. 數(shù)學(xué)公式驗(yàn)證碼(保護(hù)獲取秒殺地址的接口,分散請求
  3. 接口限流防刷(保護(hù),防止惡意刷接口)

前端頁面限制,防君子不防小人,主要防止用戶出錯(cuò)

Http明文,url可以提前拿到,防止惡意刷接口

思路

點(diǎn)擊秒殺之前,先輸入驗(yàn)證碼,分散用戶的請求

  1. 添加生成驗(yàn)證碼的接口
  2. 在獲取秒殺路徑的時(shí)候,驗(yàn)證驗(yàn)證碼
  3. ScriptEngine使用

秒殺接口地址隱藏

思路:秒殺開始之前,先去請求接口獲取秒殺地址

  1. 秒殺接口改造,帶上PathVariable參數(shù)
  2. 添加生成地址的接口
  3. 秒殺收到請求,先驗(yàn)證PathVariable

獲取秒殺地址的接口也可能暴露,通過驗(yàn)證碼驗(yàn)證

邏輯:請求生成地址接口、返回path、秒殺接口拼接path(真正接口)、訪問真正秒殺接口、先驗(yàn)證path

隱藏秒殺地址可以有很多種實(shí)現(xiàn)方式,上述只是一種實(shí)現(xiàn)方式,還可以:

  • 接口可以返回302,跳轉(zhuǎn)到新的頁面,新的頁面才是真正的秒殺頁面
    • 接口可以返回一個(gè)頁面的url,讓瀏覽器跳轉(zhuǎn)到這個(gè)新的url頁面,新的頁面才是真正的秒殺頁面
    • 活動開始前和活動開始后是兩個(gè)完全不同的頁面,這樣就可以防止提前抓取網(wǎng)頁了
  • 為了防止惡意用戶提前抓取網(wǎng)頁,對網(wǎng)頁進(jìn)行分析,然后寫出刷接口的機(jī)器人工具。
  • 活動開始之前,惡意用戶就算分析網(wǎng)頁寫了刷接口的程序也沒用,因?yàn)槟莻€(gè)頁面并不是真正的秒殺頁面。

數(shù)學(xué)公式驗(yàn)證碼

思路:點(diǎn)擊秒殺之前,先輸入驗(yàn)證碼,分散用戶的請求,防止機(jī)器人

  1. 添加生成驗(yàn)證碼的接口(答案寫入緩存)
  2. 在點(diǎn)擊秒殺獲取路徑的時(shí)候,去驗(yàn)證驗(yàn)證碼(防止暴露獲取動態(tài)路徑 path 的地址)
  3. ScriptEngine使用

邏輯:

  1. 頁面生成驗(yàn)證碼,同時(shí)驗(yàn)證碼答案寫入緩存(key+uerId+goodsId,有效時(shí)間)
  2. 用戶輸入驗(yàn)證碼
  3. 點(diǎn)擊按鈕,訪問生成地址接口(獲取秒殺路徑)
  4. 驗(yàn)證,用戶輸入和緩存驗(yàn)證
  5. 驗(yàn)證成功后刪掉緩存(防止再次使用)
  6. 然后生成path(驗(yàn)證成功后,才生成path),返回
  7. 訪問真正秒殺接口

使用驗(yàn)證碼目的

  1. 防止機(jī)器人,刷票軟件;
  2. 延緩請求,錯(cuò)峰請求秒殺接口;
  3. 保護(hù)作用,驗(yàn)證碼不對,直接返回錯(cuò)誤代碼。
  4. 防止 獲取秒殺地址接口 暴露

接口限流防刷

攔截器和緩存實(shí)現(xiàn),設(shè)置緩存,有效期內(nèi)限制訪問次數(shù);過期失效,重新限制

  • 首先自定義方法注解,放到秒殺接口的方法上
  • 接著注冊攔截器并覆寫方法
  • 服務(wù)器接到請求時(shí),攔截器會先攔截請求,并獲得注解
  • 然后在覆寫的方法中進(jìn)行邏輯判斷

邏輯:

  • 查詢訪問次數(shù)(查詢緩存)
  • 為null,設(shè)置緩存
  • 不為null
    • 小于等于限制次數(shù),+1
    • 大于限制次數(shù),返回失敗

攔截器寫通用方法

  • 自定義注解,接口加上注解

  • // 5秒鐘,最大訪問次數(shù)限制5次,需要登錄
    @AccessLimit(seconds=5, maxCount=5, needLogin=true)
  • @Retention(RUNTIME)
    @Target(METHOD)
    public @interface AccessLimit {
       int seconds();
       int maxCount();
       boolean needLogin() default true;
    }
  • 自定義攔截器,獲取注解信息,進(jìn)行限制

  • 攔截器在參數(shù)解析器前執(zhí)行,都需要在WebMvcConfigurer中注冊

  • ThreadLocal,存放數(shù)據(jù)到當(dāng)前線程,每個(gè)線程單獨(dú)一份

常見的限流算法

  1. 網(wǎng)關(guān)上做限流。比如在nginx上寫lua腳本來實(shí)現(xiàn)
  2. 在應(yīng)用上做單機(jī)限流。使用諸如基于Guava的RateLimiter令牌桶的方式
  3. 在應(yīng)用上做分布式限流。比如redisson提供了個(gè)基于redis的RateLimiter
  4. 如果是SpringCloud項(xiàng)目,可用的就更多了,比如SpringCloud?Gateway,Sentinel等等。

服務(wù)端優(yōu)化

Tomcat

內(nèi)存優(yōu)化

  • -Xms2048M 最小內(nèi)存,-Xmx2048M 最大內(nèi)存都設(shè)為 2G;
  • -XX:+HeapDumpOnOutOfMemoryError;
  • -XX:HeapDumpPath=$CATALINA_HOME/logs/heap.dump";
  • 內(nèi)存溢出時(shí),將內(nèi)存映像放到$CATALINA_HOME/logs/heap.dump 文件,方便定位問題。

并發(fā)優(yōu)化

  • maxConnections:服務(wù)器支持最大并發(fā)連接數(shù)量
  • acceptCount:當(dāng)服務(wù)器的并發(fā)連接數(shù)都在使用時(shí),會有一個(gè)隊(duì)列來存放新來的請求,隊(duì)列滿時(shí)接收到的任何請求都將被拒絕
  • maxThreads:最大工作線程數(shù)
  • minSpareThreads:最小空閑的工作線程
  • autoDeploy: 指 Tomcat 在運(yùn)行時(shí)是否應(yīng)該定期檢查新的或更新的 web 應(yīng)用程序,禁用提高性能。
  • reloadable:監(jiān)視 WEB-INF/classes/ and /WEB-INF/lib 中的類,并在檢測到更改時(shí)自動重新加載 web 應(yīng)用程序,可以設(shè)置為 true/false。

APR 優(yōu)化

Tomcat 的 BIO、NIO、APR 模式,默認(rèn) NIO 模式

  • APR:Apache HTTP 服務(wù)器的支持庫。可以簡單地理解為,Tomcat 將以 JNI 的形式調(diào)用 Apache HTTP 服務(wù)器的核心動態(tài)鏈接庫處理文件讀取或網(wǎng)絡(luò)傳輸操作,從而大大地提高 Tomcat 對靜態(tài)文件的處理性能。Tomcat APR 也是在 Tomcat 上運(yùn)行高并發(fā)應(yīng)用的首選模式。

nginx

實(shí)現(xiàn)秒殺功能設(shè)計(jì),狀態(tài)模式

反向代理

  • 反向代理到集群(server_pool_miaosha;),配置多臺服務(wù)器(localhost、otherserver等)

負(fù)載均衡文章來源地址http://www.zghlxwxcb.cn/news/detail-815642.html

  • 服務(wù)器按照權(quán)重分配請求數(shù)量,如上圖,weight=1,均分請求
  • max_fails=2,最大失敗次數(shù),判斷服務(wù)器是否存活,超過次數(shù),認(rèn)為服務(wù)器掛掉,不會分配請求了

到了這里,關(guān)于實(shí)現(xiàn)秒殺功能設(shè)計(jì)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包