Openresty安装并限频
内核调参
安装Openresty
加载lua脚本实现限频
nginx配置文件
vhosts 示例
测试
内核调参
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| openresty版本:openresty-1.19.9.1 机器规格: 8c16g 内核参数修改并生效: cat /etc/sysctl.conf && sysctl -p sysctl.conf fs.file-max = 1577138 vm.swappiness = 0 kernel.sysrq = 1 net.ipv4.neigh.default.gc_stale_time = 120 net.ipv4.conf.all.rp_filter = 0 net.ipv4.conf.default.rp_filter = 0 net.ipv4.conf.default.arp_announce = 2 net.ipv4.conf.lo.arp_announce = 2 net.ipv4.conf.all.arp_announce = 2 net.ipv4.tcp_max_tw_buckets = 50000 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_max_syn_backlog = 10240 net.ipv4.tcp_synack_retries = 2 net.ipv6.conf.all.disable_ipv6 = 1 net.ipv6.conf.default.disable_ipv6 = 1 net.ipv6.conf.lo.disable_ipv6 = 1 net.netfilter.nf_conntrack_max = 524288 net.nf_conntrack_max = 524288 net.core.netdev_max_backlog = 50000 net.ipv4.tcp_tw_reuse = 1 net.ipv4.ip_local_port_range = 1024 65000
|
安装Openresty
源码编译,nginx二进制文件;
#下载openrestry,对应apt安装的版本
wget –no-check-certificate https://openresty.org/download/openresty-1.19.9.1.tar.gz
#下载nginx_upstream_check_module模块
wget –no-check-certificate https://github.com/yaoweibin/nginx_upstream_check_module/archive/v0.3.0.tar.gz
tar -xf openresty-1.19.9.1.tar.gz
tar -xf v0.3.0.tar.gz
cp -r nginx_upstream_check_module-0.3.0/ openresty-1.19.9.1/bundle/
#更新源
apt-get update
#安装编译需要依赖
sudo apt install make gcc libpcre3 libpcre3-dev openssl libssl-dev zlib1g-dev libgeoip-dev
编译
cd openresty-1.19.9.1/
sudo ./configure –prefix=/usr/local/openresty –with-cc-opt=’-O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl111/include’ –with-ld-opt=’-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl111/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl111/lib’ –add-module=./bundle/nginx_upstream_check_module-0.3.0/ –with-pcre-jit –with-stream –with-stream_ssl_module –with-stream_ssl_preread_module –with-http_v2_module –without-mail_pop3_module –without-mail_imap_module –without-mail_smtp_module –with-http_stub_status_module –with-http_realip_module –with-http_addition_module –with-http_auth_request_module –with-http_secure_link_module –with-http_random_index_module –with-http_gzip_static_module –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-threads –with-stream –with-http_ssl_module –with-http_geoip_module
sudo make
sudo make install
mkdir -p /usr/local/nginx/conf-openresty.d
mkdir -p /usr/local/nginx/vhosts
cp /usr/local/openresty/nginx/conf/mime.types /usr/local/nginx/mime.types
指定nginx配置文件
/usr/local/openresty/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf #(依照机器具体nginx配置)
加载lua脚本实现限频
lua脚本和lua限频率配置压缩包 https://www.jxhs.me/data/2024-06-23/openresty-lua.tar.gz
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 配置文件目录:/usr/local/openresty/nginx/config application.json rules/frequency_limit.json rules/filter.json tar -zxvf openresty-lua.tar.gz -C /usr/local/openresty/nginx/ cd /usr/local/openresty/nginx/config/rules/ vim frequency_limit.json [ { "enable": true, "matchers": { "URL": { "operator": "≈", "value": "api-test.test.com/info" } }, "count": "6", # 6次访问次数 "time": "1", # 1s "limit_items": ["ip"] } ]
|
nginx配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| nginx主配置文件 user ubuntu; worker_processes auto; worker_cpu_affinity auto; worker_rlimit_nofile 65535;
error_log /app/logs/nginx/error.log warn;
events { worker_connections 50240; use epoll; } http { include mime.types; default_type application/octet-stream; log_format main '{' '"time_local": "$time_local",' '"remote_addr": "$remote_addr",' '"http_x_forwarded_for": "$http_x_forwarded_for",' '"http_x_amzn_trace_id": "$http_x_amzn_trace_id",' '"host": "$host",' '"server_port": "$server_port",' '"status": "$status",' '"request_time": "$request_time",' '"upstream_connect_time": "$upstream_connect_time",' '"upstream_header_time": "$upstream_header_time",' '"request": "$request",' '"request_id": "$request_id",' '"upstream_addr": "$upstream_addr",' '"upstream_response_time": "$upstream_response_time",' '"upstream_status": "$upstream_status",' '"request_length": "$request_length",' '"body_bytes_sent": "$body_bytes_sent",' '"remote_user": "$remote_user",' '"http_referer": "$http_referer",' '"http_user_agent": "$http_user_agent"' '}';
sendfile on; send_timeout 30;
keepalive_timeout 75s; keepalive_requests 20000; gzip on; gzip_min_length 1000; gzip_buffers 4 8k; gzip_comp_level 2; gzip_http_version 1.1; gzip_types text/css text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml application/xhtml+xml application/javascript application/json; proxy_buffer_size 128k; proxy_buffers 32 128k; proxy_busy_buffers_size 128k; proxy_temp_file_write_size 128k; proxy_read_timeout 15s; proxy_connect_timeout 3s; client_max_body_size 120m; client_body_buffer_size 120M; server_tokens off; geoip_country /usr/share/GeoIP/GeoIP.dat; geoip_city /usr/share/GeoIP/GeoLiteCity.dat; map $http_x_forwarded_for $RealIpFromForwarded { "" $remote_addr; ~^.*?,?(?P<ipAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ $ipAddr; } map $http_x_connecting_ip $clientRealIp { "" $RealIpFromForwarded; ~^.*?,?(?P<ipAddr>[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$ $ipAddr; } server { listen 80; server_name localhost; location / { return 404; } location /health { add_header Content-Type text/plain; return 200 'ngx up!'; } location /nginx_status { stub_status on; allow 127.0.0.1; deny all; } } include conf-openresty.d/*.conf; include vhosts/*.conf; }
|
nginx配置加载lua脚本
|
lua_package_path '/usr/local/openresty/nginx/lua/?.lua;;/usr/local/openresty/nginx/lua/module/?.lua;;/usr/local/openresty/nginx/lua/library/?.lua;;'; lua_package_cpath '/usr/local/openresty/nginx/lua/?.so;;'; lua_code_cache on;
lua_shared_dict frequency_limit 10m; lua_shared_dict config 5m; lua_shared_dict summary 20m; lua_shared_dict status 10m;
init_by_lua_file /usr/local/openresty/nginx/lua/on_init.lua; access_by_lua_file /usr/local/openresty/nginx/lua/on_access.lua; rewrite_by_lua_file /usr/local/openresty/nginx/lua/on_rewrite.lua; log_by_lua_file /usr/local/openresty/nginx/lua/on_log.lua;
|
vhosts 示例
| vim /usr/local/nginx/vhosts/api-test.test.com.conf server { listen 80; server_name api-test.test.com;
access_log /app/logs/nginx/api-test.test.com.access.log json; error_log /app/logs/nginx/api-test.test.com.error.log error;
location / { proxy_pass http: } location /info { echo "123 $remote_addr"; } }
|
测试
1.启动openresty
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| nginx.service cat /lib/systemd/system/nginx.service [Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.target remote-fs.target nss-lookup.target Wants=network-online.target
[Service] Type=forking PIDFile=/usr/local/openresty/nginx/logs/nginx.pid ExecStartPre=/usr/local/openresty/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf -t ExecStart=/usr/local/openresty/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf ExecReload=/usr/local/openresty/nginx/sbin/nginx -s reload ExecStop=/usr/local/openresty/nginx/sbin/nginx -s stop PrivateTmp=true LimitNOFILE=65535
[Install] WantedBy=multi-user.target
|
在另外一台服务器配置hosts做测试,模拟20个请求访问 http://api-test.test.com/info,在1s内超过6个的其他请求会返回 frequency limit 的网页信息并返回429的状态码
~$ sudo /usr/local/openresty/nginx/sbin/nginx -c /usr/local/nginx/nginx.conf # 启动 openresty
在另外一台主机上测试,模拟20个请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| ~$ for i in {1..20};do curl http://api-test.test.com/info;done 123 172.31.15.178 123 172.31.15.178 123 172.31.15.178 123 172.31.15.178 123 172.31.15.178 123 172.31.15.178 <!DOCTYPE html> <html> <body> <h1>frequency limit</h1> </body> </html> <!DOCTYPE html> <html> <body> <h1>frequency limit</h1> </body> </html> <!DOCTYPE html> <html> <body> <h1>frequency limit</h1> </body> </html> <!DOCTYPE html> <html> <body> <h1>frequency limit</h1> </body> </html> <!DOCTYPE html> <html> <body> <h1>frequency limit</h1> </body> </html> ...
|
查看nginx日志,看到返回429 status code,符合预期