電商高并發(fā)秒殺6 防刷限流

概述

本章介紹了常見的黃牛入侵手段舵匾,以及如何使用對(duì)應(yīng)的防刷手段防止黃牛入侵。同時(shí)業(yè)務(wù)的發(fā)展預(yù)估永遠(yuǎn)可能高于系統(tǒng)可承載的能力,因此介紹了使用多種限流技術(shù)保證系統(tǒng)的穩(wěn)定门怪。

1. 驗(yàn)證碼

  • 包裝秒殺令牌設(shè)置,需要驗(yàn)證碼來錯(cuò)峰锅纺,分散用戶的請(qǐng)求掷空;
  • 數(shù)學(xué)公式驗(yàn)證碼生成器;
1.1 代碼實(shí)現(xiàn)
    @RequestMapping(value = "/generateverifycode", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public void generateverifycode(HttpServletResponse response) throws BusinessException, IOException {
        String token = httpServletRequest.getParameterMap().get("token")[0];
        if (StringUtils.isEmpty(token)) {
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, "用戶還未登陸囤锉,不能生成驗(yàn)證碼");
        }
        UserModel userModel = (UserModel) redisTemplate.opsForValue().get(token);
        if (userModel == null) {
            throw new BusinessException(EmBusinessError.USER_NOT_LOGIN, "用戶還未登陸坦弟,不能生成驗(yàn)證碼");
        }

        Map<String, Object> map = CodeUtil.generateCodeAndPic();

        redisTemplate.opsForValue().set("verify_code_" + userModel.getId(), map.get("code"));
        System.out.println("驗(yàn)證碼為" + map.get("code"));
        redisTemplate.expire("verify_code_" + userModel.getId(), 10, TimeUnit.MINUTES);

        ImageIO.write((RenderedImage) map.get("codePic"), "jpeg", response.getOutputStream());


    }
Map<String, Object> map = CodeUtil.generateCodeAndPic();
1.生成驗(yàn)證碼字符串與之對(duì)應(yīng)的圖片
2.將字符串返回給

2. 限流

流量遠(yuǎn)比你想象的要多;
系統(tǒng)能運(yùn)行或者總比掛了要好官地;
寧愿讓少數(shù)人能用酿傍,也不要讓所有人不能用;

限流方案
2.1 限并發(fā)

例如同一時(shí)間固定訪問接口的線程數(shù)驱入,利用全局計(jì)數(shù)器赤炒,當(dāng)ServerController被喚醒某一個(gè)需要限制的接口瓮具,那我們就將下單接口Controller的入口處加一個(gè)全局計(jì)數(shù)器务蝠,并且要支持并發(fā)下的減和加的操作块蚌,當(dāng)controller在入口的時(shí)候尔艇,將計(jì)數(shù)器減1睛藻,判斷一下計(jì)數(shù)器的數(shù)字是否大于0剧蚣,在controller出口的時(shí)候?qū)⒂?jì)數(shù)器加1意敛,就可以做到同一時(shí)間內(nèi)對(duì)計(jì)數(shù)器的操作是固定的眷细,一旦減到0或者變?yōu)樨?fù)數(shù)巡通,就要處理對(duì)應(yīng)的問題尘执;

2.2 令牌桶算法

假設(shè)有一個(gè)桶內(nèi)放了許多令牌舍哄,假設(shè)用戶要請(qǐng)求對(duì)應(yīng)的實(shí)體,需要先獲取一個(gè)令牌正卧;初始狀態(tài)下令牌桶內(nèi)有10個(gè)令牌蠢熄,客戶端獲取一個(gè)令牌,令牌數(shù)減一炉旷;設(shè)置一個(gè)定時(shí)器签孔,每秒會(huì)往令牌桶內(nèi)放置10個(gè)令牌,這樣就可以做到客戶端一秒可以訪問10個(gè)對(duì)應(yīng)的流量進(jìn)去窘行,下一秒就是下一個(gè)10個(gè)饥追;可以限定某一時(shí)刻的最大值,應(yīng)對(duì)突發(fā)流量罐盔;

2.3 漏桶算法原理

有一個(gè)桶但绕,初始是滿的,有10滴水惶看,每秒流出一滴水捏顺;客戶端請(qǐng)求的時(shí)候是往客戶端里面加一滴水;

如果桶是滿的這一滴水就加不進(jìn)去纬黎;漏桶算法沒有辦法應(yīng)對(duì)突發(fā)流量幅骄,其目的是用來平滑網(wǎng)絡(luò)流量,固定的速度對(duì)應(yīng)的操作本今。

接口維度
總維度
假設(shè)系統(tǒng)有10個(gè)接口拆座,分別是商品詳情,下單列表冠息、用戶登錄注冊(cè)等挪凑,假設(shè)每個(gè)接口都可以承載5tps的流量,對(duì)應(yīng)10個(gè)接口就是50tps,那我們的系統(tǒng)真的能承載50tps嗎逛艰?躏碳,一般要比接口維度的總和要小20%左右;

限流范圍

集群限流:依賴Redis或其它中間件技術(shù)做統(tǒng)一計(jì)數(shù)器散怖,往往會(huì)產(chǎn)生性能瓶頸唐断;
單機(jī)限流:負(fù)載均衡的前提下單機(jī)平均限流效果更好;

限流代碼實(shí)現(xiàn)

    private RateLimiter orderCreateRateLimiter;

    @PostConstruct
    public void init() {
        executorService = new ThreadPoolExecutor(20, 20,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), new ThreadPoolExecutor.AbortPolicy());
        orderCreateRateLimiter = RateLimiter.create(300);
    }

//封裝下單請(qǐng)求
    @RequestMapping(value = "/createorder", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
    @ResponseBody
    public CommonReturnType createOrder(@RequestParam(name = "itemId") Integer itemId,
                                        @RequestParam(name = "amount") Integer amount,
                                        @RequestParam(name = "promoId", required = false) Integer promoId,
                                        @RequestParam(name = "promoToken", required = false) String promoToken) throws BusinessException {

    if (orderCreateRateLimiter.acquire() < 0) {
            throw new BusinessException(EmBusinessError.RATELIMIT);
        }
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末杭抠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子恳啥,更是在濱河造成了極大的恐慌偏灿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钝的,死亡現(xiàn)場(chǎng)離奇詭異翁垂,居然都是意外死亡铆遭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門沿猜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來枚荣,“玉大人,你說我怎么就攤上這事啼肩¢献保” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵祈坠,是天一觀的道長害碾。 經(jīng)常有香客問我,道長赦拘,這世上最難降的妖魔是什么慌随? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮躺同,結(jié)果婚禮上阁猜,老公的妹妹穿的比我還像新娘。我一直安慰自己蹋艺,他們只是感情好剃袍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著车海,像睡著了一般笛园。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侍芝,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天研铆,我揣著相機(jī)與錄音,去河邊找鬼州叠。 笑死棵红,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的咧栗。 我是一名探鬼主播逆甜,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼致板!你這毒婦竟也來了交煞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤斟或,失蹤者是張志新(化名)和其女友劉穎素征,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡御毅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年根欧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端蛆。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凤粗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出今豆,到底是詐尸還是另有隱情嫌拣,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布晚凿,位于F島的核電站亭罪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏歼秽。R本人自食惡果不足惜应役,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望燥筷。 院中可真熱鬧箩祥,春花似錦、人聲如沸肆氓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谢揪。三九已至蕉陋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間拨扶,已是汗流浹背凳鬓。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留患民,地道東北人缩举。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像匹颤,于是被迫代替她去往敵國和親仅孩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容