前言
OpenResty 是基于 Nginx 的高性能 Web 应用服务器,它集成了 Lua 编程语言,使开发人员能够快速构建灵活、可扩展的 Web 应用程序。借助 OpenResty,您可以利用 Nginx 强大的性能特点和 Lua 的编程能力来处理复杂的业务逻辑,并实现高并发和高效率的请求处理。同时,OpenResty 还提供了丰富的 Lua 库和模块,简化开发过程,如处理 HTTP 请求、操作数据库等。总之,OpenResty 是一个强大而简洁的工具,适用于构建高性能的 Web 应用程序。
环境
本文章使用的是腾讯云CVM服务器。CVM可提供多种类型的实例、操作系统和软件包。各实例中的 CPU、内存、硬盘和带宽可以灵活调整,以满足您应用程序的资源需要。同时腾讯云市场提供第三方镜像及软件供您选择。本次实验系统为Debian 12 。OpenResty版本为 1.21.4.2
安装OPENRESTY
本次是基于源码编译安装,也可以使用包管理器安装
编译环境
bash
root@VM-0-3-debian:~# lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 12 (bookworm)
Release: 12
Codename: bookworm
安装依赖
bash
sudo apt update
sudo apt install -y libgeoip-dev libpcre3 libpcre3-dev openssl libssl-dev libmaxminddb0 libmaxminddb-dev mmdb-bin libgeoip1 libgeoip-dev geoip-bin build-essential gcc libtool autoconf zlib1g zlib1g-dev git
安装libmaxminddb
libmaxminddb 是一个 C 语言库,用于解析 MaxMind DB 格式的 IP 地理位置数据库。
bash
#path ~/openresty
wget https://github.com/maxmind/libmaxminddb/releases/download/1.7.1/libmaxminddb-1.7.1.tar.gz
tar -xzvf libmaxminddb-1.7.1.tar.gz
cd libmaxminddb-1.7.1
./configure
make
make check
sudo make install
sudo sh -c "echo /usr/local/lib >> /etc/ld.so.conf.d/local.conf"
sudo ldconfig
准备openssl、pcre和zlib
查询openssl版本
bash
root@VM-0-3-debian:~# openssl version
OpenSSL 3.0.9 30 May 2023 (Library: OpenSSL 3.0.9 30 May 2023)
我们手动下载对应版本的openssl、pcre和zlib,注意这三个库只需要下载解压,并不需要提前进行安装。
bash
#path ~/openresty
# 下载
wget https://www.openssl.org/source/openssl-3.0.9.tar.gz
wget http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-8.45.tar.gz
wget http://www.zlib.net/zlib-1.3.tar.gz
# 解压
tar -zxvf openssl-3.0.9.tar.gz
tar -zxvf pcre-8.45.tar.gz
tar -zxvf zlib-1.3.tar.gz
下载ngx_http_geoip2_module
ngx_http_geoip2_module 是一个用于 Nginx 的第三方模块,它提供了对 MaxMind GeoIP2 数据库的支持。
bash
#path ~/openresty
git clone https://github.com/leev/ngx_http_geoip2_module.git
创建用户&&组&&目录
bash
groupadd nginx
useradd -g nginx -s /sbin/nologin -M nginx
mkdir -p /var/cache/nginx
下载openresty
bash
#path ~/openresty
wget https://openresty.org/download/openresty-1.21.4.2.tar.gz
tar -zxvf openresty-1.21.4.2.tar.gz
编译安装
我们可以自定义编译安装的模块,这里可以查看openresty模块的官方说明或使用
./configure --help
。
bash
#配置和准备 软件包
#path ~/openresty/openresty-1.21.4.2
./configure \
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-compat \
--with-file-aio \
--with-threads \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_random_index_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--with-stream \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-luajit \
--with-pcre-jit \
--with-http_geoip_module \
--with-http_dav_module \
--add-module=/root/openresty/ngx_http_geoip2_module \
--with-openssl=/root/openresty/openssl-3.0.9 \
--with-zlib=/root/openresty/zlib-1.3 \
--with-pcre=/root/openresty/pcre-8.45
运行
gmake
命令来编译软件包,最后使用gmake install
命令来安装它
bash
gmake
gmake install
配置环境变量
在
~/.bashrc
文件中添加环境变量,然后执行source ~/.bashrc
使其生效。
bash
#path ~/.bashrc
vim ~/.bashrc
export PATH=$PATH:/etc/nginx/bin
source ~/.bashrc
配置systemctl管理openresty
在
/etc/systemd/system/nginx.service
目录下创建nginx.service
文件。
bash
#path /etc/systemd/system/nginx.service
cat > /etc/systemd/system/nginx.service << EOF
[Unit]
Description=Nginx(OpenResty ) - high performance web server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP "
ExecStop=/bin/sh -c "/bin/kill -s TERM "
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF
然后执行
systemctl daemon-reload
使其生效。 执行systemctl enable nginx
使其开机自启。 执行systemctl start nginx
启动openresty。
bash
# 一些常用命令
systemctl status nginx #查看openresty状态。
systemctl stop nginx #停止openresty。
systemctl restart nginx #重启openresty。
打开浏览器访问http://ip:80
,如果出现下面页面则说明安装成功。
OpenResty操作命令
openresty的操作指令和nginx是完全一致的。具体如下:
bash
root@VM-0-15-debian:~# nginx -h
nginx version: openresty/1.21.4.2
Usage: nginx [-?hvVtTq] [-s signal] [-p prefix]
[-e filename] [-c filename] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit
-t : test configuration and exit
-T : test configuration, dump it and exit
-q : suppress non-error messages during configuration testing
-s signal : send signal to a master process: stop, quit, reopen, reload
-p prefix : set prefix path (default: /etc/nginx/nginx/)
-e filename : set error log file (default: /var/log/nginx/error.log)
-c filename : set configuration file (default: /etc/nginx/nginx.conf)
-g directives : set global directives out of configuration file
配置openresty
IP数据库
:GeoLite2-City,下载后放在/etc/nginx/goeip2/
目录下。
配置文件路径/etc/nginx/nginx.conf
,下面是我配置的文件,可以根据自己的需求进行修改。
conf
#path /etc/nginx/nginx.conf
# 指定启动nginx使用的用户(不指定为nobody)
user nginx;
# 定义作为web服务器/反向代理服务器时的 worder process 进程数
worker_processes auto;
# 开启多核支持,且自动根据CPU个数均匀分配 worder process 进程数
worker_cpu_affinity auto;
# 指定一个nginx进程可以打开的最多文件描述符数目
worker_rlimit_nofile 65535;
# error_log配置,等级类型:[ debug | info | notice | warn | error | crit ]
error_log /var/log/nginx/error.log notice;
# nginx的进程pid位置;
pid /var/run/nginx.pid;
# 连接处理相关设置
events {
# 使用epoll的 I/O 模型,必开项,极其有利于性能
use epoll;
# 设置是否允许一个worker可以接受多个请求,默认是off;
# 值为OFF时,一个worker process进程一次只接收一个请求,由master进程自动分配worker(nginx精于此道,故建议设置为off);
# 值为ON则一次可接收所有请求,可避免master进程额外调度,但是在高瞬时值的情况下可能导致tcp flood;
multi_accept off;
# 每个工作进程的并发连接数(默认为1024)
# 理论上nginx最大连接数 = worker_processes * worker_connections
worker_connections 65535;
}
http {
################################ngx_lua_waf web应用防火墙################################
# ##WAF 配置资源引用开始
# lua_package_path "/etc/nginx/site/lualib/?.lua;;";
# lua_shared_dict limit 20m;
# # init_by_lua_file /etc/nginx/luaconf/init.lua;
# # access_by_lua_file /etc/nginx/luaconf/waf.lua;
# lua_code_cache on;
# # Set Prometheus global dict
# lua_shared_dict prometheus_metrics 10M; #init 10M memory
# lua_shared_dict uri_by_host 10M;
# lua_shared_dict global_set 1M;
################################ngx_lua_waf web应用防火墙################################
charset utf-8;
# mime.types 指定了nginx可以接受的 Content-Type,该文件默认位于nginx.conf的同级目录
include /etc/nginx/mime.types;
# 设置默认文件类型,application/octet-stream 表示未知的应用程序文件,浏览器一般不会自动执行或询问执行
default_type application/octet-stream;
################################获取访问用户真实IP(而不是CDN节点IP)################################
set_real_ip_from 0.0.0.0/0;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
################################IP数据库################################
geoip2 /etc/nginx/goeip2/GeoLite2-City.mmdb {
auto_reload 5m;
$geoip2_data_country_code country iso_code;
$geoip2_data_country_name country names zh-CN;
$geoip2_data_province_name subdivisions 0 names zh-CN;
$geoip2_data_city_name city names zh-CN;
$geoip2_data_location_latitude location latitude;
$geoip2_data_location_longitude location longitude;
}
################################设置日志的记录格式 ################################
log_format main escape=none '$geoip2_data_country_name - $geoip2_data_city_name - '
'$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# 不记录404错误的日志
log_not_found off;
# 隐藏nginx版本号
server_tokens off;
# 开启0拷贝,提高文件传输效率
sendfile on;
# 配合 sendfile 使用,启用后数据包会累计到一定大小之后才会发送,减小额外开销,提高网络效率;
tcp_nopush on;
# 启用后表示禁用 Nagle 算法,尽快发送数据
# 与 tcp_nopush 结合使用的效果是:先填满包,再尽快发送
# Nginx 只会针对处于 keep-alive 状态的 TCP 连接才会启用 tcp_nodelay
tcp_nodelay on;
# 指定客户端与服务端建立连接后发送 request body 的超时时间,超时Nginx将返回http 408
client_body_timeout 10;
# 开启从client到nginx的连接长连接支持,指定每个 TCP 连接最多可以保持多长时间
# keepalive_timeout的值应该比 client_body_timeout 大
keepalive_timeout 65;
# keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接将被关闭
keepalive_requests 1000;
################################客户端请求头部的缓冲区大小,设置等于系统分页大小即可,如果header过大可根据实际情况调整;################################
# 查看系统分页:getconf PAGESIZE
client_header_buffer_size 32k;
# 设置客户端请求的Header头缓冲区大小,如果客户端的Cookie信息较大,按需增加
large_client_header_buffers 4 64k;
# 优化读取\$request_body变量时的I/O性能
client_body_in_single_buffer on;
# 设定request body的缓冲大小,仅在 Nginx被设置成使用内存缓冲时有效(使用文件缓冲时该参数无效)
client_body_buffer_size 128k;
# 开启proxy忽略客户端中断,避免499错误
proxy_ignore_client_abort on;
# 默认的情况下nginx引用header变量时不能使用带下划线的变量,设置underscores_in_headers为 on取消该限制
underscores_in_headers on;
# 默认的情况下nginx会忽略带下划线的变量,设置ignore_invalid_headers为off取消该限制
ignore_invalid_headers off;
# 设置客户端向服务端发送一个完整的 request header 的超时时间,优化弱网场景下nginx的性能
client_header_timeout 10;
# 设置向客户端传输数据的超时时间
send_timeout 60;
# 用于启用文件功能时用限制文件大小;
client_max_body_size 50m;
################################ 文件压缩配置,对文本文件效果较好,对图像类应用效果一般反而徒增服务器资源消耗################################
gzip on;
# 兼容http 1.0
gzip_http_version 1.0;
# 压缩比,数值越大:压缩的程度越高、空间占用越低、压缩效率越低、资源消耗越大
gzip_comp_level 6;
# 设置压缩门限,小于该长度将不会进行压缩动作(数据过小的情况下,压缩效果不明显)
gzip_min_length 1k;
# 用于在nginx作为反向代理时,根据请求头中的"Via"字段决定是否启用压缩功能,默认值为off,any表示对所有请求启动压缩;
gzip_proxied any;
# 用于在启动gzip压缩功能时,在http响应中添加Vary: Accept-Encoding头字段告知接收方使用了gzip压缩;
gzip_vary on;
# 当Agent为IE6时禁用压缩:IE6对Gzip不友好,所以不压缩
gzip_disable msie6;
# 设置系统用于存储gzip的压缩结果数据流的缓存大小(4 4k 代表以4k为单位,按照原始数据大小以4k为单位的4倍申请内存)
gzip_buffers 4 64k;
# 指定需要压缩的文件mime类型
gzip_types text/xml text/plain text/css application/javascript application/x-javascript application/xml application/json application/rss+xml;
################################ 作为反向代理服务器配置 ################################
# 当请求未携带"Host"请求头时将Host设置为虚拟主机的主域名
# proxy_set_header Host \$host;
# 设置真实客户端IP
# proxy_set_header X-Real-IP \$remote_addr;
# 简称XFF头,即HTTP的请求端真实的IP,在有前置cdn或者负载均衡可能会被修改;如果要提取客户端真实IP,需要根据实际情况调整,如若后端程序获得对X-Forwarded-For兼容性不好的话(没有考虑到X-Forwarded-For含有多个IP的情况),建议设置为:\$http_x_forwarded_for
# proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
# 启用nginx和后端server(upstream)之间长连接支持(必设项,否则很影响nginx性能),HTTP协议中从1.1版本才支持长连接;启用时需要评估upstream的keepalive参数(默认是关闭的,比较懒的同学可以设置为500)
proxy_http_version 1.1;
# 为了兼容老的协议以及防止http头中有Connection close导致的keepalive失效,需要及时清掉HTTP头部的Connection;
# 该参数决定了访问完成后,后端server后如何处理本次连接,默认配置是主动close(会给后端server带来大量的TIME_WAIT连接,降低后端server性能),设置为""结合proxy_http_version设置连接保持(长连接);
proxy_set_header Connection "";
# 用于对发送给客户端的URL进行修改,使用不到的话可以关闭
proxy_redirect off;
# 设置缓冲区的大小和数量,用于放置被代理的后端服务器取得的响应内容
proxy_buffers 64 8k;
# 设置和后端建立连接的超时时间,单位秒
proxy_connect_timeout 60;
# 设置Nginx向后端被代理服务器发送read请求后,等待响应的超时时间,默认60秒
proxy_read_timeout 60;
# 设置Nginx向后端被代理服务器发送write请求后,等待响应的超时时间,默认60秒
proxy_send_timeout 60;
# 用于配置存放HTTP报文头的哈希表容量,默认为512个字符。一般都设置为1024,这个大小是哈希表的总大小,
#设定了这个参数Nginx不是一次全部申请出来,需要用的时候才会申请;
#但是当真正需要使用的时候也不是一次全部申请,而是会设置一个单次申请最大值(proxy_headers_hash_bucket_size)
proxy_headers_hash_max_size 1024;
# 用于设置Nginx服务器申请存放HTTP报文头的哈希表容量的单位大小,默认为64个字符。一般配置为128。
#这个大小是单次申请最多申请多大,也就是每次用需要申请,但是每次申请最大申请多少,整个哈希表大小不可超过上面设置的值。
proxy_headers_hash_bucket_size 128;
# 设置缓存临时目录
proxy_temp_path /var/cache/nginx/proxy_temp;
# 设置缓存目录、目录结构及缓存数据保留策略
proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=cache_one:512m inactive=1d max_size=2g;
################################ 预防 DDOS 攻击配置策略 ################################
#limit_req_zone \$binary_remote_addr zone=req:20m rate=3r/s;
#limit_req zone=req burst=60;
#limit_zone conn \$binary_remote_addr 20m;
#limit_conn conn 5;
#limit_rate 50k;
################################设置nginx可以捕获的服务器名字(server_name)的最大数量################################
server_names_hash_max_size 1024;
################################设置nginx中server_name支持的最大长度################################
server_names_hash_bucket_size 128;
include /etc/nginx/conf.d/*.conf;
}
配置ip查询接口
在
/etc/nginx/conf.d/
目录下创建ip.conf
文件并修改为下面配置内容。
conf
#path /etc/nginx/conf.d/ip.conf
server {
listen 80;
server_name localhost;
#listen 443 ssl http2;
#listen [::]:443 ssl http2;
#ssl_certificate /etc/nginx/conf.d/ssl/cert.pem;
#ssl_certificate_key /etc/nginx/conf.d/ssl/key.pem;
# server_name xxx.xxx.xxx;
access_log /var/log/nginx/ip.log main;
default_type text/plain;
location / {
if ($http_user_agent ~* "curl|wget") {
rewrite / /ip last;
}
rewrite / /info last;
}
location /ip {
echo $remote_addr;
}
location /country_code {
echo $geoip2_data_country_code;
}
location /country {
echo $geoip2_data_country_name;
}
location /province {
echo $geoip2_data_province_name;
}
location /city {
echo $geoip2_data_city_name;
}
location /latitude {
echo $geoip2_data_location_latitude;
}
location /longitude {
echo $geoip2_data_location_longitude;
}
location /ua {
echo $http_user_agent;
}
location /info {
echo "IP ADDRESS : $remote_addr";
echo " ";
echo "COUNTRY CODE : $geoip2_data_country_code";
echo "COUNTRY : $geoip2_data_country_name";
echo "PROVINCE : $geoip2_data_province_name";
echo "CITY : $geoip2_data_city_name";
echo " ";
echo "LATITUDE : $geoip2_data_location_latitude";
echo "LONGITUDE : $geoip2_data_location_longitude";
echo " ";
echo "USER AGENT : $http_user_agent";
echo "";
echo "Use /help for more information";
}
location /help {
echo "/ IP INFO (browser) | IP ADDRESS (wget/curl)";
echo " ";
echo "/ip IP ADDRESS";
echo " ";
echo "/info IP INFO";
echo "/json IP INFO (JSON)";
echo " ";
echo "/country_code COUNTRY CODE";
echo "/country COUNTRY NAME";
echo "/province PROVINCE NAME";
echo "/city CITY NAME";
echo " ";
echo "/longitude LONGITUDE";
echo "/latitude LATITUDE";
echo " ";
echo "/ua USER AGENT";
echo " ";
echo "Advanced:";
echo "/{cmd}/{ip} FIND IP INFO, eg: /info/1.1.1.1";
}
location /json {
default_type application/json;
return 200 '{
"ip": "$remote_addr",
"country_code": "$geoip2_data_country_code",
"country": "$geoip2_data_country_name",
"province": "$geoip2_data_province_name",
"city": "$geoip2_data_city_name",
"latitude": "$geoip2_data_location_latitude",
"longitude": "$geoip2_data_location_longitude",
"ua": "$http_user_agent",
"forwarded": "$http_x_forwarded_for"
}';
}
location ~ ^/(\w+/)?(\d+\..+|\w*:.+)$ {
proxy_pass http://127.0.0.1/$1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $2;
}
}
执行
nginx -s reload
,访问http://ip:80
,如果出现下面页面则说明配置成功。
配置logrotate自动分割压缩日志
创建
/etc/logrotate.d/nginx
文件并修改为下面配置内容。
conf
#path /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
手动运行logrotate命令来测试配置是否正确:
bash
logrotate -f /etc/logrotate.d/nginx
确认一切正常后,您可以通过以下命令来实际执行logrotate并轮转日志文件
bash
logrotate /etc/logrotate.conf