Nginx----高性能的WEB服务端(二)

一、高级配置

1、网页的状态页

基于nginx 模块 ngx_http_stub_status_module 实现,在编译安装nginx的时候需要添加编译参数 --with-http_stub_status_module,否则配置完成之后监测会是提示语法错误注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态

[root@localhost conf.d]#vim pc.conf 
server{
	listen 80;
	server_name www.lucky.com;
	root /data/html/;
	location /admin {
	auth_basic "welcome 999";                 ##提示信息,不是所有的浏览器都有用
    auth_basic_user_file /mnt/.nginxuser;     ##密码文件存放位置	
	}
	location /status {
	stub_status;
	}
}
 
[root@localhost conf.d]#nginx -t
 
[root@localhost conf.d]#nginx -s reload

其余的参考上篇文章 

2、Nginx第三方模块

1.echo模块

开源的echo模块 GitHub - openresty/echo-nginx-module: An Nginx module for bringing the power of "echo", "sleep", "time" and more to Nginx's config file

[root@localhost conf.d]#vim /apps/nginx/conf.d/pc.conf
server{
	listen 80;
	server_name www.lucky.com;
	root /data/html/;

	location /ip {
	echo "welcome,your ip addr:";
	echo $remote_addr;
	}
}

[root@localhost conf.d]#nginx -t          ###如果没有安装第三方模块是会报错的


添加echo第三方模块后检查语法是否出错

3、变量

官方文档    http://nginx.org/en/docs/varindex.html

1.内置变量

常用的内置变量

$remote_addr; 
#存放了客户端的地址,注意是客户端的公网IP
 
 
$proxy_add_x_forwarded_for
#此变量表示将客户端IP追加请求报文中X-Forwarded-For首部字段,多个IP之间用逗号分隔,如果请求中没有X-Forwarded-For,就使用$remote_addrthe “X-Forwarded-For” client request header field with the $remote_addr variable appended to it, separated by a comma. If the “X-Forwarded-For” field is not present in the client request header, the $proxy_add_x_forwarded_for variable is equal to the $remote_addr variable.
客户机    代理1     代理2     nginx服务器
$proxy_add_x_forwarded_for: 在代理1 上存的是  客户机的ip
$proxy_add_x_forwarded_for: 在代理2 上存的是  客户机的ip,代理1的ip            用逗号隔开
$proxy_add_x_forwarded_for: nginx  上存的是  客户机的ip,代理1的ip,代理2的ip
 
 
 
$args; 
#变量中存放了URL中的参数,例如:http://www.kgc.org/main/index.do?id=20190221&partner=search
#返回结果为: id=20190221&partner=search    存放的就是这个
 
select   *  from table  where id=20190221
 
 
$document_root; 
#保存了针对当前资源的请求的系统根目录,例如:/apps/nginx/html
 
 
 
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令,比
如:http://www.kgc.org/main/index.do?id=20190221&partner=search会被定义为/main/index.do 
#返回结果为:/main/index.do
 
 
$host; 
#存放了请求的host名称
 
 
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
 
 
$remote_port; 
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
 
$remote_user; 
#已经经过Auth Basic Module验证的用户名
 
$request_body_file; 
#做反向代理时发给后端服务器的本地资源的名称
 
$request_method; 
#请求资源的方式,GET/PUT/DELETE等
 
$request_filename; 
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,如:/apps/nginx/html/main/index.html
 
$request_uri;   https:// www.baidu.com/main/index.do?id=20190221&partner=search 
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,例如:/main/index.do?id=20190221&partner=search 
 
$scheme; 
#请求的协议,例如:http,https,ftp等
 
$server_protocol; 
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
 
$server_addr; 
#保存了服务器的IP地址
 
$server_name; 
#请求的服务器的主机名
 
$server_port;  443  https 
#请求的服务器的端口号
 
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段
arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores 
#用下划线代替横线
#示例: echo $http_User_Agent;  
 
$http_user_agent; 
#客户端浏览器的详细信息
 
$http_cookie; 
#客户端的cookie信息
 
 
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
 
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
arbitrary request header field; the last part of a variable name is the field 
name converted to lower case with dashes replaced by underscores #用下划线代替横线
#示例: 
echo $http_user_agent; 
echo $http_host;
 
 
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有问题
echo $sent_http_server;
 
 
 
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
#对比 变量  $arg  是全部, 如果 要id   如下
echo $arg_id;

实验:变量

[root@localhost conf.d]#vim /apps/nginx/conf.d/pc.conf
server{
	listen 80;
	server_name www.lucky.com;
	root /data/html/;

	location /ip {
	echo "welcome,your ip addr:";
	echo $remote_addr;
	}

	location /main {
	index index.html;
	default_type text/html;
	echo "hello world,main-->";
	echo $remote_addr;
	echo $args;
	echo $arg_user;
	echo $document_root;
	echo $document_uri;
	echo $host;
	echo $http_user_agent;
	echo $http_cookie;
	echo $request_filename;
	echo $scheme;
	echo $scheme://$host$document_uri?$args;
	}
}

[root@localhost conf.d]#nginx -t


[root@localhost conf.d]#nginx -s reload

测验:

2.自定义变量

假如需要自定义变量名称和值,使用指令set $variable value;

语法格式:

Syntax: set $variable value;
Default: —
Context: server, location, if    #可以放置的位置
server{
	listen 80;
	server_name www.lucky.com;
	root /data/html;

	location /ip {
	echo "welcome,your ip addr:";
	echo $remote_addr;
	}
###############内置变量#####################
	location /main {
	index index.html;
	default_type text/html;
	echo "hello world,main-->";
	echo $remote_addr;
	echo $args;
	echo $arg_user;
	echo $document_root;
	echo $document_uri;
	echo $host;
	echo $http_user_agent;
	echo $http_cookie;
	echo $request_filename;
	echo $scheme;
	echo $scheme://$host$document_uri?$args;
	}
#########################################

#############自定义变量##################
	location /test {
	set $name  kkk;
	echo $name;
	set $my_port $server_port;
	echo $my_port;
	}
#############################
}

4、自定义访问日志

如果访问出错---404,可以去看日志信息cat /apps/nginx/logs/error.log

1.日志的格式 可以自由指定

访问日志是记录客户端即用户的具体请求内容信息,而在全局配置模块中的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;
Defau1t:
access_log 1ogs/access.1og combined;
Context: http,server, location,if in location,limit_except
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                      '$server_name:$server_port';
 
 
log_format  test  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"'
                      '$server_name:$server_port';
 
格式可以定义多个
 
###注意如果开启 include  注意定义自配置文件与 日志格式的上下关系  ,   日志格式一定要在  include 之前 否则会不生效。

注意如果开启 include  注意定义自配置文件与 日志格式的上下关系  ,日志格式一定要在  include 之前 否则会不生效。

2.自定义json格式日志

方便ELK收集日志

vim   /apps/nginx/conf/nginx.conf

log_format access_json '{"@timestamp":"$time_iso8601",'
        '"host":"$server_addr",'
        '"clientip":"$remote_addr",'
        '"size":$body_bytes_sent,'
        '"responsetime":$request_time,'
        '"upstreamtime":"$upstream_response_time",'
        '"upstreamhost":"$upstream_addr",'  
        '"http_host":"$host",'
        '"uri":"$uri",'
        '"xff":"$http_x_forwarded_for",'
        '"referer":"$http_referer",'
        '"tcp_xff":"$proxy_protocol_addr",'
        '"http_user_agent":"$http_user_agent",'
        '"status":"$status"}';

提取状态码

3.日志分割

nginx的日志是生成在安装目录下/usr/local/nginx/logs中,大量的日志如果不做良好的管理,长此以往会造成日志文件过大且日志分析困难

----------------日志切割-------------------
vim /opt/fenge.sh
#!/bin/bash
# Filename: fenge.sh
day=$(date -d "-1 day" "+%Y%m%d")											#显示前一天的时间
logs_path="/var/log/nginx"
pid_path="/usr/local/nginx/logs/nginx.pid"
[ -d $logs_path ] || mkdir -p $logs_path 									#创建日志文件目录
mv /usr/local/nginx/logs/access.log ${logs_path}/kgc.com-access.log-$day	#移动并重命名日志文件
kill -USR1 $(cat $pid_path)													#重建新日志文件
find $logs_path -mtime +30 -exec rm -rf {} \;								#删除30天之前的日志文件
#find $logs_path -mtime +30 | xargs rm -rf 
 
 
 
chmod +x /opt/fenge.sh
/opt/fenge.sh
ls /var/log/nginx
ls /usr/local/nginx/logs/access.log 
 
#设置周期计划任务
crontab -e
0 1 * * * /opt/fenge.sh

编写日志分割的脚本
#!/bin/bash
#this is used for cutting nginx logs 
##定义日志收集的目录
newlogpath=/var/log/nginx
##定义区分日志的标识,采用时间标记,计划每天一次日志分割
lastday=`date -d "-1 day" +%Y%m%d`
##找到应用程序生成日志的源路径
oldlogpath=/usr/local/nginx/logs
##定义应用程序的pid号 也就是nginx的master进程号
pid=`cat ${oldlogpath}/nginx.pid`
 
##先判断收集日志的目录是否存在,没有则创建,有则进行下一步
[ -d $newlogpath ]||mkdir $newlogpath
 
##使用mv命令进行日志分割,将生成的访问日志和错误日志都移动到收集日志的目录下,并添加时间标记
mv $oldlogpath/access.log $newlogpath/access.log.$lastday
mv $oldlogpath/error.log $newlogpath/error.log.$lastday
 
##重新生成新的日志,便于nginx记录后续访问事务
kill -USR1 $pid
 
##删除大于30天的日志,释放磁盘空间
find $newlogpath -mtime +30 -exec rm -rf {} \;
 
chmod +x ~/nginx_log.sh
crontab -e
0 0 * * * ~/nginx_log.sh

 面试:你写过那些脚本?

一键安装及脚本

日志分割

系统调优

自动检测系统性能

 5、Nginx压缩功能

支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,这样有助于降低出口带宽的利用率,降低企业的IT支出,不过会占用相应的CPU资源。  gzip不支持压缩图片

Nginx对文件的压缩功能  是依赖于模块 ngx_http_gzip_module
允许Nginx服务器将输出内容在发送客户端之前进行压缩,以节约网站带宽,提升用户的访问体验,默认已经安装,可在配置文件中加入相应的压缩功能参数对压缩性能进行优化

官方文档: Module ngx_http_gzip_module

#启用或禁用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;
 
#预压缩,先压缩好,不用临时压缩,消耗cpu
gzip_static on | off;

1.gzip压缩

   gzip on;
   gzip_comp_level 9;
   gzip_min_length 1k;
   gzip_vary on;
   gzip_static on;

文件中写入一些东西 

写配置文件

curl 是文字浏览器不压缩

去浏览器访问

点到空白处,鼠标右击,检查 或者按F12

304这里是缓存,再次强刷按ctrl进行出现 200就好了 

 favicon.ico表示的是网站的小图标,是不压缩的

太小的文件没必要压缩,压缩说不定变大

2.gzip预压缩

[root@localhost ~]#vim /apps/nginx/conf.d/pc.conf
server{
	listen 80;
	server_name www.lucky.com;
	root /data/html;
	gzip on;
	gzip_comp_level 9;
	gzip_min_length 1k;
	gzip_vary on;
	gzip_static on;
	location /ip {
	echo "welcome,your ip addr:";
	echo $remote_addr;
	}
}

[root@localhost ~]#nginx -t

[root@localhost ~]#nginx -s reload

浏览器访问

强刷

  gzip不支持压缩图片  curl 不支持压缩

6、https功能

Web网站的登录页面都是使用https加密传输的,加密数据以保障数据的安全,HTTPS能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议,HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。

过程:

1.客户端发起HTTPS请求
用户在浏览器里输入一个 https 网址,然后连接到服务器的 443 端口。

2.服务端的配置
采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥。

3.传送服务器的证书给客户端
证书里其实就是公钥,并且还包含了很多信息,如证书的颁发机构,过期时间等等。

4.客户端解析验证服务器证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如:颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框提示证书存在问题。如果证书没有问题,那么就生成一个随机值,然后用证书中公钥对该随机值进行非对称加密。

5.客户端将加密信息传送服务器
这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加感解密了。

6. 服务端解密信息
服务端将客户端发送过来的加密信息用服务器私钥解密后,得到了客户端传过来的随机值。

7.服务器加密信息并发送信息
服务器将数据利用随机值进行对称加密,再发送给客户端。

8.客户端接收并解密信息
客户端用之前生成的随机值解密服务段传过来的数据,于是获取了解密后的内容。

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;   
#为指定的虚拟主机配置是否启用ssl功能,此功能在1.15.0废弃,使用listen [ssl]替代
listen 443 ssl;
 
ssl_certificate /path/to/file;
#指向包含当前虚拟主机和CA的两个证书信息的文件,一般是crt文件
 
ssl_certificate_key /path/to/file;
#当前虚拟主机使用的私钥文件,一般是key文件
 
ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]; 
#支持ssl协议版本,早期为ssl现在是TLS,默认为后三个
 
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

因为http是用明文传输的,只要抓包,直接获取你的用户名和密码,所以ssl很重要

1.自签名证书

#所有的证书需要放在一起不能移开
 
bash certificate.sh
 
cat kgc.com.crt ca.crt > www.kgc.com.crt
#kgc.com.crt(购买者)
#ca.crt(颁发者)
 
mv kgc.com.key  www.kgc.com.key
#www.kgc.com.key(验证钥匙)

 证书查看 查看jd的证书

实验:自签名证书

进入配置文件

[root@localhost ssl]#vim /apps/nginx/conf.d/pc.conf
server{
	listen 80;
	listen 443 ssl;
	root /data;
	server_name www.kgc.com;
	ssl_certificate /data/ssl/www.kgc.com.crt;
	ssl_certificate_key /data/ssl/www.kgc.com.key;
	ssl_session_cache shared:sslcache:20m;
	ssl_session_timeout 10m;
}

[root@localhost ssl]#nginx -t

[root@localhost ssl]#nginx -s reload

浏览器访问

7、自定义图标

favicon.ico 文件是浏览器收藏网址时显示的图标,当客户端使用浏览器问页面时,浏览器会自己主动发起请求获取页面的favicon.ico文件,但是当浏览器请求的favicon.ico文件不存在时,服务器会记录404日志,而且浏览器也会显示404报错。

【自定义小图标】
wget www.baidu.com/favicon.ico
放到主目录就可以了

不生效可以重新打开浏览器

实验:定义百度图标

浏览器检测:

京东小图标

二、重写功能   rewrite

重写功能(rewrite)用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,另外还可以在一定程度上提高网站的安全性。

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之一用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性

1、ngx_http_rewrite_module模块指令

官方文档: https://nginx.org/en/docs/http/ngx_http_rewrite_module.html

1.if指令

官方文档:https://nginx.org/en/docs/http/ngx_http_rewrite_module.html#if

用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:

if (条件匹配) {   
 action
}

使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:

​
=  #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!=  #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~  #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
 
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
 
 
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
举例:
location /main {
     index index.html;
     default_type text/html;
#定义文件类型
     if ( $scheme = http ){
#如果用户访问的协议是http,$scheme变量表示用户来访问使用的协议。       
    echo "if-----> $scheme";
#则输出if --->协议 
    }
     if ( $scheme = https ){
#如果用户访问的协议是https,$scheme变量表示用户来访问使用的协议。 
      echo "if ----> $scheme";
#则输出if --->协议 
   }

举例:

检测:

2.return

return用于完成对请求的处理,并直接向客户端返回响应状态码,比如:可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return可以在server、if 和 location块进行配置

语法格式:

www.kgc.com/test/
404
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; #返回给客户端的URL地址 

3字打头重定向
301  永久重定向  将缓存记录在浏览器中
302  临时重定向  没有缓存  每次都要重定向 

301:永久重定向 (读取过一次,会将配置缓存在客户端;即使Nginx服务器宕机,在缓存时间内也可以跳转)

302:临时重定向 (不会存在客户端;每次跳转页面,都要问一遍服务器,然后解析;一旦服务器宕机,就无法跳转)

测试:当用户不存在时跳转  302

nginx宕机了,那么就访问不了了

测试:当用户不存在时跳转     301

配置文件

当我们访问页面存在时,状态码为301 

再去浏览器访问查看是可以调过来的

简述Nginx  301  和  302  重定向 及其区别

301:永久重定向 (读取过一次,会将配置缓存在客户端;即使Nginx服务器宕机,在缓存时间内也可以跳转)

302:临时重定向 (不会存在客户端;每次跳转页面,都要问一遍服务器,然后解析;一旦服务器宕机,就无法跳转)

  • 27
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值