Nginx基本概念
nginx是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx专为性能优化而开发,性能是器最重要的考量,实现上非常注重效率,能经受高负载的考验,据报告能支持高达50,000个并发连接数。
Nginx不仅能做反向代理,实现负载均衡;还能可以作正向代理来进行上网等功能。
反向代理
代理与反向代理
代理服务器是位于客户端和原始服务器的一台中间服务器,为了从原始服务器获取到内容,客户端向代理服务器发送一个请求并带上目标服务器(原始服务器),代理服务器在接收到请求后就会将请求转发给原始服务器,并将从原始服务器上获取到的数据返回给客户端,代理服务器是代理的客户端,所以一般客户端是知道代理服务器的存在的,比如翻墙就用了代理服务器。
(代理对象是客户端,不知道服务端是谁。)
反向代理服务器是位于原始服务器端的服务器,反向代理服务器接受来自互联网的请求,然后将这些请求发送给内网的服务器,并将从内网的服务器获取结果返回给互联网上的客户端,反向代理服务器是代理的服务端,所以客户端是不知道反向代理服务器的存在的,服务端是知道反向代理服务器的。(隐藏了真实服务器IP地址。代理对象是服务端,不知道客户端是谁。)
代理服务器的作用
- 访问原来无法访问的资源
- 用作缓存,加速访问速度
- 对客户端访问授权,上网进行认证
- 代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
反向代理服务器的作用
- 保护内网安全
- 负载均衡
- 缓存,减少服务器的压力
nginx的作用
1.反向代理,将多台服务器代理成一台服务器
2.负载均衡,将多个请求均匀的分配到多台服务器上,减轻每台服务器的压力,提高服务的吞吐量
3.动静分离,nginx可以用作静态文件的缓存服务器,提高访问速度
nginx的工作过程
1.在nginx启动后,会有一个master进程和多个worker进程,master进程主要用来管理worker进程,包括:接受信号,将信号分发给worker进程,监听worker进程工作状态,当worker进程退出时(非正常),启动新的worker进程。基本的网络事件会交给worker进程处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的 。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的 。
2.当master接收到重新加载的信号会怎么处理(./nginx -s reload)?,master会重新加载配置文件,然后启动新的进程,使用的新的worker进程来接受请求,并告诉老的worker进程他们可以退休了,老的worker进程将不会接受新的,老的worker进程处理完手中正在处理的请求就会退出。
Nginx配置文件
主配置文件:/usr/local/nginx/conf/nginx.conf
通过nginx -c 可以指定要读取的配置文件来启动
nginx常见的配置文件及作用:
配置文件 | 作用 |
---|---|
nginx.conf | nginx的基本配置文件 |
mime.types | MIME类型关联的扩展文件 |
fastcgi.conf | 与fastcgi相关的配置文件 |
proxy.conf | 与proxy相关的配置 |
sites.conf | 配置nginx提供的网站,包括虚拟主机 |
默认的 nginx 配置文件 nginx.conf 内容如下:
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# 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;
# }
#}
}
nginx 文件结构
... #全局块
events { #events块
...
}
http #http块
{
... #http全局块
server #server块
{
... #server全局块
location [PATTERN] #location块
{
...
}
location [PATTERN]
{
...
}
}
server
{
...
}
... #http全局块
}
nginx.conf的内容分为以下几段:
- main配置段:全局配置段。其中main配置段中可能包含 event配置段;
- event{}:定义event模型工作特性;
- http{}:定义http协议相关配置。
配置指令:(注:以分号结尾)
1.第一部分:全局块
从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。
比如上面第一行配置的:worker_processes :1;
这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约
main配置段
1.daemon {on|off}; //是否已守护进程运行进程nginx,调试时应设置为off
2.master_process {on|off}; //是否以master/worker模型来运行nginx,调试时可以设置为off
3.error_log 位置1 级别2; //配置错误日志
//Nginx 软件会把自身的故障信息及用户的日志信息记录到指定的日志文件里。
//error_log file level;
//error_log 是关键字,file 是保存错误日志的文件路径,level 是错误日志级别
//第二个参数是错误级别。包括debug, info, notice, warn, error, crit, alert, 以及 emerg这几种不同的级别。
正常运行必备的配置参数
user USERNSME {GROUPNAME}; //指定运行worker进程的用户和组;
pid /path/to/pid_file; //指定nginx守护进程的pid文件
worker_rlimit_nofile NUMBER; //设置所有worker进程最大可以打开的文件数,默认为1024;
worker_rlimit_core SIZE; //指明所有worker进程所能够使用的总体的最大核心文件大小,保持默认即可
//后两句可以省略
优化性能的配置参数
worker_processse N; //启动N个worker进程,这里的N为了避免上下文切换,通常设置为cpu总核数-1或等于总t核数
worker_cpu_affinity CPUMASK3 [CPUMASK…]; //将进程绑定到某个CPU中,避免频繁刷新缓存
time_resolution INTERVAL; //计时器解析度。降低此值,可减少gettimeofday()系统调用的次数
worker_priority NUMBER; //指明worker进程的NICE值(优先级)
2.第二部分:events 块
比如上面的配置:
events {
worker_connections 1024;//每个 work process 支持的最大连接数为 1024.
}
events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process
下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word
process 可以同时支持的最大连接数等。
上述例子就表示每个 work process 支持的最大连接数为 1024.
这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置
event{}相关配置
use epoll; #多路复用I/O中的一种方式,仅用于linux2.6以上内核,大大提升nginx性能
accept_mutex {on|off}; #master调度用户请求至各worker进程时使用的负载均衡锁,“on”表示能让多个worker轮流地、序列化地去响应新请求(防止惊群现象发生)
lock_file FILE; #accept_nutex用到的互斥锁锁文件路径
#每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
use [epoll | rtsig | select | poll]; #指明使用的事件模型,建议让nginx自行选择
worker_connections #; //每个进程能够接受的最大连接数
multi_accept on; #设置一个进程是否同时接受多个网络连接,默认为off
3.第三部分:http 块
这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。
需要注意的是:http 块也可以包括 http 全局块、server 块。
http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。
1、全局 server 块
最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。
server{}:定义一个虚拟主机,示例如下:
server {
keepalive_requests 120; #单连接请求上限次数
listen 80; #监听端口
server_name www.idfsoft.com; #监听地址
root "/vhosts/web";
location /baabababba{}
location /sskjx{}
.....
//当直接访问服务器,不加其他路径访问时,并且nginx配置中,含有location /{}配置时,nginx的location会优先匹配到此代码块,会指向此代码块中的root , server中的root, 不会生效。当去掉/ 配置,nginx找不到匹配到的location代码块时候,则会才执行server中的root。
server_name NAME1 [NAME2...]; ##后面可以跟多个主机,名称可以用正则表达式或通配符
2、location 块
一个 server 块可以配置多个 location 块。
这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称
(也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓
存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
http {
1. include mime.types;#文件扩展名与文件类型映射表
2. default_type application/octet-stream; #默认文件类型,默认为text/plain
3. keepalive_timeout 65;#http连接超时时间
4. gzip on; #实现资源压缩的原理是通过ngx_http_gzip_module模块拦截请求,并对需要做gzip的类型做gzip
5. sendfile on; ##指定nginx是否调用sendfile函数(zero copy)来输出文件,对于普通应用必须设为on;
##如果用来进行下载等应用磁盘I/O重负载应用,可设置为OFF,以平衡磁盘与网络I/O处理速度,降低系统的uptime
6. autoindex on; ##开启目录列表访问,适合下载服务器,默认关闭
7. upstream { ##负载均衡配置
...
}
8. server { ##服务器级别,每一个server类似于httpd中的一个<VirtualHost,通俗来说就是一个网站>
listen80;
server_name localhost;
location / { ##请求级别,类似与httpd中的<Location>,用于定义URL与本地文件系统的映射关系
root html;
index index.html index.htm;
}
}
}
展示
反向代理
eg:用nginx反向代理,根据访问的路径跳转到不同端口的服务中,nginx的监听端口为9001
访问http://localhost:9001/edu/ 直接跳转到127.0.0.1:8080
访问http://localhost:9001/vod/ 直接跳转到127.0.0.1:8081
在浏览器输入:http://localhost:9001/edu/a.html
则跳转到端口号为8080的服务器中edu目录下的a.html
在浏览器输入:http://localhost:9001/vod/a.html
则跳转到端口号为8081的服务器中edu目录下的a.html
location区段,通过指定模式来与客户端请求的URI相匹配
功能:允许根据用户请求的URI来匹配定义的各location,匹配到时,此请求将被响应的location配置快中的配置所处理,例如做访问控制等功能
语法:如下
- location [修饰符] pattern {…}
常用的修饰符说明:
项目 | Value |
---|---|
= | 精确匹配 |
~ | 正则表达式模式匹配,区分大小写 |
~* | 正则表达式模式匹配,不区分大小写 |
^~ | 前缀匹配,类似于无修饰符的行为,也是以指定模块开始,不同的是,如果模式匹配,那么就停止搜索其他模式了,不支持正则表达式 |
@ | 定义命名location区段,这些区段客户端不能访问,只可以有内部产生的请求访问,如try_files或error_page等 |
(1)没有修饰符表示必须以指定模式开始,如:
server {
server_name www.baibai.com;
location /abc {
…
}
}
那么如下内容可以就可以正确匹配:
www.baibai.com/abc
www.baibai.com/abc/
www.baibai.com/abc?.…
(2)=:表示必须与指定的模式精确匹配,如:
server {
server_name www.baibai.com;
location = /abc {
…
}
}
那么如下内容可正确匹配:
www.baibai.com/abc
www.baibai.com/abc?.…
如下内容则无法匹配:
www.baibai.com/abc/
www.baibai.com/abc/adcde
~:表示指定的正则表达式要区分大小写,如:
server {
server_name www.baibai.com;
location ~ ^/abc$ {
…
}
}
那么如下内容可以正确匹配:
www.baibai.com/abc
www.baibai.com/abc?.…
如下内容则无法匹配:
www.baibai.com/abc/
www.baibai.com/ABC
www.baibai.com/abcde
(4)~*:表示指定的正则表达式不区分大小写
查找顺序和优先级,由高到底依次为:
1.带有“=”的精确匹配优先
2.正则表达式
(有多个正则表达式出现时,按照它们在配置文件中定义的顺序)
3.没有修饰符的精确匹配
负载均衡
upstream {}负载均衡配置
负载均衡:随着网站的发展,服务器压力越来越大,我们可能首先会将数据库,静态文件分离出去。但是随着发展,单独业务API的请求的压力也会变得很大,这时候我们可能需要做负载均衡将一台服务器面临的压力分散到多台服务器上。
在http下添加 upstream upstream_name {} 来配置要映射的服务器。
// eg:server 127.0.0.1:7878;
//upstream_name大家可以指定为服务的域名或者项目的代号。
//server下的location 我们将 / 下的全部请求转发到 http://upstream_name ,也就是我们上面配置的服务器列表中的某一台服务器上。具体是哪台服务器,nginx会根据配置的调度算法来确认。
eg:在地址栏输入地址:http://localhost/edu/a.html/负载均衡效果,平均8080和8081端口(此时,如果端口为8080和8081的服务器若都有edu文件夹)
在浏览器输入:http://localhost/edu/a.html
刷新页面,就会交替出现端口为8080和端口为8081服务器中的a.html
负载均衡,nginx 分配服务器策略
第一种 轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。
第二种 weight
weight 代表权重默认为 1,权重越高被分配的客户端越多
第三种 ip_hash
每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器
第四种 fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。
动静分离
Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和
静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 Nginx
处理静态页面,Tomcat 处理动态页面。动静分离从目前实现角度来讲大致分为两种,
一种是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
另外一种方法就是动态跟静态文件混合在一起发布,通过 nginx 来分开
eg:在服务器中同一目录下有www和image两个文件夹,www中有a.html,image中有1.jpg
location 多级目录配置
很多情况下,我们的一个项目中要区分多级目录,如dev、pub环境等,这时候需要通过nginx的location配置,不同环境的代码走不同的目录
常用:
location /dev/ {
root /www/project; # 注意,此时走的是/www/project下边的dev目录
index index.php index.html;
}
location /pub/ {
alias /www/project/pub/; # 此时是/www/project/pub/目录
index index.html;
}
# 其他路径直接返回403页面
location / {
return 403;
}
其中对于location下边目录有两种设置方式,分别是 root 和 alias,
//两者有什么区别呢?
alias 指定的目录是准确的,给location指定一个目录。
root 指定上级目录,并且该上级目录 一定要 含有locatoin指定名称的同名目录。
location中index配置
server {
listen 80;
server_name example.org www.example.org;
location / {
root /data/www;
index index.html index.php;
}
location ~ \.php$ {
root /data/www/test;
}
}
上面的例子中,如果你使用example.org或www.example.org直接发起请求,那么首先会访问到“/”的location,结合root与index指令,会先判断/data/www/index.html是否存在,如果不,则接着查看
/data/www/index.php ,如果存在,则使用/index.php发起内部重定向,就像从客户端再一次发起请求一样,Nginx会再一次搜索location,毫无疑问匹配到第二个~ \.php$,从而访问到/data/www/test/index.php。
深入理解Nginx中Server和Location的匹配逻辑
参考链接:Nginx简介及配置文件详解
参考链接:nginx基本原理介绍
参考链接:nginx基本概念和原理
参考链接:Nginx简介及配置文件详解
参考链接:nginx配置详解
参考链接:Nginx配置配置文件详解
参考链接:nginx location 多级目录配置
参考链接:nginx中的index配置