文章目录
- 一、显示乱码问题
- 二、index显示列表
- 三、location语法
- 3.1 URI URL URN简介
- 四、常用优化
- 4.1 网络连接优化
- 4.2 Nginx版本号隐藏
- 4.3 选择事件驱动模型
- 4.3.1 select pool epoll 详解
- 4.4 配置单个工作进程的最大连接数
- 4.5 配置允许sendfile方式传输文件
- 4.6 会话保持
- 4.7 配置Nginx worker进程最大打开文件数
- 4.8 配置Nginx gzip压缩实现性能优化
- 4.9 nginx expires功能
- 五、常用正则(Nginx配置文件)
- 六、rewrite实例
- 七、if语句模块
- 八、https
- 九、PHP后端处理(fastcgi)
- 十、负载均衡和反向代理
一、显示乱码问题
server {
listen 80;
server_name example.com;
root /var/www/example;
location /{
charset utf-8; #一般是在个别的location中加入此项,具体情况需要具体对待
rewrite .* /index.html break;
}
}
二、index显示列表
- 一般为企业内部使用
可在location server 或 http段中加入
autoindex on #自动显示目录
autoindex_exact_size off; #人性化方式显示文件否则以byte(字节)显示
autoindex_localtime on; #按服务器时间显示,否则以gmt时间显示
#gmt时间:格林威治中央区时,北京时间=gmt时间+8小时
三、location语法
=:对URI做精确匹配
location = / {
.....
}
~:对URI做正则表达式模式匹配,区分字符大小写
~*:对URI做正则表达式模式匹配,不区分字符大小写
^~: 对URI的左半部分做匹配检查,不区分大小写
不带符号:匹配起始于此uri的所有url
location /coco {
.....
}
例如www.example.com/coco/xxx/xxx
只要是路径以/coco开头的都会匹配,这种一般用于最后的同用匹配
- PS:匹配优先级:= ,^~ , /* ,不带符号
3.1 URI URL URN简介
URI可以分为URL、URN或同时具备locators 和names特性的一个东西。URN作用就好像一个人的名字,URL就像一个人的地址。换句话说:URN确定了东西的身份,URL提供了找到它的方式。
四、常用优化
4.1 网络连接优化
- 只能在events模块设置,用于防止在同一个时刻只有一个请求的情况下,出现多个睡眠进程会被唤醒 但只能有一个进程获得请求的情况,如果不优化,在多进程的Nginx会影响部分性能,示例:
events {
accept_mutex on;
}
#优化同一时刻只有一个请求而避免多个睡眠进程被唤醒的设置,on为防止被同时唤醒,默认为off,因此nginx刚安装完以后要进行适当的优化
4.2 Nginx版本号隐藏
- 当前使用的Nginx版本可能会有一些漏洞,如果被黑客利用将有可能造成无法估量的损失,此时需要进行Nginx版本号隐藏,示例:
server_tokens off
#在http模块中配置,可以在客户机(测试机)使用抓包工具验证
4.3 选择事件驱动模型
- Nginx支持多种事件驱动,如select、poll、epoll,只能设置在events模块中,示例:
events {
accept——mutex on;
multi_accept on;
use epoll; #使用epoll事件驱动,因为epoll的性能比其他事件驱动要好
}
4.3.1 select pool epoll 详解
- ① select
- 介绍:select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个**文件描述符(内核利用文件描述符赖访问文件)**的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作。
优点:
- 几乎支持所有平台,同时良好的跨平台支持也是其优点之一
缺点:
- 单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024 (可以通过修改宏定义或修改编译内核的方式提升最大数量)
- select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量TCP连接处于非活跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销
- ② pool
介绍:poll在1986年诞生于System V Release 3,它和select在本质上没有多大差别,但是poll没有最大文件描述符数量的限制 - 缺点:
- 包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大
select()和poll() 特点:
select()和poll()将就绪的文件描述符告诉进程后,如果进程没有对其进行IO操作,那么下次调用select()和poll()的时候将再次报告这些文件描述符,所以它们一般不会丢失就绪的消息,这种方式称为水平触发
- ③ epoll
介绍:直到Linux2.6才出现了由内核直接支持的实现方法,那就是epoll,它几乎具备了之前所说的一切优点,被公认为Linux2.6下性能最好的多路I/O就绪通知方法
特点:
- epoll可以同时支持水平触发和边缘触发(Edge Triggered,只告诉进程哪些文件描述符刚刚变为就绪状态,它只说一遍,如果我们没有采取行动,那么它将不会再次告知,这种方式称为边缘触发),理论上边缘触发的性能要更高一些,但是代码实现相当复杂
- epoll同样只告知那些就绪的文件描述符,而且当我们调用epoll_wait()获得就绪文件描述符时,返回的不是实际的描述符,而是一个代表就绪描述符数量的值,你只需要去epoll指定的一个数组中依次取得相应数量的文件描述符即可,这里也使用了内存映射(mmap)技术,这样便彻底省掉了这些文件描述符在系统调用时复制的开销。
- 另一个本质的改进在于epoll采用基于事件的就绪通知方式。在select/poll中,进程只有在调用一定的方法后,内核才对所有监视的文件描述符进行扫描,而epoll事先通过epoll_ctl()来注册一个文件描述符,一旦基于某个文件描述符就绪时,内核会采用类似callback的回调机制,迅速激活这个文件描述符,当进程调用epoll_wait()时便得到通知。
- 可以举一个小例子来概述以上事件驱动的特征
设定:每个学生的桌子上都有一个交卷信号灯
- select|poll机制就是 学生按一下灯老师就下去收卷子,但是需要一个个的去询问谁想交卷
- epoll机制就是 学生按一下灯老师不仅会收到交卷信号,还会知道交卷单位的信息,可以直接去目标地收卷子
4.4 配置单个工作进程的最大连接数
- 通过worker_connections number;进行设置,number为整数,number的值不能大于操作系统能打开的最大的文件句柄数,使用ulimit -n 可以查看当前操作系统支持的最大文件句柄数,默认为1024
- 文件句柄数:
很多项目上线不久后会突然宕机,在日志中可查看到出现too many open files
too many open files:顾名思义即打开过多文件数。
这里的files不单是文件的意思,也包括打开的通讯链接(比如socket),正在监听的端口等等,所以有时候也可以叫做句柄(handle),这个错误通常也可以叫做句柄数超出系统限制。
events {
worker_connections 102400;
}
#以上设置单个工作进程最大连接数为102400
4.5 配置允许sendfile方式传输文件
- 是由后端程序负责把源文件打包加密生成目标文件,然后程序读取目标文件返回给浏览器;这种做法有个致命的缺陷就是占用大量后端程序资源,如果遇到一些访客下载速度巨慢,就会造成大量资源被长期占用得不到释放(如后端程序占用的CPU/内存/进程等),很快后端程序就会因为没有资源可用而无法正常提供服务。通常表现就是 nginx报502错误,而sendfile打开后配合location可以实现有nginx检测文件使用存在,如果存在就有nginx直接提供静态文件的浏览服务,因此可以提升服务器性能
sendfile on;
# 可以配置在http、server或者location模块,配置如下:
sendfile_max_chunk 512k;
#Nginxg工作进程每次调用sendfile()传输的数据最大不能超出这个值,默认值为0表示无限制,可以设置在http/server/location模块中。
4.6 会话保持
- 用户和服务器建立连接后客户端分配keep-alive链接超时时间,服务器将在这个超时时间过后关闭链接,我们将它设置低些可以让ngnix持续工作的时间更长,1.8.1默认为65秒,一般不超过120秒。
keepalive_timeout 65 60;
#60为发送给客户端应答报文头部中显示的超时时间为60秒,如果不设置 客户端将不显示超时时间
keep-Alive;timeout=60
#浏览器收到的服务器返回的报文
#如果设置为0表示关闭会话保持功能,将如下显示:
Connection:close
#浏览器收到的服务器返回的报文
4.7 配置Nginx worker进程最大打开文件数
worker_rlimit_nofile 65535;
4.8 配置Nginx gzip压缩实现性能优化
- 图片、视频(流媒体)等文件尽量不要压缩,因为这些文件大多都是经过压缩的,如果再压缩很可能不会减小或减小很少,或者有可能增大,而在压缩时还会消耗大量的CPU、内存资源
gzip on;
#gzip on 表示开启压缩功能
gzip_min_length 1k;
#表示允许压缩的页面最小字节数,页面字节数从header头部的content-length中获取。默认值为0,表示不管页面多大都进行压缩,建议设置为大于1K,如果小于1k可能会越压越大
gzip_buffers 432k;
#压缩缓存区大小
gzip_http_version 1.1;
#压缩版本
gzip_comp_level 9;
#压缩比率
gzip_types text/css text/xml application/javascript;
#指定压缩类型
gzip_vary on;
#vary header支持
4.9 nginx expires功能
- 为用户访问网站的内容设定一个过期时间,当用户第一次访问到这些内容时,会把这些内容存储在用户浏览器本地,这样用户第二次及之后继续访问该网站,浏览器就会检查已经缓存在用户浏览器本地的内容,就不会去浏览器下载了。直到缓存的内容过期或者被清除为止。
## Add expires header according to URI(path or dir).
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
expires 360d;
}
五、常用正则(Nginx配置文件)
.:匹配除换行符意外的任意字符
?:重复0次或多次
+ :重复1次或多次
* :重复0次或多次
\d :匹配数字
^ : 匹配字符串的开始
$ : 匹配字符串的结束
{n} : 重复n次
{n,} : 重复n次或多次
[c] : 匹配单个字符c
[a-z] :匹配a-z小写字母的任意一个
- 类似分组():小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
六、rewrite实例
http {
# 定义image日志格式
log_format imagelog '[$time_local] ' $image_file ' ' $image_type ' ' $body_bytes_sent ' ' $status;
# 开启重写日志
rewrite_log on;
server {
root /home/www;
location / {
# 重写规则信息
error_log logs/rewrite.log notice;
# 注意这里要用‘’单引号引起来,避免{}
rewrite '^/images/([a-z]{2})/([a-z0-9]{5})/(.*)\.(png|jpg|gif)$' /data?file=$3.$4;
# 注意不能在上面这条规则后面加上“last”参数,否则下面的set指令不会执行
set $image_file $3;
set $image_type $4;
}
location /data {
# 指定针对图片的日志格式,来分析图片类型和大小
access_log logs/images.log mian;
root /data/images;
# 应用前面定义的变量。判断首先文件在不在,不在再判断目录在不在,如果还不在就跳转到最后一个url里
try_files /$arg_file /image404.html;
}
location = /image404.html {
# 图片不存在返回特定的信息
return 404 "image not found\n";
}
}
七、if语句模块
- 示例:
if ($http_user_agent ~ MSIE) {proxy_pass
rewrite ^(.*)$ /msie/$1 break;
}
#如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
#如果cookie匹配正则,设置变量$id等于正则引用部分
if ($request_method = POST) {
return 405;
}
#如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($slow) {
limit_rate 10k;
}
#限速,$slow可以通过 set 指令设置
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
}
#如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if ($args ~ post=140){
rewrite ^ http://example.com/ permanent;
}
#如果query string中包含"post=140",永久重定向到example.com
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.jefflei.com www.leizhenfang.com;
if ($invalid_referer) {
return 404;
}
#防盗链
}
八、https
- 定义一个新的server,必需配置的项有:listen,server_name,ssl,ssl_certificate,ssl_certificate_key,一般配置的时候直接复制,然后修改主机名,整数私钥文件,日志路径,root根目录
如果项让访问80端口的请求转到443端口,可使用rewrite语句
listen 443;
server_name agent.t.jlhcar.com;
ssl on;
ssl_certificate, "/usr/local/certificate/agent.t.jlhcar.com.pem";
#证书
ssl_certificate_key "/usr/local/certificate/agent.t.jlhcar.com.key";
#私钥
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;\\协议
...
#日志以及root根目录的其他配置
server {
listen 80;
server_name agent.xxx.com;
rewrite ^/(.*)$ https://agent.xxx.com/$1;
有一个容易错误的地方,http转https的时候会将post转为get请求,此时需要如以下配置
server {
listen 80;
server_name dev-payment.xxxx.cn;
return 307 https://dev-payment.xxxx.cn$request_uri;
}
九、PHP后端处理(fastcgi)
location ~ \.php($|/) {
fastcgi_pass unix:/dev/shm/php-fpm.unix; //最重要的一项,根据实际情况来配置(根据php的配置文件listen的配置来配置,其值可以是一个域名、IP地址:端口、或者是一个Unix的Socket文件。
)
fastcgi_index index.php; //当请求以/结尾的时候,会将请求传递给所设置的index.php文件处理。
fastcgi_split_path_info ^(.+\.php)(.*)$; //Nginx默认获取不到PATH_INFO的值,得通过fastcgi_split_path_info指定定义的正则表达式来给$fastcgi_path_info赋值。
fastcgi_param PATH_INFO $fastcgi_path_info; //
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi.conf;
}
十、负载均衡和反向代理
在http配置项中需要配置一个upstream
upstream ucart{
server 119.29.48.27:80;
server 119.29.48.27:80;
}
注意:nginx中不识别_(下划线),否则会出现400错误
然后在server配置段,将所需要处理的请求反向代理至后端服务器,在可根据需要和服务器配置情况来定义权重,实现负载均衡
location /ucarapi/ {
proxy_pass http://ucar_t/;
proxy_connect_timeout 3; //连接超时时间
proxy_read_timeout 30;
proxy_set_header Host tapi.51ucar.cn; //HTTP头信息,后端服务器根据此来找到特定虚拟主机
proxy_set_header X-Real-IP $remote_addr; //HTTP头信息,真实IP
proxy_set_header X-Scheme $scheme;
}
注意:nginx中不识别_(下划线),否则会出现400错误
然后在server配置段,将所需要处理的请求反向代理至后端服务器,在可根据需要和服务器配置情况来定义权重,实现负载均衡
location /ucarapi/ {
proxy_pass http://ucar_t/;
proxy_connect_timeout 3; //连接超时时间
proxy_read_timeout 30;
proxy_set_header Host tapi.51ucar.cn; //HTTP头信息,后端服务器根据此来找到特定虚拟主机
proxy_set_header X-Real-IP $remote_addr; //HTTP头信息,真实IP
proxy_set_header X-Scheme $scheme;
}