Nginx05-配置Nginx
动静分离
vim /usr/local/nginx/conf/nginx.conf
location / {
root html;
index index.php index.html index.htm;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
#pass是将请求转发给本机9000端口,PHP解释器现在在本机
#如果PHP解释器不在本机,在哪个服务器就写哪个服务器的IP
fastcgi_index index.php;
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #注释
include fastcgi.conf; #nginx的内部变量,出场时定义好的
}
/usr/local/nginx/sbin/nginx -s reload
优化配置
全局配置-优化并发
worker_processes 2; # 与CPU核心数量一致
worker_cpu_affinity 0001 0010 0100 1000;
use epoll; # 默认值,底层的驱动方式
worker_cpu_affinity 01 10; # worker进程与固定编号的cpu核心绑定
worker_priority 0; # 指定worker进程的nice值,设定worker进程优先级 [-20,20],最大到19
worker_rlimit_nofile 10000; # worker进程所能打开的文件描述符上限总和
event {
worker_connections 65535; # 每个worker最大并发连接数,可以略微的超出范围
accept_mutex on; # worker进程轮流处理请求
}
最大并发连接数= worker_processes * worker_connections
客户端请求限制
共享空间10M,一个IP有10个并发连接
http {
limit_conn_zone $binary_remore_addr zone=perip:10m;
limit_conn perip 10;
}
限制虚拟主机并发
http {
...
limit_conn_zone $server_name zone=perserver:10m;
server {
listen 80;
server_name localhost;
limit_conn perserver 20;
}
}
限制相应速率传输
http {
limit_rate 100k;
limit_rate_after 10m;
...
}
测试并发连接
使用ApacheBench工具
ab -c 2000 -n 2000 http://192.168.4.5/ # 地址必须以/结尾
# -c 人数 并发数
# -n 总请求次数
**worker_cpu_affinity**
将worker进程与固定cpu核心绑定,提高缓存命中率
例子中展示的是4核心,第一个worker进程与0号cpu(0001)绑定,第二个worker进程与1号cpu(0010)绑定
**worker_cpu_affinity**
worker_cpu_affinity 0001 0010 0100 1000
有几个核心就有几位数
# 0号cpu 00000001
# 1号cpu 00000010
# 8号cpu 10000000
**优化Linux内核参数**(最大文件数量)
增大nginx的并发量的同时,也要增大内核的最大文件数,不然会被限制
临时配置
ulimit -Hn 100000 //设置硬限制,不可违背,这是操作系统的限制,所以这是在改内核
ulimit -Sn 100000 //设置软限制,可以违背
查看
ulimit -a
open files (-n) 10000 #显示的是软连接的值
永久配置
重启设备生效
vim /etc/security/limits.conf
* soft nofile 100000
* hard nofile 100000
#该配置文件分4列,分别如下:
#限制的用户或组 硬限制或软限制 需要限制的项目 限制的值
优化Nginx数据包头缓存
vim /usr/local/nginx/conf/nginx.conf
http {
client_header_buffer_size 1k; //默认请求包头信息的缓存buffer,默认值1k,
large_client_header_buffers 4 4k;
//大请求包头部信息的缓存个数与容量,4个4k,共16k,地址栏全是文字,占内存比较小
//生产环境中16k足够,若不够用,可能有人恶意攻击,消耗你的内存
}
日志切割
每周5的03点03分自动执行脚本完成日志切割工作。
vim /usr/local/nginx/logbak.sh
#!/bin/bash
date=`date +%Y%m%d`
logpath=/usr/local/nginx/logs
mv $logpath/access.log $logpath/$date-access.log
mv $logpath/error.log $logpath/$date-error.log
kill -USR1 $(cat $logpath/nginx.pid)
rm -f $(find /usr/local/nginx/logs/ -type f -name "*.log" -mtime +30)
crontab -e
03 03 * * 5 /usr/local/nginx/logbak.sh
地址重写和重定向
格式
rewrite regex replacement [flag]
if指令判断符号
= 判断变量与内容相等
~ 区分大小写正则匹配
!~ 区分大小写正则不匹配
-f 判断文件存在
-d 判断目录存在
-e 判断文件或目录存在
-x 判断可执行文件
!= 判断变量与内容不等
~* 不区分大小写正则匹配
!~* 不区分大小写正则不匹配
!-f 判断文件不存在
!-d 判断目录不存在
!-e 判 断文件或目录不存在
!-x 判断不可执行文件
应用
if ( $http_user_agent ~* firefox ) {
rewrite ^/(.*) /firefox/$1;
}
# $1 代表前面第一个括号里的内容
rewrite 旧地址(正则表示) 新地址 [选项]
last 完成匹配格式后,用新的格式继续新的匹配,不再读取其他rewrite
break 不再读取其他语句,结束请求
redirect 临时重定向,改变地址栏,返回301
permanent 永久重定向,返回302
防盗链
当请求消息头的referer符合白名单时,内置变量$invalid_refer的值为空字符串,否则为1
location ~* \.(gif|jpg|png|swf|flv)$ {
vaild-referers www.test.com; 允许使用链接的域名
if ($invalid_referer) {
return 403;
}
}
访问控制
deny、allow可以写在不同的语句块中,内层的语句块会覆盖外层的语句块
# 禁止所有用户访问
deny all;
# 只允许指定IP访问,其他禁止访问
allow 192.168.13.88
deny all;
精准匹配
用户访问的URI与指定的URI完全一致
使用“=”表示
location =/js {
allow 192.168.1.1;
}
location =/admin/auto {
allow 192.168.1.2;
}
正则匹配
有多个location,将按照location的书写顺序进行匹配,匹配即停止
使用正则用“~”表示
location ~\.html$ {
allow 192.168.1.1;
}
location ~/admin/.*\.html$ {
allow 192.168.1.2;
}
禁用正则匹配
^~ 用于前缀匹配,比正则匹配优先级高。
如果一个 URI 匹配了 ^~ 定义的块,那么这个块将被立即使用,不会再进行正则表达式匹配,其他正则匹配也就失效了
location ~\.html$ {
allow 192.168.1.1;
}
location ~/admin/.*\.html$ {
allow 192.168.1.2;
}
最大前缀匹配
有多个location,匹配程度最高的会执行
注意:location后没有符号
location /hc.test {
allow 192.168.1.1;
}
location /hc.test/log {
allow 192.168.1.2;
}
root和alias的区别
alias 只能作用在location中,而root可以存在server、http和location中。
alias 后面必须要用 “/” 结束,否则会找不到文件,而 root 则对 ”/” 可有可无。
alias 指定资源路径时,不会添加location字段指定的路径,示例如下:
location /img {
alias /var/www/image/;
}
# 访问http://localhost/img时,会在/var/www/image下寻找
location /img {
root /var/www/image;
}
# 访问http://localhost/img时,会在/var/www/image/img下寻找
访问控制的优先级
精确匹配 (=):最高优先级。
前缀匹配 (^~):如果匹配成功,停止进一步匹配,不再进行正则表达式匹配。
正则表达式匹配 (~ 和 ~*):如果没有更高优先级的匹配,则进行正则表达式匹配。
普通前缀匹配:最低优先级,如果没有更高优先级的匹配,这时才会使用普通的前缀匹配。
访问控制匹配规则
= 精确匹配,内容要同表达式完全一致才匹配成功
^ 以某个字符串开头
$ 以某个字符串结尾
~ 执行正则匹配,区分大小写
~* 执行正则匹配,不区分大小写
^~ 禁用正则(与=都能阻止继续搜索正则)
!~ 取反
!~* 取反
/ 通用匹配,任何请求都会匹配到
用户认证
需要--with-http_auth_request_module 系统默认已安装
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
auth_basic "Input Password:"; // 认证提示符,提示信息,不能打中文
auth_basic_user_file "/usr/local/nginx/pass"; // 认证密码文件,此文件不存在,需要自己创建
location / {
root html;
index index.html index.htm;
}
}
生成密码文件,创建用户及密码
使用htpasswd命令创建账户文件,需要确保系统中已经安装了httpd-tools。
yum -y install httpd-tools
htpasswd -C /usr/local/nginx/pass tom // 创建密码文件pass,该文件会被自动创建,tom是用户名
htpasswd /usr/local/nginx/pass jerry // 追加用户,不使用-C选项
cat /usr/local/nginx/pass
tom:$apr1$mGP4Yk.g$1l.7uUssDYSY97ON4POPu/
jerry:$apr1$anqEMwda$qmFgBeYK1a9JkLE8Ur8gl/
重启Nginx服务
nginx -s reload
客户端测试,输入密码后可以访问
配置SSL虚拟主机
编译时添加选项
--with-http_ssl_module # nginx开启ssl
--with-openssl=xxx # 指定openssl路径,一般是新安装的路径
生成私钥与证书
cd /usr/local/nginx/conf // 默认放在此路径下,也可以放到别的路径
openssl genrsa > cert.key // 生成私钥,cert.key 随意命名
openssl req -new -x509 -key cert.key > cert.pem // 根据私钥生成证书,证书里存放着公钥
# req 请求
# -new 新的证书
# -x509 证书的格式
#填写国家、省份、市、公司、部门、服务器名、邮箱
修改Nginx配置文件,设置加密网站的虚拟主机
server {
listen 443 ssl;
server_name www.c.com;
ssl_certificate cert.pem; // 指定证书文件
ssl_certificate_key cert.key; // 指定私钥文件
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m; // 超时时间,访问网站比别人慢,因为进行加密了
ssl_ciphers HIGH:!aNULL:!MD5; // 密码不能为空
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
http 跳转 https
编辑默认server块
rewrite ^(.*) https://127.0.0.1 permanent;
自定义报错
自定义报错页面,以指定的状态码进行响应
可以写在http server location中
vim /usr/local/nginx/conf/nginx.conf
error_page 404 /404.html; #自定义错误页面
error_page 500 501 502 /50x.html; #每一个错误页面都可以写
error_page 404 =200 /404.html; #以200的状态码来进行响应
404报错会被反向代理到http://backend
location / {
error_page 404 @fallback;
}
location @fallback {
proxy_pass http://backend;
}
# 自定义404
vim /usr/local/nginx/html/404.html
肥肠抱歉
# 404不显示nginx版本号
vim nginx.conf 在http公共配置区域增加 server_tokens off;
#常见http状态码
200 一切正常
301 永久重定向,用户请求的原页面已经失效,浏览器将旧地址转换为新地址
302 临时重定向,用户请求的原页面没有失效,浏览器将旧地址转换为新地址
401 用户请求资源时,所提供的认证信息是错误的,或者没有提供
403 用户请求资源时,所提供的认证信息正确,但是浏览器禁止访问该用户访问,权限不足
404 文件不存在
414 请求URI头部过长
500 服务器内部错误,脚本语法错误或者并发过高,超过系统限制
502 集群错bad geteway
动态修改内容
addition 模块
假设后端应用程序生成了两个部分的响应,而你想要将它们合并为一个单独的响应。
你可以使用 addition 模块来完成这个任务。
# 当请求 /combine 时,nginx 将代理到后端服务器,并在发送给客户端之前将
# part1.html 和 part2.html 的内容添加到响应体的前面,从而形成一个组合的响应。
location /combine {
proxy_pass http://backend;
addition_types text/html;
addition_before_body /part1.html;
addition_before_body /part2.html;
}
add_before_body # 在响应体前添加子请求
add_after_body # 在响应体后添加子请求
addition_typs # 指定MIME类型,*表示启用所有MIME类型
sub 模块
假设你想要从后端应用程序生成的响应中去除某些特定部分,你可以使用 sub 模块来实现。
# 在这个例子中,nginx 会代理请求到后端服务器,并且在将响应发送给客户端之前,从响应
# 中去除所有匹配 <div class="remove-me">This part will be removed</div> 的内容。
location /remove {
proxy_pass http://backend;
sub_filter '<div class="remove-me">This part will be removed</div>' '';
}
xslt 模块
假设后端应用程序生成的是 XML 格式的响应,而你想将其转换为 HTML,你可以使用 xslt 模块。
# 在这个例子中,nginx 会代理请求到后端服务器,并且在将响应发送给客户端之前,使用指定的
# XSLT 样式表将 XML 响应转换为 HTML 格式
location /transform {
proxy_pass http://backend;
xslt_stylesheet /path/to/stylesheet.xsl;
}
Lua模块
使用ngx_lua模块可以编写高性能的应用程序,无需将逻辑传递给upstream server
OpenResty
- OpenResty 是一个基于 Nginx 的全功能 Web 应用服务器,是ngnix的增强版。
- OpenResty 将 Nginx 作为其核心引擎,自带Lua。
- Nginx使用Lua模块需要先下载Lua模块,并在编译时使用--add-module=/path/to/lua-nginx-module
动态生成内容
通过 Lua 脚本可以在 nginx 中动态生成内容,比如基于请求的特定条件生成响应内容。
location /lua {
default_type 'text/plain';
content_by_lua_block {
ngx.say("Hello, world!")
}
}
# 当访问/lua路径时,nginx将执行Lua脚本ngx.say("Hello, world!")并将输出发送给客户端。
请求路由
基于请求的内容或其他条件将请求分发到不同的后端服务器
# 指定查找lua脚本的位置
lua_package_path '/path/to/lua-scripts/?.lua;;';
server {
location /route {
access_by_lua_block {
if ngx.var.arg_version == "v1" then
ngx.var.backend = "http://backend_v1"
else
ngx.var.backend = "http://backend_v2"
end
}
proxy_pass $backend;
}
}
生产例子
假设我们有两个后端服务器,一个位于美国,另一个位于欧洲。我们想要根据用户的 IP 地址将请求路由到相应的服务器上。
# 首先,安装lua-resty-iputils库来解析IP地址的地理位置信息
luarocks install lua-resty-iputils
# 配置 nginx,将 Lua 模块与 IP 地址解析库集成,并根据解析的地理位置信息来路由请求
lua_package_path "/usr/local/lib/lua/?.lua;;";
resolver 8.8.8.8;
lua_shared_dict geo_data 10m;
server {
listen 80;
server_name example.com;
location / {
access_by_lua_block {
local geoip = require "resty.iputils"
local country = geoip.lookup_originating_country()
if country == "US" then
ngx.var.backend = "http://us_backend"
elseif country == "EU" then
ngx.var.backend = "http://eu_backend"
else
ngx.var.backend = "http://default_backend"
end
}
proxy_pass $backend;
}
}
示例说明:
1、使用 lua_shared_dict 定义了一个共享内存区域 geo_data 用于缓存 IP 地址的地理位置信息。
2、通过 resty.iputils 库的 lookup_originating_country() 函数获取用户的地理位置信息,
并根据不同的地理位置将请求路由到不同的后端服务器。
3、如果无法解析地理位置信息或者用户位于其他地区,则请求将路由到默认的后端服务器。
nginx中的Lua API 命令
ngx.var.VARIABLE
获取 nginx 内置变量的值。
常用的内置变量包括 $remote_addr(客户端 IP 地址)、$request_uri(请求的 URI)、$http_user_agent(客户端的 User-Agent 等)。
这个命令允许你在 Lua 脚本中访问这些变量的值,并根据它们进行逻辑判断。
ngx.req.get_uri_args()
获取请求的 URI 参数。
这个命令返回一个 Lua table,其中包含了请求 URI 中的所有参数及其对应的值。
你可以在 Lua 脚本中使用它来处理请求中的参数信息。
ngx.req.set_uri_args(args_table)
设置请求的 URI 参数。
这个命令允许你在 Lua 脚本中修改请求的 URI 参数,可以用于重写请求参数或者添加新的参数。
ngx.req.get_headers()
获取请求头信息。这个命令返回一个 Lua table,其中包含了请求的所有头部信息。
你可以在 Lua 脚本中使用它来获取请求头中的特定信息,比如 User-Agent、Host 等。
ngx.req.set_header(header_name, header_value)
设置请求头信息。这个命令允许你在 Lua 脚本中修改请求的头部信息,
可以用于添加新的头部信息或者修改已有的头部信息。
ngx.say(...)
输出内容到响应体。这个命令允许你在 Lua 脚本中向客户端发送响应内容,可以是字符串、数字等。
ngx.exit(status)
终止请求处理并发送指定的 HTTP 状态码给客户端。
这个命令允许你在 Lua 脚本中根据某些条件直接终止请求处理,并返回指定的状态码给客户端。
ngx.redirect(uri, status)
重定向请求到另一个 URI。这个命令允许你在 Lua 脚本中进行重定向操作,
可以指定重定向的目标 URI 和 HTTP 状态码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通