<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      openresty IP限流

      1、針對大流量大并發網絡請求下,為了保證服務的正常運行,不得不針對性采取限流的方式來解決大流量帶來的服務器的壓力。

      2、在目前項目中對于接入了不同的平臺,所以需要針對具體的平臺做相對應的限流,或者針對所有的平臺做ip白名單的限制,針對ip限流。

      3、以下代碼是通過平臺上報的ip對平臺做相對應的限流,主要使用的是redis+openresty來做處理;涉及代碼只做過基本的壓測,未投入實際生產

      相關代碼記錄如下:

        1 --
        2 -- Created by IntelliJ IDEA.
        3 -- User: tiemeng
        4 -- Date: 2019/3/3
        5 -- Time: 10:00
        6 -- To change this template use File | Settings | File Templates.
        7 --
        8 ngx.header.content_type = "text/html;charset=utf8"
        9 
       10 
       11 -- redis配置
       12 local redisConfig = {
       13     redis_a = {
       14         host = '127.0.0.1',
       15         port = 6379,
       16         pass = '',
       17         timeout = 200,
       18         database = 0,
       19     }
       20 }
       21 
       22 local limitCount = 5
       23 
       24 local time = 10000 -- 時間,單位為毫秒
       25 
       26 --[[
       27       獲取請求IP
       28  ]]
       29 local function getIp()
       30     local headers = ngx.req.get_headers()
       31     local ip = headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr or "0.0.0.0"
       32     return ip
       33 end
       34 
       35 
       36 
       37 --[[
       38         連接redis
       39  ]]
       40 local function redisConn()
       41     local redis = require('resty.redis_factory')(redisConfig)
       42     local ok, redis_a = redis:spawn('redis_a')
       43     if ok ~= nil then
       44         return redis, redis_a
       45     end
       46 
       47     return redis, nil
       48 end
       49 
       50 
       51 --[[
       52     通過ip獲取平臺名稱
       53  ]]
       54 local function getPlatformNameByIp(ip)
       55     local handle, redis = redisConn()
       56     if redis == nil then
       57         return nil
       58     end
       59     local platform = redis:hget('iplist', ip)
       60     handle.destruct()
       61     if platform ~= ngx.null then
       62         return platform
       63     end
       64     ngx.log(ngx.ERR, "ip:" .. ip .. ",未在白名單中,禁止訪問")
       65     return nil
       66 end
       67 
       68 local function forbid2()
       69     local ip = getIp();
       70     -- 2、獲取當前ip是那個平臺
       71     local platfromName = getPlatformNameByIp(ip)
       72     if platfromName == nil then
       73         return false
       74     end
       75     -- 3、獲取當前平臺的總數
       76     local key = 'forbid_' .. platfromName
       77     local handle, redis = redisConn()
       78     if redis == nil then
       79         return nil
       80     end
       81     local curTime = ngx.now() * 1000
       82     local ok, err = redis:eval([[
       83         local len = redis.call('llen',KEYS[1])
       84         if len < 10 then
       85             redis.call('rpush',KEYS[1],ARGV[2])
       86             return true
       87         end
       88         local times = redis.call('lrange',KEYS[1],0,0)
       89         local timeSum = tonumber(times[1])+tonumber(ARGV[1])
       90         if timeSum > tonumber(ARGV[2]) then
       91             return false
       92         end
       93         redis.call('lpop',KEYS[1])
       94         redis.call('rpush',KEYS[1],ARGV[2])
       95         return true
       96     ]], 1, key, time, curTime)
       97     handle.destruct()
       98     return ok
       99 end
      100 
      101 
      102 
      103 if forbid2() ~= 1 then
      104     ngx.exit(403)
      105 end

      測試中出現的問題:

      起初是使用以下代碼實現的,從代碼表面看是沒有任何問題,但是在壓力測試下并發數達到50的時候就會出現限流失效;出現失效的主要原因是,在redis中list的操作并不是所謂的原子操作,所以通過翻閱相關資料了解到,可以在redis中嵌入相關的lua腳本,可以達到原子的操作;所以在一開始的代碼82-96行使用redis的eval函數來調用lua的腳本,已達到原子操作的要求;修改后經過壓測后達到相對用的效果

       1 local function isForbid()
       2     local ip = getIp();
       3     -- 2、獲取當前ip是那個平臺
       4     local platfromName = getPlatformNameByIp(ip)
       5     if platfromName == nil then
       6         return false
       7     end
       8     -- 3、獲取當前平臺的總數
       9     local key = 'forbid_' .. platfromName
      10     local handle, redis = redisConn()
      11     if redis == nil then
      12         return nil
      13     end
      14     -- 4、校驗是否超過限制
      15     local len = redis:llen(key)
      16 
      17     if len < limitCount then
      18         redis:rpush(key, ngx.now() * 1000)
      19         handle.destruct()
      20         return true
      21     end
      22     local times = redis:lrange(key, 0, 0)
      23     if times == ngx.null then
      24         return false
      25     end
      26 
      27     if tonumber(times[1]) + time >= ngx.now() * 1000 then
      28         ngx.log(ngx.ERR, "forbid_platform :" .. platfromName)
      29         return false
      30     end
      31     os.execute("sleep " .. 1)
      32     redis:lpop(key)
      33     redis:rpush(key, ngx.now() * 1000)
      34     handle.destruct()
      35     return true
      36 end

       

      nginx部分相關配置:

      http {
          include       mime.types;
          default_type  application/octet-stream;
          lua_package_path '/websys/nginx/lua/?.lua;/websys/lualib/?/init.lua;;';
      
          #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
          #                  '$status $body_bytes_sent "$http_referer" '
          #                  '"$http_user_agent" "$http_x_forwarded_for"';
      
          #access_log  logs/access.log  main;
      
          sendfile        on;
          #tcp_nopush     on;
      
          #keepalive_timeout  0;
          #keepalive_timeout  65;
          #    resolver 127.0.0.1 192.168.1.1 8.8.8.8;
          #gzip  on;
          access_by_lua_file lua/access.lua;

      此限流主要在openresty的access層做了限制,主要引入方式為上方紅色字體

       

      起初想的是通過redis的incr來實現針對ip做限流,但是其中會有鍵失效的時間問題;如果使用incr做相對應的操作,如果10秒鐘請求量為50的話,是沒法保證時間的連續性;所以最后采用了通過list來保證了時間的連續性;

       

      本文主要記錄相關的問題及知識點,如簡述和實現方式有問題歡迎吐槽

      posted on 2019-03-07 09:48  鐵猛  閱讀(1152)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 精品 无码 国产观看| 免费A级毛片无码A∨蜜芽试看| 蜜臀久久精品亚洲一区| 国产一区二区不卡在线| 国产av普通话对白国语| 亚洲一区二区无码影院| 成人乱码一区二区三区四区| 99久久免费只有精品国产| 高唐县| 内射人妻视频国内| 四虎永久精品免费视频| 亚洲精品乱码久久久久久自慰| 国产精品九九九一区二区| 日本中文字幕有码在线视频| 国产精品视频一区二区噜| 狠狠色噜噜狠狠亚洲AV| 97欧美精品系列一区二区| 天堂在线精品亚洲综合网| 中国女人内谢69xxxx| 国产亚洲精品久久久久久无亚洲 | 久久国产精品不只是精品| 亚洲乱码精品中文字幕| 国产欧美日韩高清在线不卡| 亚洲欧美中文日韩在线v日本| av亚洲一区二区在线| 肉大捧一进一出免费视频| 亚洲精品美女一区二区| 最新午夜男女福利片视频| 男女激情一区二区三区| 亚洲香蕉av一区二区蜜桃| 九九热在线免费视频精品| 夜夜爱夜鲁夜鲁很鲁| 日韩丝袜欧美人妻制服| 日韩精品中文字幕一线不卡| 伊人久久久大香线蕉综合直播| 激情动态图亚洲区域激情| 欧美嫩交一区二区三区| 亚洲人成电影在线天堂色| 人妻夜夜爽天天爽一区| 亚洲国产精品一二三四五| 亚洲高清日韩专区精品|