It has been 492 days since the last update, the content of the article may be outdated.
必要的原理介绍 ● Nginx 里有一个 master 进程和多个 worker 进程.master 进程并不处理网络请求,主要负责调度工作进程:加载配置,启动工作进程及非停升级.worker 进程负责处理网络请求与响应. ● master 进程主要用来管理 worker 进程,具体包括如下 4 个主要功能:
接收来自外界的信号
向各 worker 进程发送信号
监控 worker 进程的运行状态
当 worker 进程退出后 (异常情况下), 会自动重新启动新的 worker 进程
● worker 进程主要用来处理基本的网络事件:
多个 worker 进程之间是对等其相互独立的,他们同等竞争来自客户端的请求.
一个请求,只可能在一个 worker 进程中处理,一个 worker 进程,不可能处理其他的进程请求.
worker 进程的个数是可以设置的,一般我们会设置与机器的 cpu 核数一致,同时,nginx 为了更好的利用多核特性,具有 cpu 绑定选项,我们可以将某一个进程绑定在某一核上,这样就不会因为进程的切换带来 cache 的失效
● master 需要完成的工作 ○ 读取并验证配置信息 ○ 创建。绑定及关闭套接字 ○ 启动,终止及维护 worker 进程的个数 ○ 无须中止服务而重新配置工作特性 ○ 控制非中断式升级,启动新的二进制程序并在需要时回滚至老版本 ○ 重新打开日志文件 ○ 编译嵌入式 perl 脚本 ● worker 进程主要完成的任务包括 ○ 接收,传入并处理来自客户端的连接 ○ 提供反向待了及过滤功能 ○ nginx 任何能完成的其他工作
Nginx 的请求方式处理 ● Nginx 是一个高性能的 web 服务器,能够同时处理大量的并发请求。它结合多进程机制和异步机制,异步机制使用的是异步非阻塞方式
多进程机制 ● 服务器每当收到一个客户端时就有服务器主进程(master process)生成一个子进程(worker process)出来和客户端建立连接进行交互,直到连接断开,该子进程就结束了。 ● 使用进程的好处时各个进程之间时相互独立,不需要加锁,减少了使用锁对性能造成的影响,同时降低了编程的复杂度,降低开发成本。其次采用独立的进程可以让进程之间不会影响,如果一个进程发生异常退出时,其他进程正常工作,master 进程则很快的启动新的 worker 进程,确保服务不会中断,从而将风险降到最低。 ● 缺点是操作系统生成一个子进程需要进行内存复制等操作,在资源和时间上会产生一定的开销。当有大量请求时,会导致系统性能下降。 nginx 事件驱动模型 ● 在 Nginx 的异步非阻塞机制中,工作进程在调用 IO 后,就去处理其他的请求,当 IO 调用返回后,会通知该工作进程。对于这样的系统调用,主要使用 Nginx 服务器的事件驱动模型来实现。 ● ● nginx 事件驱动模型由事件收集器和事件处理器三部分基本单元组成 ○ 事件收集器 负责收集 worker 进程 IO 请求; ○ 事件发送器:负责将 IO 事件发送到事件处理器; ○ 事件处理器:负责各种事件的响应工作 ● 事件发送器将每个请求放入一个待处理事件列表,使用非阻塞 I/O 方式调用 事件处理器 来处理该请求,其处理方式称为 "多路 IO 复用方法," 常见的包括以下三种 select 模式,poll 模型.epoll 模型 Nginx 进程处理模型 ● nginx 服务器使用 master/worker 多进程模式,多线程启动和执行的流程如下:
主程序 master process 启动后,通过一个 for 循环来接收和处理外部信号
主进程通过 fork 函数产生 worker 子进程,每个子进程执行一个 for 循环来实现 Nginx 服务器对事件的接收和处理 当一个 worker 进程在 accept 这个连接之后,就开始 读取请求 , 解析请求 , 处理请求 ,产生数据后,再 返回给客户端 ,最后才 断开连接 ,这样一个完整的请求就是这样的了。我们可以看到,一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。 在 Nginx 服务器的运行过程中, 主进程 和 工作进程 需要进程交互。交互依赖于 Socket 实现的 管道 来实现。
第一步当然是安装了 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 wget http://downloads.sourceforge.net/project/pcre/pcre/8.37/pcre-8.37.tar.gz tar –xvf pcre-8.37.tar.gz ./configure make make install yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel ./configure make && make install yum install -y gcc gcc-c++ ./nginx
常用命令 咱复习一下 1 2 3 4 5 6 7 8 ./nginx ./nginx -s stop ./nginx -s reload
核心笔记 配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 /usr/local/nginx/conf 下 worker_processes 1; events { worker_connections 1024; } 这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。 需要注意的是:http 块也可以包括 http 全局块、server 块。 http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了 节省互联网服务器硬件成本。 每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。 而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。 1、全局 server 块 最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。 2、location 块 一个 server 块可以配置多个 location 块。 这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称 (也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓 存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
核心配置 重点来了 反向代理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 worker_processes 1 ;events { worker_connections 1024 ; } http { include mime.types; default_type application/octet-stream; sendfile on ; keepalive_timeout 65 ; server { listen 80 ; server_name 192.168.253.130 ; location / { proxy_pass http://127.0.0.1:8001; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } } 然后访问 192.168.253.130===》》就会代理到 tomcat服务器 nginx 监听端口为 9001 ,准备两台tomcat访问 http://192.168.253.130:9001/edu/ 直接跳转到tomcat1 127.0.0.1:8081 访问 http://192.168.253.130:9001/vod/ 直接跳转到tomcat2 127.0.0.1:8082 所有的配置如下 worker_processes 1 ; events { worker_connections 1024 ; } http { include mime.types; default_type application/octet-stream; sendfile on ; keepalive_timeout 65 ; server { listen 80 ; server_name 192.168.253.130 ; location / { proxy_pass http://127.0.0.1:8001; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } server { listen 9001 ; server_name 192.168.253.130 ; location ~ /edu/ { proxy_pass http://127.0.0.1:8081; } location ~ /vod/ { proxy_pass http://127.0.0.1:8082; } } } 然后访问 192.168.253.130:9001/edu/a.html ===》》就会代理到 tomcat服务器127.0.0.1:8081 //edu/a.html 然后访问 192.168.253.130:9001 /vod/a.html ===》》就会代理到 tomcat服务器127.0.0.1:8081 /vod/a.html 1 、= :用于不含正则表达式的 uri 前,要求请求字符串与 uri 严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。 2 、~:用于表示 uri 包含正则表达式,并且区分大小写。3 、~*:用于表示 uri 包含正则表达式,并且不区分大小写。4 、^~:用于不含正则表达式的 uri 前,要求 Nginx 服务器找到标识 uri 和请求字符串匹配度最高的 location 后,立即使用此 location 处理请求,而不再使用 location 块中的正则 uri 和请求字符串做匹配。 注意:如果 uri 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
负载均衡 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 配置文件全部如下 worker_processes 1 ;events { worker_connections 1024 ; } http { include mime.types; default_type application/octet-stream; sendfile on ; keepalive_timeout 65 ; server { listen 80 ; server_name 192.168.253.130 ; location / { proxy_pass http://127.0.0.1:8001; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } server { listen 9001 ; server_name 192.168.253.130 ; location ~ /edu/ { proxy_pass http://127.0.0.1:8081; } location ~ /vod/ { proxy_pass http://127.0.0.1:8082; } } upstream myservers{ server 192.168.253.130:8081 ; server 192.168.253.130:8082 ; } server { listen 9010 ; server_name 192.168.253.130 ; location / { proxy_pass http://myservers; proxy_connect_timeout 10 ; } } } =====>>>一个一次 192.168.253.130:8081; 192.168.253.130:8082; 1、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器 down 掉,能自动剔除。 upstream myservers{ server 192.168.253.130:8081 ; server 192.168.253.130:8082 ; } 2、weight weight 代表权,重默认为 1 ,权重越高被分配的客户端越多 upstream myservers{ server 192.168.253.130:8081 weight=1 ; server 192.168.253.130:8082 weight=2 ; } 3、ip_hash 每个请求按访问 ip 的 hash 结果分配,这样每个访客固定访问一个后端服务器,可以解决 session 的问题。 upstream myservers{ ip_hash; server 192.168.253.130:8081 ; server 192.168.253.130:8082 ; } 4、fair(第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先分配。 upstream myservers{ server 192.168.253.130:8081 ; server 192.168.253.130:8082 ; fair; }
根据文件类型设置过期时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 location ~.*\.css$ { expires 1d ; break; } location ~.*\.js$ { expires 1d ; break; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { access_log off ; expires 15d ; break; }
禁止文件缓存 1 2 3 location ~* \.(js|css|png|jpg|gif)$ { add_header Cache-Control no -store; }
静态文件压缩 1 2 3 4 5 6 7 8 9 10 11 12 server { gzip on ; gzip_http_version 1 .1 ; gzip_comp_level 4 ; gzip_min_length 1000 ; gzip_types text/plain application/javascript text/css; }
指定定错误页面 1 2 3 4 5 error_page 500 502 503 504 /50x.html;location = /50x.html { root /source/error_page; }复制代码
跨域问题 跨域的定义
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。通常不允许不同源间的读操作。 同源的定义
如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。 nginx 解决跨域的原理
例如:
不过只需要启动一个 nginx 服务器,将 server_name 设置为 xx_domain, 然后设置相应的 location 以拦截前端需要跨域的请求,最后将请求代理回 github.com 。如下面的配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 server { listen 8080 ; server_name xx_domain location / { proxy_pass https://github.com; proxy_redirect off ; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Scheme $scheme ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; } }
重定向配置 1 2 3 4 5 6 7 8 9 10 11 12 location / { return 404 ; } location / { return 404 "pages not found" ; } location / { return 302 /blog ; } location / { return https://www.mingongge.com ; }
Gzip 压缩 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript gzip on ; gzip_disable "msie6" gzip_static; gzip_proxied any;gzip_min_length 1000 ;gzip_comp_level 6 ;
SSL 证书配置及跳转 HTTPS 配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 server { listen 192.168.1.250:443 ssl; server_tokens off ; server_name mingonggex.com www.mingonggex.com; root /var/www/mingonggex.com/public_html; ssl_certificate /etc/nginx/sites-enabled/certs/mingongge.crt; ssl_certificate_key /etc/nginx/sites-enabled/certs/mingongge.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 ; } server { listen 80 ; server_name mingongge.com; https://$server_name$request_uri; }
文件只能下载 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 location /data { alias /data/; if ($request_filename ~* ^.*?\.(doc|pdf|xlsx|png|txt)$) { add_header Content-Disposition attachment; add_header Content-Type application/octet-stream; } proxy_connect_timeout 3 ; proxy_read_timeout 3 ; proxy_send_timeout 3 ; autoindex on ; sendfile on ; charset utf-8 ,gbk; }
只能查看图片 1 2 3 4 5 6 7 8 9 10 11 12 13 1.在图片所在的目录下创建一个名为.htaccess’的隐藏文件,该文件用于设置禁止下载 2.在.htaccess文件中添加以下配置: SetHandler default-handler Options-Indexes 这样设置后,用户就无法通过点击链接或使用下载工具下载图片了 接下来,在 nginx的配置文件中添加以下配置 location /path/to/images/ { add header Content-Disposition "inline" ;add header Content-Type "image/jpeg" ;} 此配置会为指定路径下的所有图片文件添加Content-Disposition’和Content-Type’头信息,使其只能在线查看。 最后,重启 nginx 服务器使配置生效
1 2 3 4 5 6 7 8 9 location /pic { alias /data/; proxy_connect_timeout 3 ; proxy_read_timeout 3 ; proxy_send_timeout 3 ; autoindex on ; add_header Content-Disposition "inline" ; add_header Content-Type "image/jpeg" ; }