Ver código fonte

feat:带宽限流首个config+lua文件上传

lihao16 4 meses atrás
pai
commit
409044cf14

+ 68 - 0
script/OpenResty/lua/bandwidth_limiter.lua

@@ -0,0 +1,68 @@
+-- lua/bandwidth_limiter.lua
+local _M = {}
+local redis = require "resty.redis"
+
+local redis_host = "127.0.0.1"
+local redis_port = 6379
+local redis_password = "Hycpb@123"
+local redis_db = 6
+
+local redis_prefix = "tenant:device_count:"
+local max_bandwidth = 1024 * 1024 -- 1MB
+local min_bandwidth = 64 * 1024   -- 最小限速 64KB
+
+local function get_redis()
+    local red = redis:new()
+    red:set_timeout(1000)
+
+    local ok, err = red:connect(redis_host, redis_port)
+    if not ok then
+        ngx.log(ngx.ERR, "Redis connection error: ", err)
+        return nil, err
+    end
+
+    -- 认证密码
+    if redis_password and redis_password ~= "" then
+        local ok, err = red:auth(redis_password)
+        if not ok then
+            ngx.log(ngx.ERR, "Redis auth failed: ", err)
+            return nil, err
+        end
+    end
+
+    -- 选择数据库
+    if redis_db then
+        local ok, err = red:select(redis_db)
+        if not ok then
+            ngx.log(ngx.ERR, "Redis select db failed: ", err)
+            return nil, err
+        end
+    end
+
+    return red
+end
+
+function _M.register_device(tenant_id)
+    local red, err = get_redis()
+    if not red then return min_bandwidth end
+
+    local key = redis_prefix .. tenant_id
+    local count, err = red:incr(key)
+    if not count then
+        ngx.log(ngx.ERR, "Redis INCR failed: ", err)
+        return min_bandwidth
+    end
+
+    red:expire(key, 60)  -- 设置 60 秒自动过期
+    return math.max(math.floor(max_bandwidth / count), min_bandwidth)
+end
+
+function _M.unregister_device(tenant_id)
+    local red, err = get_redis()
+    if not red then return end
+
+    local key = redis_prefix .. tenant_id
+    red:decr(key)
+end
+
+return _M

+ 17 - 0
script/OpenResty/lua/file_proxy.lua

@@ -0,0 +1,17 @@
+-- lua/file_proxy.lua
+local _M = {}
+
+-- MinIO 反向代理地址前缀(可改为你的 MinIO 网关地址)
+local minio_base_url = "http://117.73.3.135:9000"
+
+-- 从参数中拼接 MinIO 下载地址
+function _M.get_minio_url(file_key)
+    if not file_key or file_key == "" then
+        ngx.log(ngx.ERR, "file_key is missing")
+        return nil
+    end
+    -- 简单拼接,建议再加签名校验/编码等
+    return minio_base_url .. file_key
+end
+
+return _M

+ 73 - 0
script/OpenResty/nginx.conf

@@ -0,0 +1,73 @@
+worker_processes  1;
+
+events {
+    worker_connections  1024;
+}
+
+http {
+	lua_shared_dict limit_cache 10m;
+    include       mime.types;
+    default_type  application/octet-stream;
+    sendfile        on;
+    keepalive_timeout  65;
+	client_max_body_size	1024m;
+	
+	upstream minio-server {
+		server 117.73.3.135:9000;
+	}
+	
+	lua_package_path "/usr/local/openresty/nginx/conf/lua/?.lua;;";
+	server {
+        listen       83;
+        server_name  localhost;
+
+		location /download {
+			set_by_lua_block $tenant_id {
+                return ngx.var.arg_tenant_id or "default"
+            }
+
+			set_by_lua_block $file_key {
+                return ngx.var.arg_file_key
+            }
+
+			access_by_lua_block {
+                local limiter = require "bandwidth_limiter"
+                local proxy = require "file_proxy"
+
+                local tenant_id = ngx.var.tenant_id
+                local file_key = ngx.var.file_key
+
+                local rate = limiter.register_device(tenant_id)
+                ngx.var.limit_rate = rate
+                ngx.ctx.tenant_id = tenant_id
+
+                local url = proxy.get_minio_url(file_key)
+                if not url then
+                    return ngx.exit(400)
+                end
+
+                local parsed = url:match("https?://[^/]+(/.+)")
+                if not parsed then
+                    return ngx.exit(400)
+                end
+
+                return ngx.exec("/internal_minio" .. parsed)
+            }
+
+            log_by_lua_block {
+                local limiter = require "bandwidth_limiter"
+                if ngx.ctx.tenant_id then
+                    limiter.unregister_device(ngx.ctx.tenant_id)
+                end
+            }
+		}
+
+		# ´úÀí MinIO µÄÄÚ²¿ location
+		location ~ ^/internal_minio/(.*)$ {
+			internal;
+			limit_rate $limit_rate;
+			proxy_pass http://minio-server/$1;
+			proxy_set_header Host $host;
+		}
+	}	
+}