diff --git a/playbooks/roles/vhosts/OpenResty/handlers/main.yml b/playbooks/roles/vhosts/OpenResty/handlers/main.yml new file mode 100644 index 0000000..22c1996 --- /dev/null +++ b/playbooks/roles/vhosts/OpenResty/handlers/main.yml @@ -0,0 +1,4 @@ +- name: Restart OpenResty + systemd: + name: openresty + state: restarted diff --git a/playbooks/roles/vhosts/OpenResty/meta/main.yml b/playbooks/roles/vhosts/OpenResty/meta/main.yml new file mode 100644 index 0000000..9711b33 --- /dev/null +++ b/playbooks/roles/vhosts/OpenResty/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - role: common diff --git a/playbooks/roles/vhosts/OpenResty/tasks/main.yml b/playbooks/roles/vhosts/OpenResty/tasks/main.yml new file mode 100644 index 0000000..507d5e2 --- /dev/null +++ b/playbooks/roles/vhosts/OpenResty/tasks/main.yml @@ -0,0 +1,28 @@ +- name: Install prerequisites for OpenResty + apt: + name: software-properties-common + state: present + update_cache: yes + +- name: Add OpenResty apt repository + apt_repository: + repo: ppa:openresty/ppa + state: present + +- name: Install OpenResty + apt: + name: openresty + state: present + update_cache: yes + +- name: Deploy nginx configuration + template: + src: nginx.conf.j2 + dest: /usr/local/openresty/nginx/conf/nginx.conf + notify: Restart OpenResty + +- name: Enable and start OpenResty + systemd: + name: openresty + enabled: yes + state: started diff --git a/playbooks/roles/vhosts/OpenResty/templates/nginx.conf.j2 b/playbooks/roles/vhosts/OpenResty/templates/nginx.conf.j2 new file mode 100644 index 0000000..a81f972 --- /dev/null +++ b/playbooks/roles/vhosts/OpenResty/templates/nginx.conf.j2 @@ -0,0 +1,56 @@ +worker_processes auto; +events { worker_connections 1024; } + +http { + lua_shared_dict limit_cache 10m; + + server { + listen 80; + server_name localhost; + + location /api/askai { + access_by_lua_block { + local redis = require "resty.redis" + local r = redis:new() + r:set_timeout(200) + + -- 连接 Redis + local ok, err = r:connect("127.0.0.1", 6379) + if not ok then + ngx.log(ngx.ERR, "failed to connect to redis: ", err) + return ngx.exit(500) + end + + -- 用户标识(优先 token 参数,否则用 IP) + local user = ngx.var.arg_user or ngx.var.remote_addr + local today = os.date("%Y%m%d") + local user_key = "limit:user:" .. user .. ":" .. today + local global_key = "limit:global:" .. today + + -- 用户限额 200 + local current, err = r:incr(user_key) + if current == 1 then + r:expire(user_key, 86400) + end + if current > 200 then + ngx.status = 429 + ngx.say("Too Many Requests: user limit reached") + return ngx.exit(429) + end + + -- 全局限额 20000 + local gcount, err = r:incr(global_key) + if gcount == 1 then + r:expire(global_key, 86400) + end + if gcount > 20000 then + ngx.status = 429 + ngx.say("Too Many Requests: global limit reached") + return ngx.exit(429) + end + } + + proxy_pass http://127.0.0.1:5000; + } + } +} diff --git a/playbooks/roles/vhosts/Redis/meta/main.yml b/playbooks/roles/vhosts/Redis/meta/main.yml new file mode 100644 index 0000000..9711b33 --- /dev/null +++ b/playbooks/roles/vhosts/Redis/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - role: common diff --git a/playbooks/roles/vhosts/Redis/tasks/main.yml b/playbooks/roles/vhosts/Redis/tasks/main.yml new file mode 100644 index 0000000..c2ec476 --- /dev/null +++ b/playbooks/roles/vhosts/Redis/tasks/main.yml @@ -0,0 +1,11 @@ +- name: Install Redis server + apt: + name: redis-server + state: present + update_cache: yes + +- name: Enable and start Redis service + systemd: + name: redis-server + enabled: yes + state: started