文章目录
- 一、Nginx高级设置
- Nginx状态页
- Nginx第三方模块
- Nginx变量使用
- 内置变量
- 自定义变量
- Nginx自定义访问日志
- 自定义默认格式日志
- 自定义json格式日志
- Nginx压缩功能
- https功能
- https配置参数
- 自签名证书
- 虚拟主机
- 二、Nginx代理服务
- 三、代理服务常见模式
- 四、Nginx代理服务支持协议
- 五、Nginx反向代理配置语法
- 六、Nginx反向代理场景实践
一、Nginx高级设置
Nginx状态页
基于nginx模块ngx_http_stub_status_module实现,在编译安装nginx的时候需要添加编译参数–with-http_stub_status_module,否则配置完成之后监测会是提示语法错误
注意:状态页显示的是整个服务器的状态,而非虚拟主机的状态
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location /nginx_status {
stub_status on;
auth_basic "auth login";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}
http://file.test.com/nginx_status
- Active connections:2表示Nginx正在处理的活动连接数2个。
- server 2 表示Nginx启动到现在共处理了2个连接
- accepts 2 表示Nginx启动到现在共成功创建2次握手
- handled requests 1 表示总共处理了1次请求
- Reading:Nginx读取到客户端的Header信息数,数值越大,说明排队越长,性能不足
- Writing:Nginx返回给客户端Header信息数,数值越大,说明访问量越大
- Waiting:Nginx已经处理完正在等候下一次请求指令的驻留链接(开启keep-alive的情况下,这个值等于Active-(Reading+Writing))
Nginx第三方模块
第三模块是对nginx的功能扩展,第三方模块需要在编译安装Nginx的时候使用参数–add-module=PATH指定路径添加,有的模块是由公司的开发人员针对业务需求定制开发的,有的模块是开源爱好者开发好之后上传到github进行开源的模块,nginx支持第三方模块需要从源码重新编译支持,比如:开源的echo模块https://github.com/openresty/echo-nginx-module
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location /main {
index index.html;
default_type text/html;
echo "hello world,main-->";
echo $remote_addr;
echo_reset_timer; # 将计时器开始时间重置为当前时间
echo_location /sub1;
echo_location /sub2;
echo "took $echo_timer_elapsed sec for total.";
}
location /sub1 {
echo_sleep 2;
echo hello;
}
location /sub2 {
echo_sleep 1;
echo world;
}
[root@localhost src]# wget https://github.com/openresty/echo-nginx-module/archive/refs/heads/master.zip
[root@localhost src]# unzip master.zip
[root@localhost src]# mv echo-nginx-module-master echo-nginx-module
[root@localhost src]# cd nginx-1.18.0
[root@localhost nginx-1.18.0]# ./configure --prefix=/apps/nginx \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--with-http_gzip_static_module \
--with-prce \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-file-aio \
--add-module=/usr/local/src/echo-nginx-module
[root@localhost nginx-1.18.0]# make -j 2 && make install
http://file.test.com/main
Nginx变量使用
nginx的变量可以在配置文件中应用,作为功能判断或者日志等场景使用
变量可以分为内置变量和自定义变量
内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问的相关的值
内置变量
官方文档:https://nginx.org/en/docs/varindex.html
常用内置变量
$remote_addr;
# 存放了客户端的地址,注意是客户端的公网IP
$proxy_add_x_forwarded_for;
# 此变量表示将客户端IP追加请求报文中X-Forwarded-For首字母段,多个IP之间用逗号分割,如果请求中没有X-Forwarded-For,就使用$remote_addr
$args;
# 变量中存放了URL中的参数
$document_root;
# 保存了正对当前资源的系统根目录
$document_uri;
# 保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比如/img/logo.png
$host;
# 存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
# 如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果媒体设置,则显示0
$remote_port;
# 客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_body_file;
# 做反向代理时发给后端服务器的本地资源的名称
$request_method
# 请求资源的方式,GET/PUT等等
$request_filename
# 当前请求的资源文件的磁盘路径,由root或alias指令与URL请求生成的文件绝对路径
# /apps/nginx/html/www/index.html
$request_uri;
# 包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args
$scheme;
# 请求的协议,例如:http,https,ftp等等
$server_protocol;
# 保存了客户端请求资源的使用的协议版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等等
$server_addr;
# 保存了服务器的IP地址
$server_name;
# 请求的服务器的主机名
$server_port;
# 请求的服务器的端口号
$http_<name>
# name为任意请求报文首部字段,表示记录请求报文的首部字段
$http_user_agent;
# 客户端浏览器的详细信息
$http_cookie;
# 客户端的cookie信息
$cookie_<name>;
# name为任意请求报文首部字段cookie的key名
自定义变量
假如需要自定义变量名和值,使用指令set $variable value;
语法格式:
Syntax:Set $variable value;
Default: -
Context: server, location, if
范例:
[root@localhost ~]# vim /apps/nginx/conf.d/www.conf
location {
set $name zs;
echo $name;
set $my_port $server_port;
echo $my_port;
echo "$server_name:$server_port";
}
Nginx自定义访问日志
访问日志是记录客户端即用户的具体请求内容信息,全局配置模块中的error_log是记录nginx服务器允许时的日志保存路径和记录日志的level,因此有着本质的区别,而且Nginx的错误日志一般只有一个,但是访问日志可以在不同server中定义多个,定义一个日志需要使用access_log指定日志的保存路径,使用log_format指定日志的格式,格式中定义要保存的具体日志内容。
访问日志由ngx_http_log_module模块实现
语法格式:
Syntax: access_log path [format [buffer=size] [gzip [=level]] [flush=time] [if=condition]];
access_log off;
Default:
access_log logs/access.log combined;
Context: http, server, location, if in location, limit_excepts
自定义默认格式日志
如果虚脱保留日志的源格式,至少添加相应的日志内容,则配置如下:
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
log_fomat nginx_format1 '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$server_name:$server_port';
access_log logs/access.log nginx_format1;
# 重启nginx并访问测试日志格式
# /apps/nginx/logs/access.log
自定义json格式日志
Nginx的默认访问日志记录内容相对比较单一,默认的格式也不方便后期做日志统计分析,生产环境中通常将nginx日志转换为json日志,然后配合使用ELK做日志收集-统计-分析。
log_format access_json '{"@timestamp":"$time_iso8601",'
'"host":"$server_addr",'
'"Clientip":"$remote_addr",'
'"size":$body_bytes_sent,'
'"responsetime":$request_time,'
'"upstreamhost":"$upstream_response_time",'
'"upstreamhost":"$upstream_addr",'
'"http_host":"$host",'
'"uri":"$uri",'
'"xff":"$http_x_forwarded_for",'
'"tcp_xff":"$proxy_protocol_addr",'
'"status":"$status"}';
access_log logs/access.log access_json
Nginx压缩功能
Nginx支持对指定类型的文件进行压缩,然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,不过会占用相应的CPU资源。
Nginx对文件的压缩功能是依赖于模块ngx_http_gzip_module
官方文档:https://nginx.org/en/docs/http/ngx_http_gzip_module.html
# 启用或禁用gzip压缩,默认关闭
gzip on | off;
# 压缩比由低到高1到9,默认为1
gzip_comp_level level;
# 禁用IE6 gzip功能
gzip_disable "MSIE [1-6]\.";
# gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
# 启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
# 指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
# 指明进队哪些类型的资源指向压缩操作,默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
# 如果启用压缩,是否再相应报文首部插入"vary: Accept-Encoding",一般建议打开
gzip_vary on | off
# 重启nginx并进行访问测试压缩功能
[root@localhost ~]# curl -I --compressed servername
https功能
https配置参数
nginx的https功能基于模块ngx_http_ssl_module实现,因此如果是编译安装的nginx要使用参数ngx_http_ssl_module开启ssl功能,但是作为nginx的核心功能,yum安装的nginx默认就是开启的,编译安装的nginx需要指定编译参数–with-http_ssl_module开启
官方文档:https://nginx.org/en/docs/http/ngx_http_ssl_module.html
配置参数如下:
ssl on | off;
listen 443 ssl;
# 为指定的虚拟主机配置是否启用ssl功能,此功能再1.15.0废弃,使用listen [ssl]替代。
ssl_certificate_key /path/to/file;
# 当前虚拟主机使用的公钥文件,一般是crt文件
ssl_cerificate_key /path/to/file;
# 当前虚拟主机使用的私钥文件,一般是key文件
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
# 支持ssl协议版本,早期为ssl现在是TSL,默认为后三个
ssl_session_cache off | none | [builtin[:size]] [shared:name:size];
# 配置ssl缓存
off
# 关闭缓存
none:
# 通知客户端支持ssl session cache,但实际不支持
builtin[:size]:
# 使用OpenSSL内建缓存,为每worker进程私有
[shared:name:size]
# 在各worker之间使用一个共享的缓存,需要定义一个缓存名称和缓存空间大小,一兆可以存储4000多个会话信息,多个虚拟主机可以使用相同的缓存名称
ssl_session_timeout time;
# 客户端连接可以复用ssl session cache中缓存的有效时长,默认5m
自签名证书
- 生成ca证书
cd /apps/nginx
mkdir certs && cd certs
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ca.key -x509 -days 3650 - out ca.crt
- 生成证书请求文件
openssl req -newkey rsa:4096 -nodes -sha256 -keyout iproute.cn.key -out iproute.cn.csr
- 签发证书
openssl x509 -req -days 36500 -in iproute.cn.csr -CA ca.crt -CAkey ca.key - CAcreateserial -out iproute.cn.crt
cat iproute.cn.crt ca.crt > iproute.crt
- 验证证书内容
openssl x509 -in iproute.cn.crt -noout -text
- 证书配置,在nginx的主配置文件中写
[root@localhost ~]# vim /apps/nginx/conf/nginx.conf
server {
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/certs/iproute.crt;
ssl_certificate_key /apps/nginx/certs/iproute.cn.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
root /apps/nginx/html;
}
虚拟主机
[root@localhost ~]# ll /apps/nginx/conf.d
总用量 12
-rw-r--r--. 1 root root 107 9月 25 16:45 bbs.conf
-rw-r--r--. 1 root root 109 9月 25 16:45 blog.conf
-rw-r--r--. 1 root root 107 9月 25 16:44 www.conf
[root@localhost conf.d]# cat *.conf
server {
listen *:8080;
server_name bbs.eagle.com;
location / {
root /apps/nginx/html/bbs;
index index.html;
}
}
server {
listen *:8080;
server_name blog.eagle.com;
location / {
root /apps/nginx/html/blog;
index index.html;
}
}
server {
listen *:8080;
server_name www.eagle.com;
location / {
root /apps/nginx/html/www;
index index.html;
}
}
二、Nginx代理服务
- 代理一次往往并不模式,该服务我们常常用到如(代理理财,代理租房,代理收货等等)
租房—>中介—>房源
- 在没有代理模式的情况下,客户端和Nginx服务端,都是客户端直接请求服务端,服务端直接响应客户端
- 那么在互联网请求里,客户端往往无法直接向服务端发起请求,那么就需要用到代理服务,来实现客户端和服务通信
三、代理服务常见模式
- Nginx作为代理服务,按照应用场景模式进行总结,代理分为正向代理、反向代理
- 正向代理与反向代理的区别
- 区别在于形式上服务的”对象“不一样
- 正向代理代理的对象是客户端,为客户端服务
- 反向代理代理的对象是服务端,为服务端服务
四、Nginx代理服务支持协议
-
Nginx作为代理服务,可支持的代理协议非常的多
-
如果将Nginx作为反向代理服务,常常会用到如下几种代理协议
五、Nginx反向代理配置语法
- 代理配置语法
Syntax: proxy_pass URL;
Default: —
Context: location, if in location, limit_except
http://localhost:8000/uri/
http://192.168.56.11:8000/uri/
http://unix:/tmp/backend.socket:/uri/
- 添加发往后端服务端请求头信息
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http, server, location
# 用户请求的时候HOST的值是www.eagleslab.com, 那么代理服务会像后端传递请求的还是eagleslab
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- 代理到后端的TCP连接、响应、返回等超时时间
//nginx代理与后端服务器连接超时时间(代理连接超时) # 去饭店
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
//nginx代理等待后端服务器的响应时间 # 点菜
Syntax: proxy_read_timeout time;
Default: proxy_read_timeout 60s;
Context: http, server, location
//后端服务器数据回传给nginx代理超时时间 # 等上菜菜
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
- proxy_buffer代理缓冲区
# nginx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传,不是全部接受完再传给客户端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;
Context: http, server, location
# 设置nginx代理保存用户头信息的缓冲区大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
# proxy_buffers 缓冲区
# 为每个连接设置缓冲区数量为number,每块缓冲区的大小为size,这些缓冲区用于保存从代理的服务器读取的响应。
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
- 常用优化配置
- Proxy代理网站常用优化配置如下,将配置写入新文件,调用时使用include即可
[root@localhost ~]# vim /etc/nginx/proxy_params
proxy_set_header Host $proxy_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
proxy_buffering on;
proxy_buffer_size 32k;
proxy_buffers 4 128k;
- 重复使用配置
- 代理配置location时调用方便后续多个Location重复使用
location / {
proxy_pass http://127.0.0.1;
include proxy_params;
}
六、Nginx反向代理场景实践
- Nginx反向代理配置实例
- 客户端请求反向代理80端口,反向代理web02代理后向后端转发请求,转发至后端的8080端口,服务端web01处理之后向代理服务器返回结果
- web01服务器配置一个网站,监听在8080端口
[root@web01 ~]# vim /etc/nginx/conf.d/web.conf
server{
listen 8080;
server_name localhost;
location / {
root /code/8080
index index.html;
allow all;
}
}
[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl restart nginx
[root@web01 ~]# mkdir -p /code/8080
[root@web01 ~]# echo "listening 8080..." > /code/8080/index.html
- proxy代理服务,配置监听80端口,使能够通过代理服务器访问到后端的8080端口内容
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
listen 80;
server_name proxy.test.com;
location / {
proxy_pass http://192.168.64.129:8080;
}
}
[root@web02 ~]# nginx -t
[root@web02 ~]# systemctl restart nginx
- 存在的问题,通过抓包可以看到客户端是使用域名对网站进行访问的,但是代理却是使用的IP地址加端口号
- 当访问80端口的时候,没有域名的情况下,默认会去找排在最上面的那个配置文件。
- 所以我们需要解决这个问题,保留住最开始的请求头部信息。
- 并且发现我们向代理服务器发起的http是1.1但是代理向web服务器发起的是1.0,1.0不支持长链接,解决这个问题就指定协议版本
- 修改配置文件,使用proxy_set_header模块
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
listen 80;
server_name proxy.test.com;
location / {
proxy_pass http://192.168.64.129:8080;
proxy_set_header Host $proxy_host;
}
}
- 使用http1.1协议
[root@web02 ~]# vim /etc/nginx/conf.d/proxy_web_node1.conf
server{
listen 80;
server_name proxy.test.com;
location / {
proxy_pass http://192.168.64.129:8080;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
}
}
- 在生产环境中,我们必须要记录客户端的来源IP,如果所有的访问日志,全部都来源于代理,那么我们根本不知道有哪些地区的用户访问了我们什么页面。
- 还需要使用proxy_set_header
server{
listen 80;
server_name proxy.test.com;
location / {
proxy_pass http://192.168.64.129:8080;
proxy_set_header Host $proxy_host;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}