Nginx的那些实战骚操作自我介绍我是WAKE UP 专注于DevOps技术栈. 个人公众号: WAKE UP技术 个人主页: https:// 个人博客: https://blog.
必要的原理介绍● 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 实现的 管道 来实现。
第一步当然是安装了#安装 pcre 依赖 wget http://downloads./project/pcre/pcre/8.37/pcre-8.37.tar.gz #解压压缩文件 tar –xvf pcre-8.37.tar.gz #进入安装目录后./configure 完成后,回到 pcre 目录下执行 make,最后执行 make install ./configure make make install #安装 openssl 、zlib 、 gcc 依赖 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel
#安装nginx,解压 ./configure make && make install #上面如果失败 yum install -y gcc gcc-c++ #进入目录 /usr/local/nginx/sbin/nginx 启动服务 ./nginx
常用命令 咱复习一下#启动命令,在/usr/local/nginx/sbin 目录下执行 ./nginx
#关闭命令,在/usr/local/nginx/sbin 目录下执行 ./nginx -s stop
#重新加载命令,在/usr/local/nginx/sbin 目录下执行 ./nginx -s reload
核心笔记 配置文件#配置文件存在的目录 /usr/local/nginx/conf 下
#1、全局块 #从配置文件开始到 events 块之间的内容,主要会设置一些影响 nginx 服务器整体运行的配置指令,主要包括配 #置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以 #及配置文件的引入等。 #这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是 #会受到硬件、软件等设备的制约
worker_processes 1;
#2、events 块 #events 块涉及的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process #下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word #process 可以同时支持的最大连接数等。 #上述例子就表示每个 work process 支持的最大连接数为 1024. #这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。 events { worker_connections 1024; }
#3、http 块 这算是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。 需要注意的是:http 块也可以包括 http 全局块、server 块。 #3-1 http 全局块 http 全局块配置的指令包括文件引入、MIME-TYPE 定义、日志自定义、连接超时时间、单链接请求数上限等。 #3-2 server 块 这块和虚拟主机有密切关系,虚拟主机从用户角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了 节省互联网服务器硬件成本。 每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。 而每个 server 块也分为全局 server 块,以及可以同时包含多个 locaton 块。 1、全局 server 块 最常见的配置是本虚拟机主机的监听配置和本虚拟主机的名称或 IP 配置。 2、location 块 一个 server 块可以配置多个 location 块。 这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如 server_name/uri-string),对虚拟主机名称 (也可以是 IP 别名)之外的字符串(例如 前面的 /uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓 存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
核心配置 重点来了反向代理#1、反向代理实例一 #通过访问nginx=====》tomcat进行代理 #,修改nginx.conf下面为全部的配置文件, #192.168.253.130 为你的nginx服务器ip #http://127.0.0.1:8001 为你的tomcat的访问路径 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; } } }
#修改tomcat端口为8001,启动tomcat #重新加载nginx
然后访问 192.168.253.130===》》就会代理到 tomcat服务器
#2、反向代理实例二 #实现效果:使用 nginx 反向代理,根据访问的路径跳转到不同端口的服务中 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
#在 http 块中添加 server{}
所有的配置如下 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 包含正则表达式,则必须要有 ~ 或者 ~* 标识。
负载均衡#首先准备两个同时启动的Tomcat 配置文件全部如下 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; } }
}
#myservers名称自定义 #访问192.168.253.130:9010 =====>>>一个一次 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; }
根据文件类型设置过期时间location ~.*\.css$ { expires 1d; break; } location ~.*\.js$ { expires 1d; break; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { access_log off; expires 15d; #保存15天 break; }
# curl -x127.0.0.1:80 http://www./static/image/common/logo.png -I #测试图片的max-age
禁止文件缓存location ~* \.(js|css|png|jpg|gif)$ { add_header Cache-Control no-store; }
静态文件压缩server { # 开启gzip 压缩 gzip on; # 设置gzip所需的http协议最低版本 (HTTP/1.1, HTTP/1.0) gzip_http_version 1.1; # 设置压缩级别,压缩级别越高压缩时间越长 (1-9) gzip_comp_level 4; # 设置压缩的最小字节数, 页面Content-Length获取 gzip_min_length 1000; # 设置压缩文件的类型 (text/html) gzip_types text/plain application/javascript text/css; }
指定定错误页面# 根据状态码,返回对于的错误页面 error_page 500 502 503 504 /50x.html; location = /50x.html { root /source/error_page; }复制代码
跨域问题跨域的定义 同源的定义 nginx解决跨域的原理 例如: 前端server域名为:http://xx_domain 后端server域名为:https://github.com 现在http://xx_domain对https://github.com发起请求一定会出现跨域。
不过只需要启动一个nginx服务器,将server_name设置为xx_domain,然后设置相应的location以拦截前端需要跨域的请求,最后将请求代理回github.com。如下面的配置: ## 配置反向代理的参数 server { listen 8080; server_name xx_domain
## 1. 用户访问 http://xx_domain,则反向代理到 https://github.com location / { proxy_pass https://github.com; proxy_redirect off; proxy_set_header Host $host; # 传递域名 proxy_set_header X-Real-IP $remote_addr; # 传递ip proxy_set_header X-Scheme $scheme; # 传递协议 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
重定向配置location / { return 404; #直接返回状态码 } location / { return 404 "pages not found"; #返回状态码 + 一段文本 } location / { return 302 /blog ; #返回状态码 + 重定向地址 } location / { return https://www. ; #返回重定向地址 }
Gzip压缩gzip_types
#压缩的文件类型 text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript
gzip on; #采用gzip压缩的形式发送数据
gzip_disable "msie6" #为指定的客户端禁用gzip功能
gzip_static; #压缩前查找是否有预先gzip处理过的资源
gzip_proxied any; #允许或者禁止压缩基于请求和响应的响应流
gzip_min_length 1000; #设置对数据启用压缩的最少字节数
gzip_comp_level 6; #设置数据的压缩等级
SSL 证书配及跳转HTTPS配置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; }
# Permanent Redirect for HTTP to HTTPS server { listen 80; server_name ; https://$server_name$request_uri; }
文件只能下载 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.在图片所在的目录下创建一个名为.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 服务器使配置生效
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"; }
|