Nginx Nginx 的历史 Nginx 特点 高并发,CPU消耗低,内存消耗少,它可以保持1000个没有活动的连接只占2.5M内存,成本低廉,配置简单、 支持Rewrite重写、内置健康检查功能、节省带宽、稳定性高、支持热部署,效率高,具有稳定性,可以实 现静态网页,启动容易,可以实现负载均衡和反向代理 Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的 HTTP和反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器.Nginx是由俄罗斯人 Igor Sysoev为 俄罗斯访问量第二的 Rambler.ru站点开发的.Igor Sysoev在建立的项目时,使用基于BSD许可.自Nginx 发布 以来,Nginx 已经因为它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名.在俄罗斯许多 大网站都已经使用它, 且一直表现不凡.俄罗斯大约有20%左右的虚拟主机是由nignx服务或代理的.Google 在线安全博客中统计Nginx服务或代理了大约所有Internet虚拟主机的4%.而Netcraft的统计显示,Nginx服 务的主机在过去的一年里以四倍的速度增长并且在这几年里,它的排名还在不断上升 为什么要用Nginx Nginx专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率 .它支持内核Poll模型,能经受高 负载的考验,有报告表明能支持高达 50,000个并发连接数.Nginx具有很高的稳定性,其它HTTP服务器当遇 到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应只能 重启服务器.例如当前Apache一旦上到200个以上进程,web响应速度就明显非常缓慢了.而Nginx采取了分 阶段资源分配技术,使得它的CPU与内存占用率非常低.Nginx官方表示保持10,000(即C10K)个没有活动的连 接,它只占2.5M内存,所以类似DOS这样的攻击对Nginx来说基本上是毫无用处的.就稳定性而言,nginx比 lighttpd更胜一筹.Nginx支持热部署,它的启动特别容易, 并且几乎可以做到7*24不间断运行,即使运行数个 月也不需要重新启动.你还能够在不间断服务的情况下,对软件版本进行进行升级.Nginx采用master-slave模 型,能够充分利用SMP的优势,且能够减少工作进程在磁盘I/O的阻塞延迟. Nginx代码质量非常高,代码很规范,手法成熟, 模块扩展也很容易. Nginx采用了一些os提供的最新特性如对sendfile (Linux2.2+),acceptfilter(FreeBSD4.1 +),TCP_DEFER_ACCEPT (Linux 2.4+)的支持,从而大大提高了性能.当然,nginx还很年轻,多多少少存在一 些问题,比如:Nginx是俄罗斯人创建,目前文档方面还不是很完善.因为文档大多是俄语,所以文档方面这也 是个障碍.尽管Nignx的模块比较多,但它们还不够完善.对脚本的支持力度不够. nginx和apache的80端口之争(必看):https://cloud.tencent.com/developer/news/139466
获取Nginx Nginx的官方网站: http://nginx.org/en/download.html Nginx官网提供了三个类型的版本 Mainline version:Mainline 是 Nginx 目前主力在做的版本,可以说是开发版 Stable version:最新稳定版,生产环境上建议使用的版本 Legacy versions:遗留的老版本的稳定版 2/34
服务器系统和软件排名统计网站:www.netcraft.com
3/34
nginx安装 源码包的编译安装流程: 1、安装gcc、gcc-c++编译器和相关的依赖包 2、下载软件的源码包、解包解压缩 3、生成安装配置文件: ./configuration [选项] 4、根据配置文件编译源码文件:make 5、安装:make install nginx源码包的安装实例: 1、 安装gcc、gcc-c++编译器:yum install -y gcc gcc-c++ wget curl 2、 用wget下载nginx软件的源码包、解包解压缩:http://nginx.org wget http://nginx.org/download/nginx-1.15.8.tar.gz ls tar -xvf nginx-1.15.8.tar.gz 3、 生成安装配置文件Makefile: cd nginx-1.15.8 yum install -y pcre-devel openssl-devel ./configure 4、 根据Makefile配置文件编译源码文件:make 5、 安装:make install 6、 创建nginx命令的快捷方式:ln -s /usr/local/nginx/sbin/nginx /bin/nginx 7、 启动nginx服务: nginx -h 查nginx命令的帮助 nginx -t 检测nginx配置文件语法 nginx 启动nginx服务 nginx -s reload 重启nginx服务 nginx -s stop 停止nginx服务 8、 访问nginx的默认网站:curl 192.168.11.11 浏览器访问nginx的默认网站:http://192.168.11.11 4/34 Nginx编译安装:
- 停止原有web服务器: lsof -i:80 && systemctl stop httpd 2.下载nginx-1.8.1版的软件: 首先,在浏览器中输入nginx.org回车进入nginx的官网,然后单击网站右侧的download进入下载页面,复 制nginx-1.8.1版的网址,再执行如下命令。 cd wget http://120.52.51.13/nginx.org/download/nginx-1.8.1.tar.gz ls nginx
- 添加普通用户账号来运行nginx: [root@clone1 nginx-1.8.1]# useradd nginx -M -s /sbin/nologin [root@clone1 nginx-1.8.1]# yum install -y gcc pcre-devel openssl-devel 安装gcc编译器和相 关的依赖包
- 解压并安装Nginx: [root@clone1 nginx-1.8.1]# tar xf nginx-1.8.1.tar.gz [root@clone1 nginx-1.8.1]# cd nginx-1.8.1 [root@clone1 nginx-1.8.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx -- with-http_stub_status_module --with-http_ssl_module 生成编译安装的Makefile环境配置文件 [root@clone1 nginx-1.8.1]# make && make install
--prefix=/usr/local/nginx \指定安装路径 --with-http_stub_status_module \声明启用service status服务状态页,默认不启用 --with-http_ssl_module \启用ssl(Secure Sockets Layer安全套接层)模块,以支持https请 求 --sbin-path=/usr/bin/ \声明nginx命令目录 5. 启动: [root@clone1 nginx-1.8.1]# ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx [root@clone1 nginx-1.8.1]# nginx -t 检测nginx配置文件的语法 [root@clone1 nginx-1.8.1]# nginx 启动nginx服务 [root@clone1 nginx-1.8.1]# lsof -i:80 或 netstat -atunlp | grep :80
查看命令帮助: /usr/local/nginx/sbin/nginx -h -v 查看nginx版本 -V 查看编译参数 -t 测试默认配置文件 -c 加载非默认位置配置文件,默认配置文件是/usr/local/nginx/conf/nginx.conf -s 发送信号(signal)给nginx的master主进程,信号可以是stop, quit, reopen, reload nginx文件解说: nginx的工作目录:/usr/local/nginx/ 主配置文件:/usr/local/nginx/conf/nginx.conf 默认主页目录:/usr/local/nginx/html/ 默认主页:/usr/local/nginx/html/index.html 50x错误提示网页:/usr/local/nginx/html/50x.html 日志文件目录:/usr/local/nginx/logs mkdir /usr/local/nginx/conf.d sed -i '18a\ include /usr/local/nginx/conf.d/.conf;' /usr/local/nginx/conf/nginx.conf 5/34 练习:修改nginx的默认主页文件,并做内测。 echo 'welcome to nginx software.' >> /usr/local/nginx/html/index.html lsblk >> /usr/local/nginx/html/index.html elinks 127.0.0.1 6. 查看启动状态: [root@clone1 nginx-1.8.1]# netstat -tanp|grep 80 tcp 0 0 0.0.0.0:80 0.0.0.0: LISTEN 5535/nginx 7. 测试主页是否可以访问: 在192.168.11.11本地测试(内测):elinks 127.0.0.1 在192.168.11.1的win7系统中远程测试(公测):Win+R运行-->explorer http://192.168.11.11
8.kill信号:
TERM, INT 快速关闭
QUIT 从容关闭,关闭主进程顺便关闭工作子进程
HUP 重载配置用新的配置开始新的工作进程从容关闭旧的工作进程
USR1 重新打开日志文件
USR2 平滑升级可执行程序
WINCH 从容关闭工作进程,不会立即关闭子进程
作业
1.编写一个名称为/sh/nginx.sh的脚本,要求实现自动下载nginx-1.8.1.tar.gz软件包,并自动解压和安装
nginx软件包,最后启动nginx服务,并用elinks做内测。
方法一
#!bin/bash
lsof -i:80 && systemctl stop httpd
wget http://nginx.org/download/nginx-1.8.1.tar.gz
ls && (useradd nginx -M -s /sbin/nologin;id nginx)
yum -y install gcc openssl-devel pcre-devel
tar xf nginx-1.8.1.tar.gz
ls && cd nginx-1.8.1/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --
with-http_ssl_module
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
nginx -t && nginx
lsof -i:80
elinks 127.0.0.1
方法二
touch nginx.sh
chmod -v +x nginx.sh
cat > nginx.sh <<EOF
#!/bin/bash
id nginx || useradd -M -s /sbin/nologin nginx
6/34
yum install -y gcc pcre-devel openssl-devel curl elinks
[ -f nginx-1.10.3.tar.gz ] && tar xf nginx-1.10.3.tar.gz
[ -d nginx-1.10.3 ] && cd nginx-1.10.3
./configure --prefix=/usr/local/nginx
--user=nginx
--group=nginx
--with-http_stub_status_module
--with-http_ssl_module
read -p '按enter键继续安装nginx...'
make && make install
#测试配置文件,并启动nginx服务.
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
nginx -t
nginx
curl 127.0.0.1
netstat -ntlp|grep :80
chmod -v +x /etc/rc.d/rc.local
grep nginx /etc/rc.d/rc.local||echo '/usr/local/nginx/bin/nginx' >> /etc/rc.d/rc.local
pwd
cd ..
mkdir -pv /usr/local/nginx/conf.d
grep 'conf.d' /usr/local/nginx/conf/nginx.conf
[ $? -eq 0 ] || sed -i '18a\include ../conf.d/*.conf;' /usr/local/nginx/conf/nginx.conf
read -p 'ctrl+c退出操作。按enter键,继续配置8081端口的虚拟主机...'
cat > /usr/local/nginx/conf.d/8081.conf <<EOA
server {
listen 8081;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html/8081;
index index.html index.htm;
}
}
EOA
mkdir -pv /usr/local/nginx/html/8081
echo 'www.8081.com:8081' > /usr/local/nginx/html/8081/index.html
nginx -t && nginx -s reload
netstat -atnlp|grep 80
curl 127.0.0.1:8081
EOF
2.给node11主机临时设置一个新IP 192.168.11.110,并在此主机上创建网站主页目录/web/qf,网站主
页文件为/web/qf/index.html,用nginx基于IP和端口(端口号为8088)的虚拟主机技术发布此网站,配置文
件名为/usr/local/nginx/conf.d/qf.conf。网站域名为web.qf.com。
ifconfig ens33:4 192.168.11.110 up
ip a
mkdir -pv /web/qf
echo welcome to linux >/web/qf/index.html
vim /usr/local/nginx/conf.d/qf.conf
server {
listen 192.168.11.110:8088;
server_name web.qf.com;
location / {
7/34
root /web/qf;
index index.html index.htm;
}
}
nginx -t
nginx -s reload
curl 192.168.11.110:8088
3.要求给第2题的web.qf.com的网站做基于用户认证的访问控制,允许alice用户访问此网站。
htpasswd -c /usr/local/nginx/passwd alice
New password:0
Re-type new password:0
vim /usr/local/nginx/conf.d/qf.conf
server {
listen 192.168.11.110:8088;
server_name web.qf.com;
location / {
root /web/qf;
index index.html index.htm;
auth_basic "ll";
auth_basic_user_file /usr/local/nginx/passwd;
}
}
nginx -t
nginx -s reload
curl 192.168.11.110:8088 -u alice:0
nginx.sh
配置文件详解
nginx主配置文件主要有以下几大块
1、全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日
志存放路径,配置文件引入,允许生成worker process数等。
2、events(事件)块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种
事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
3、http块:可以嵌套多个server(可用于配置web虚拟主机),配置代理,缓存,日志定义等绝大多数功
能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超
时时间,单连接请求数等。
4、server(服务器)块:配置虚拟主机的相关参数,一个http中可以有多个server。
5、location(定位)块:配置请求的路由(用于做反向代理、正向代理),以及各种页面的处理情况。
[root@clone1 nginx]# vim /usr/local/nginx/conf/nginx.conf
#user nobody; #nginx用户及组,如果用户和组名一样可只写一个
worker_processes 1; #定义了nginx对外提供web服务时的worker进程数。
#最优值取决于许多因素,包括(但不限于)CPU核的数量、存
8/34
储数据的硬盘数量及负载模式。
#不能确定的时候,将其设置为可用的CPU核心数将是一个好的
开始(设置为“auto”将尝试自动检测它)
#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;
server_tokens off; #隐藏软件版本号
#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;
9/34 #}
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;
}
#} } 自定义日志 自己定义日志:在日志部分写入 log_format cust '$remote_addr : $time_local : $http_user_agent'; access_log logs/access.log cust; #cust:自定义的日志名称 测试自定义日志: # curl 192.168.1.254 #cat access.log 访问的Ip:访问的时间:访问的客户端的类型 $remote_addr 记录客户端的ip $remote_user 记录远程客户端的名字 $time_local 记录访问时间 $request 记录请求的URL或HTTP协议 $status 记录请求状态 10/34 $body_bytes_sent 记录发送给客户端的文件的内容的大小 $http_referer 记录从哪个页面链接访问过来的 $http_user_agent 记录客户端浏览器的信息 $http_x_forwarded_for 记录客户端的ip 虚拟主机 web虚拟主机: 就是虚拟出来的主机,实质上是在一台物理主机上发布多个网站。实现web虚拟主机的方法有基于IP、 端口、域名。
基于IP的虚拟主机: 准备工作:准备网站主页目录和主页,给ens33网卡临时设置192.168.11.21和192.168.11.22这两个IP。 mkdir -pv /11 /12 echo www.11.com > /11/index.html echo www.12.com > /12/index.html ifconfig ens33:1 192.168.11.21/24 up ifconfig ens33:2 192.168.11.22/24 up ifconfig 或 ip a 创建虚拟主机的配置文件: mkdir /usr/local/nginx/conf.d grep -n include /usr/local/nginx/conf/nginx.conf sed -i '18a\ include /usr/local/nginx/conf.d/*.conf;' /usr/local/nginx/conf/nginx.conf grep -n include /usr/local/nginx/conf/nginx.conf vim /usr/local/nginx/conf.d/ip.conf 基于IP的虚拟主机配置文件代码如下 server { listen 192.168.11.21:80; 监听192.168.11.21 IP的80号端口 server_name web.11.com; 服务器的名称(域名,即网址) location / { 定位设置(也称位置设置) root /11; 网站主页的根目录 index index.html index.htm; 默认的主页文件索引列表 } } server { listen 192.168.11.22:80; server_name web.12.com; location / { root /12; index index.html index.htm; } } 本地测试: nginx -t nginx -s reload curl 192.168.11.21 curl 192.168.11.22 11/34
基于端口的虚拟主机: server { listen 192.168.11.21:8081; server_name web.11.com; location / { root /11; index index.html index.htm; } } server { listen 192.168.11.21:8082; server_name web.12.com; location / { root /12; index index.html index.htm; } }
本地测试: nginx -t nginx -s reload curl 192.168.11.21:8081 curl 192.168.11.21:8082
基于域名的虚拟主机: 1.域名解析 方法一:用/etc/hosts文件做本地域名解析 echo '192.168.11.11 web.11.com web.12.com' >> /etc/hosts ping -c 2 web.11.com ping -c 2 web.12.com 2.修改配置文件vim /usr/local/nginx/conf.d/ip.conf server { listen 80 default; #default 在浏览器中直接键入IP地址会进入这个; server_name web.11.com; location / { root /11; #发布/11目录 index index.html index.htm; } } server { listen 80; server_name web.12.com; location / { root /12; #发布/12目录 index index.html index.htm; } } server { listen 80; server_name www.baidu.com; location / { 12/34 root /baidu; #发布/baidu目录 index index.html index.htm; } } 本地测试: nginx -t nginx -s reload curl www.google.com curl www.163.com 在win7/10下访问测试: 首先,在c:\windows\system32\drivers\etc\hosts文件中添加如下内容 192.168.11.11 web.11.com web.12.com 然后,打开IE、UC、360、chrome、firefox浏览器,输入如下网址进行测试: web.11.com web.12.com 访问控制 访问控制: 有时我们会有这么一种需求,就是你的网站并不想提供一个公共的访问或者某些页面不希望公开,我们 希望的是某些特定的客户端可以访问.那么我们可以在访问时要求进行身份认证,就如给你自己的家门加一 把锁,以拒绝那些不速之客.我们在服务课程中学习过apache的访问控制,对于Nginx来说同样可以实现,并且 整个过程和Apache 非常的相似. 用户认证: location / { root /11; index index.html index.htm; auth_basic "haha"; auth_basic_user_file /usr/local/nginx/passwd.db; } apache认证用户账号的创建工具:htpasswd [查 which htpasswd] 查htpasswd文件由哪个包提供:yum provides htpasswd 安装htpasswd工具的软件:yum install -y httpd-tools [root@web html]# htpasswd -c /usr/local/nginx/passwd.db lucy 创建lucy用户,密码为0 New password: 0 Re-type new password:0 Adding password for user user1 [root@web html]# cat /usr/local/nginx/passwd.db htpasswd命令选项: -c 创建新的htpasswd账号文件,仅用于第1次 -m 以MD5方式加密用户密码 -D 删除指定的用户账号 本地测试: curl 192.168.11.11 匿名访问网站(无法访问),会报错401状态码 13/34 curl 192.168.11.11 -u lucy:0 使用此用户访问网站(正常访问) curl 192.168.11.11 -u alice:01 使用此用户访问网站(无法访问),因为passwd.db账号文件中没有此 用户 win7/10访问测试:打开IE、360、UC、chrome等浏览器,在地址栏中输入192.168.11.11回车,会提示 输入用户名、密码的对话框,输入正确的用户名和密码就可以访问到网站的内容。 访问控制(基于IP): location / { root /11; index index.html index.htm; allow 192.168.11.12; 允许此IP的客户端访问此网站 allow 192.168.11.11; 允许此IP的客户端访问此网站 #allow 192.168.11.0/24; 允许此网段的客户端访问此网站 deny all; 拒绝所有其他IP的客户端访问此网站 } 解释说明: order allow,deny allow from 192.168.10.0/24 deny from all deny/allow顺序:从上到下
网站的访问测试如下: 本地访问测试:curl 192.168.11.11 会报错403状态码 在node12上访问测试:curl 192.168.11.11 正常显示网页内容 win7/10访问测试:curl 192.168.11.11 状态访问 注意:此功能必须在编译安装时启用--with-http_stub_status_module模块。 状态访问统计: 在server中添加如下行 location ~ /status { stub_status on; access_log off; } 查看访问状态统计: 浏览器:http://192.168.11.111/status 刷新可得到如下变化结果 Active connections: 557 server accepts handled requests 服务器接受处理过的请求 36573075 36573075 43806112 Reading: 3 Writing: 16 Waiting: 538 Active connections 活动连接数 server accepts handled requests 14/34 nginx总共处理了36573075个连接, 成功创建36573075次握手 (相等表示中间没有失败的), 总共处理了 43806112个请求 (平均每次握手处理了1.2个数据请求). Reading nginx读取到客户端的Header信息数. Writing nginx返回给客户端的Header信息数. Waiting 开启keep-alive的情况下,这个值等于active - (reading + writing),意思就是Nginx说已经处理完正在等候 下一次请求指令的驻留连接.
查询http协议的头部信息:curl -i 192.168.11.111/status HTTP/1.1 200 OK Server: nginx/1.8.1 Date: Mon, 18 Mar 2019 01:45:08 GMT Content-Type: text/plain Content-Length: 100 Connection: keep-alive Active connections: 1 server accepts handled requests 20 20 20 Reading: 0 Writing: 1 Waiting: 0
http状态码及501-504错误 访问日志管理 必须记住的状态码功能:200、400、401、403、404、500 访问日志中常见错误代码(管理必备) 100 请求已接收,客户端可以继续发送请求 101 Switching Protocals服务器根据客户端的请求切换协议 200 一切正常 201 服务器已经创建了文档 202 已经接受了请求,但处理尚未完成 300 文档正常返回,但一些头部信息可能不正确 301 客户端请求的资源可以在其他位置找到 305 请求代理服务 400 请求语法错误 401 访问被拒绝 401.1 登录失败 403 资源不可用 403.6 IP地址被拒绝 403.9 用户数过多 404 无法找到指定资源 页面找不到 406 指定资源已找到,但MIME类型与客户端要求不兼容 407 要求进行代理身份验证 500 服务器内部错误 15/34 501 服务器不支持客户端请求的功能 501.3 服务器太忙 502 网关错误 503 服务不可用 504 网关超时,服务器处于维护或负载过高无法响应 505 服务器不支持客户端请求的HTTP版本 404 页面找不到 403 访问被拒绝 nginx的500,502,504错误解决方法 一、解决500错误: 1、500错误指的是服务器内部错误,也就是服务器遇到意外情况,而无法履行请求. 2、500错误一般有几种情况: (1)web脚本错误,如php语法错误,lua语法错误等. (2)访问量大的时候,由于系统资源限制,而不能打开过多的文件 3、一般分析思路: (1)查看nginx error log ,查看php error log (2)如果是too many open files,修改nginx的worker_rlimit_nofile参数,使用ulimit查看系统打开文件限制, 修改/etc/security/limits.conf (3)如果是脚本的问题,则需要修复脚本错误,并优化代码 (4)各种优化都做好,还是出现too many open files,那就要考虑做负载均衡,把流量分散到不同服务器上去 了 二、解决502,504错误 1、使用nginx代理,而后端服务器发生故障;或者php-cgi进程数不够用;php执行时间长,或者是php-cgi进 程死掉;已经fastCGI使用情况等都会导致502、504. 2、502 是指请求的php-fpm已经执行,但是由于某种原因而没有执行完毕,最终导致php-fpm进程终止. 一般来说,与php-fpm.conf的设置有关,也与php的执行程序性能有关,网站的访问量大,而php-cgi的进程数偏 少.针对这种情况的502错误,只需增加php-cgi的进程数. 具体就是修改/usr/local/php/etc/php-fpm.conf文件,将其中的max_children值适当增加. 这个数据要依据你的VPS或独立服务器的配置进行设置.一般一个php-cgi进程占20M内存,你可以自己计算 下,适量增多. /usr/local/php/sbin/php-fpm restart 然后重启一下. 3、504 表示超时,也就是客户端所发出的请求没有到达网关,请求没有得到可以执行的php-fpm 三、解决503错误 503 Service Temporarily Unavailable错误 单个ip并发设置过小会导致503报错 反向代理、负载均衡 nginx的反向代理***** 用nginx做反向代理,有负载均衡: 负载均衡策略: 1.轮循:风水轮流转 2.加权轮循:能者多劳,通过weight指定权重值。 16/34 3.ip hash:用hash算法 [root@nginx conf]# vim /usr/local/nginx/conf/nginx.conf http { include mime.types; default_type application/octet-stream; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; upstream qf { server 192.168.10.11:80; server 192.168.10.12; server 192.168.10.13; } server { listen 80; server_name www.nginx.com; index index.html index.htm; location / { proxy_pass http://qf; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
如果真实WEB服务的性能不同,为了保证每个apache-server都能够满足最大的访问. 可以加入权重,权重值越高,分到的请求越多. [root@nginx conf]# vim /usr/local/lnmp/nginx/conf/nginx.conf
upstream uplook { server 192.168.10.11 weight=1 max_fails=2 fail_timeout=30s; server 192.168.10.12 weight=2; server 192.168.10.13 backup; \backup:备份,其他服务器宕机后启用 sorry } 说明:max_fails是指定失败的retry重试次数 fail_timeout是指单次连接的重试超时时间
为了保证在短时间内,同一个客户端的请求不被分配到其他的apache-server上? [root@nginx conf]# vim nginx.conf
upstream back { ip_hash; server 172.16.0.10; server 172.16.5.100; server 172.16.16.100; } 17/34 客户端测试: 一直得到同一个页面.
nginx+(apache|nginx) ,实现后端的真实WEB服务器获取客户端真实IP 代理服务器(node11): vim /usr/local/nginx/conf.d/proxy.conf location / { #root html; #index index.html index.htm; proxy_pass http://webs; proxy_set_header Host $host; proxy_set_header X-Real-ip $remote_addr; proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; }
后端的真实WEB服务器: apache(node12): vim /etc/httpd/conf/httpd.conf主配置文件中修改如下代码(第196行) LogFormat "%h %l %u %t "%r" %>s %b "%{Referer}i" "%{X-Real-ip}i" "%{User-Agent}i "" combined 重启服务:systemctl restart httpd nginx: 安装real-ip模块 location / { root html; index index.html index.htm; set_real_ip_from 10.10.10.11; real_ip_header X-Real-ip; }
反向代理练习 反向代理 在计算机网络中,反向代理是代理服务器的一种。服务器根据客户端的请求,从其关系的一组或多 组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理 的IP地址,而不知道在代理服务器后面的服务器簇的存在[1]。 与前向代理(即正向代理)不同,前向代理作为客户端的代理,将从互联网上获取的资源返回给一个或多个 的客户端,服务端(如Web服务器)只知道代理的IP地址而不知道客户端的IP地址;而反向代理是作为服 务器端(如Web服务器)的代理使用,而不是客户端。客户端借由前向代理可以间接访问很多不同互联网 服务器(簇)的资源,而反向代理是供很多客户端都通过它间接访问不同后端服务器上的资源,而不需要 知道这些后端服务器的存在,而以为所有资源都来自于这个反向代理服务器。 反向代理在现时的互联网中并不少见,而另一些例子,像是CDN、SNI代理等,是反向代理结合DNS的一类 延伸应用。 18/34 首先,给ens33临时添加一个新IP地址192.168.11.111。 ifconfig ens33:111 192.168.11.111/24 up ip a 19/34 然后,新建proxy.conf代理的配置文件。 vim /usr/local/nginx/conf.d/proxy.conf 配置文件全文内容如下 server { listen 192.168.11.111:80; server_name proxy.qf.com; location / { proxy_pass http://12700696.ys168.com/; } location /images/ { root /data; } } 重启服务,并测试: nginx -t && nginx -s reload curl 192.168.11.111 注意:server_name基于端口、ip时可以注释,基于域名时不能省略
负载均衡: 负载:承受能力,载重能力。 均衡:平均分配 负载均衡器:将载重压力平均分配给不同的后端服务器。负载均衡器类似于现实生活中酒店的接单 员,后端的真实服务器类似于酒店里的厨房的厨师。 准备工作:后端web服务器准备(node12上做)。 yum install -y httpd systemctl restart httpd systemctl enable httpd cd /var/www/html ls mkdir -v www mail echo haha > /var/www/html/index.html echo w.qf.com > www/index.html echo mail.qf.com > mail/index.html curl 127.0.0.1/www/ curl 127.0.0.1/mail/ 用基于端口的方式发布www(port-8081)、mail(port-8082)目录的网站 rpm -ql httpd | grep vhost vim /etc/httpd/conf.d/port.conf Listen 8081 Listen 8082 <VirtualHost *:8081> ServerAdmin 12700696@qq.com DocumentRoot "/var/www/html/www" ServerName w.qf.com </VirtualHost> <VirtualHost *:8082> ServerAdmin 12700696@qq.com DocumentRoot "/var/www/html/mail" ServerName mail.qf.com </VirtualHost> 20/34 然后,重启httpd服务,做访问测试: systemctl restart httpd netstat -atunlp | grep :80 curl 127.0.0.1 curl 127.0.0.1:8081 curl 127.0.0.1:8082 后端真实服务器的准备工作完毕,请在node11主机上继续做nginx负载均衡。
负载均衡的配置代码:vim /usr/local/nginx/conf.d/proxy.conf upstream back { 定义一个名称为back的后端服务器群,名称中不允许用_下划线,否则会报400错误 server 192.168.11.12:80; server 192.168.11.12:8081; server 192.168.11.12:8082; } server { listen 192.168.11.111:80; server_name proxy.qf.com; location / { proxy_pass http://back/;
} location /images/ { root /data; } } 重启服务,并测试: nginx -t && nginx -s reload 打开IE浏览器:输入 192.168.11.111回车 缓存 1.定义一个简单nginx缓存服务器 [root@nginx ~]# vim /etc/nginx/nginx.conf upstream test{ server 192.168.10.21; } proxy_cache_path /usr/local/nginx/cache levels=1:2 keys_zone=test:20m max_size=1g; server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location / { proxy_pass http://test; proxy_set_header X-forwarded-for $proxy_add_x_forwarded_for; 21/34 proxy_set_header X-real-ip $remote_addr; proxy_cache test; proxy_cache_valid 200 10m; } } A客户---B代理商----C生产商 2.指令说明 proxy_cache_path 语法:proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size]; 默认值:None 使用字段:http 指令指定缓存的路径和一些其他参数,缓存的数据存储在文件中,并且使用代理url的哈希值作为关键字与 文件名。levels参数指定缓存的子目录数,例如: proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m; 文件名类似于:/data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c levels指定目录结构,可以使用任意的1位或2位数字作为目录结构,如 X, X:X,或X:X:X 例如: “2”, “2:2”, “1:1:2“,但是最多只能是三级目录。 所有活动的key和元数据存储在共享的内存池中,这个区域用keys_zone参数指定。one指的是共享池的名 称,10m指的是共享池的大小。 注意每一个定义的内存池必须是不重复的路径,例如: proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m; proxy_cache_path /data/nginx/cache/two levels=2:2 keys_zone=two:100m; proxy_cache_path /data/nginx/cache/three levels=1:1:2 keys_zone=three:1000m; 如果在inactive参数指定的时间内缓存的数据没有被请求则被删除,默认inactive为10分钟。一个名为 cache manager的进程控制磁盘的缓存大小,它被用来删除不活动的缓存和控制缓存大小,这些都在 max_size参数中定义,当目前缓存的值超出max_size指定的值之后,超过其大小后最少使用数据(LRU替 换算法)将被删除。内存池的大小按照缓存页面数的比例进行设置,一个页面(文件)的元数据大小按照 操作系统来定,如FreeBSD/i386下为64字节,FreeBSD/amd64下为128字节。 proxy_cache 语法:proxy_cache zone_name; 默认值:None 使用字段:http, server, location 设置一个缓存区域的名称,一个相同的区域可以在不同的地方使用。 在0.7.48后,缓存遵循后端的”Expires”, “Cache-Control: no-cache”, “Cache-Control: max-age=XXX”头部 字段,0.7.66版本以后,”Cache-Control:“private”和”no-store”头同样被遵循。nginx在缓存过程中不会处 理”Vary”头,为了确保一些私有数据不被所有的用户看到,后端必须设置 “no-cache”或者”maxage=0”头,或者proxy_cache_key包含用户指定的数据如$cookie_xxx,使用cookie的值作为 proxy_cache_key的一部分可以防止缓存私有数据,所以可以在不同的location中分别指定 proxy_cache_key的值以便分开私有数据和公有数据。 缓存指令依赖代理缓冲区(buffers),如果proxy_buffers设置为off,缓存不会生效。 proxy_cache_valid 语法:proxy_cache_valid reply_code [reply_code …] time; 默认值:None 使用字段:http, server, location 为不同的应答设置不同的缓存时间,例如: proxy_cache_valid 200 302 10m; 22/34 proxy_cache_valid 404 1m; 为应答代码为200和302的设置缓存时间为10分钟,404代码缓存1分钟。 如果只定义时间: proxy_cache_valid 5m; 那么只对代码为200, 301和302的应答进行缓存。 同样可以使用any参数任何应答。 proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m; 3.新建缓存目录 4.重新加载一下配置文件 5.测试 location nginx location在配置中的优先级 语法规则: location [=|~|~|^~] /uri/ { … } location表达式类型(必知) ~ 表示执行一个正则匹配,区分大小写 ~ 表示执行一个正则匹配,不区分大小写 ^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他location。 = 进行普通字符精确匹配。也就是完全匹配。 @ “@” 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files location优先级说明 在nginx的location和配置中location的顺序没有太大关系。正location表达式的类型有关。相同类型的表达 式,字符串长的会优先匹配。 以下是按优先级排列说明: 第一优先级:等号类型(=)的优先级最高。一旦匹配成功,则不再查找其他匹配项。 第二优先级:^~类型表达式。一旦匹配成功,则不再查找其他匹配项。 第三优先级:正则表达式类型(~ ~)的优先级次之。如果有多个location的正则能匹配的话,则使用正 则表达式最长的那个。 第四优先级:常规字符串匹配类型。按前缀匹配。 location优先级顺序示意图: = > ^~ > ~ ~ > / location优先级示例 配置项如下: location = / {
只匹配请求 /
[ configuration ] index index.html } location / {
匹配所有以 / 开头的请求。但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ] index b.html 23/34 } location /docs/ {
匹配所有以 /docs/ 开头的请求。但是如果有更长的同类型的表达式,则选择更长的表达式。
#如果有正则表达式可以匹配,则优先匹配正则表达式。 [ configuration C ] alias /web/dir1/dir2; index c.html; } location ^~ /images/ {
匹配所有以 /images/ 开头的表达式,如果匹配成功,则停止匹配查找。所以,即便有符合的正则表达
式location,也不会被使用 [ configuration D ] alias /web/images/; index img.html; } location ~* .(gif|jpg|jpeg)$ {
匹配所有以 gif jpg jpeg结尾的请求。但是 以 /images/开头的请求,将使用 Configuration D
[ configuration E ] root /web/images/; } 请求匹配示例 / -> configuration A /index.html -> configuration B /documents/document.html -> configuration C /images/1.gif -> configuration D /documents/1.jpg -> configuration E 注意,以上的匹配和在配置文件中定义的顺序无关。 ---- 练习准备: mkdir -v /usr/local/nginx/html/xx echo 'xx.com' > /usr/local/nginx/html/xx/index.html curl 192.168.11.11/xx/ 练习: 首先,备份/usr/local/nginx/conf.d的*.conf配置文件,然后配置location代码。 cd /usr/local/nginx/conf.d ls mkdir bak mv .conf bak/ cd /usr/local/nginx/conf vim nginx.conf 修改如下内容 44 location /xx/ { 然后,重启nginx服务,并做访问测试。 nginx -t & nginx -s reload curl 192.168.11.11/xx/ 24/34 location总结 Nginx Location配置总结 语法规则: location [=|~|~|^~] /uri/ { … } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求为/ static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。 ~ 开头表示区分大小写的正则匹配 ~* 开头表示不区分大小写的正则匹配 !~和!~分别为区分大小写不匹配及不区分大小写不匹配 的正则 / 通用匹配,任何请求都会匹配到。 多个location配置的情况下匹配顺序(优先级)为: 首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用匹配。当有匹配 成功时候,停止匹配,按当前匹配规则处理请求。 例子,有如下匹配规则: location = / { #规则A } location = /login { #规则B } location ^~ /static/ { #规则C } location ~ .(gif|jpg|png|js|css)$ { #规则D } location ~ .png$ { #规则E } location !~ .xhtml$ { #规则F } location !~* .xhtml$ { #规则G } location / { #规则H } 那么产生的效果如下: 访问根目录/, 比如http://localhost/ 将匹配规则A 访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H 访问 http://localhost/static/a.html 将匹配规则C 访问 http://localhost/a.gif, http://localhost/b.jpg 将匹配规则D和规则E,但是规则D顺序优先,规则E不 起作用,而 http://localhost/static/c.png 则优先匹配到规则C 访问 http://localhost/a.PNG 则匹配规则E,而不会匹配规则D,因为规则E不区分大小写。 访问 http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHTML不会匹配规则G,因为 25/34 不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想看实际应用中哪里会 用到。 访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候应该是 nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理服务器存 在。 所以实际使用中,个人觉得至少有三个匹配规则定义,如下: #直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 #这里是直接转发给后端应用服务器了,也可以是一个静态首页
第一个必选规则
location = / { proxy_pass http://tomcat:8080/index }
第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ { root /webroot/static/; } location ~* .(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } #第三个规则就是通用规则,用来转发动态请求到后端应用服务器 #非静态文件请求就默认是动态请求,自己根据实际把握 #毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了 location / { proxy_pass http://tomcat:8080/ } 三、ReWrite语法 last – 基本上都用这个Flag。 break – 中止Rewirte,不在继续匹配 redirect – 返回临时重定向的HTTP状态302 permanent – 返回永久重定向的HTTP状态301 1、下面是可以用来判断的表达式: -f和!-f用来判断是否存在文件 -d和!-d用来判断是否存在目录 -e和!-e用来判断是否存在文件或目录 -x和!-x用来判断文件是否可执行 2、下面是可以用作判断的全局变量 例:http://localhost:88/test1/test2/test.php $host:localhost $server_port:88 $request_uri:http://localhost:88/test1/test2/test.php $document_uri:/test1/test2/test.php $document_root:D:\nginx/html $request_filename:D:\nginx/html/test1/test2/test.php 26/34 四、Redirect语法 server { listen 80; server_name start.igrow.cn; index index.html index.php; root html; if ($http_host !~ “^star.igrow.cn$" { rewrite ^(.) http://star.igrow.cn$1 redirect; } } 五、防盗链 location ~ .(gif|jpg|swf)$ { valid_referers none blocked start.igrow.cn sta.igrow.cn; if ($invalid_referer) { rewrite ^/ http://$host/logo.png; } } 六、根据文件类型设置过期时间 location ~* .(js|css|jpg|jpeg|gif|png|swf)$ { if (-f $request_filename) { expires 1h; break; } } 七、禁止访问某个目录 location ~* .(txt|doc)${ root /data/www/wwwroot/linuxtone/test; deny all; } 一些可用的全局变量: $args $content_length $content_type $document_root $document_uri $host $http_user_agent $http_cookie $limit_rate $request_body_file $request_method $remote_addr $remote_port $remote_user $request_filename $request_uri $query_string $scheme $server_protocol $server_addr $server_name $server_port $uri 27/34 location案例OK nginx location指令详解 Nginx的HTTP配置主要包括三个区块,结构如下: http { //这个是协议级别 include mime.types; default_type application/octet-stream; keepalive_timeout 65; gzip on;
server { //这个是服务器级别 listen 80; server_name localhost; location / { //这个是请求级别 root html; index index.html index.htm; } } } root 、alias指令区别 location /img/ { alias /var/www/image/; } #若按照上述配置的话,则访问/img/目录里面的文件时,ningx会自动去/var/www/image/目录找文件 location /img/ { root /var/www/image; } #若按照这种配置的话,则访问www.baiud.com/img/目录下的文件时,nginx会去/var/www/image/img/ 目录下找文件。] 总结:alias是一个目录别名的定义,root则是最上层目录的定义。
警告:还有一个重要的区别是alias后面必须要用“/”结束,否则会找不到文件的。。。而root则可有可无~~ location区段 通过指定模式来与客户端请求的URI相匹配,基本语法如下: location [=|~|~|^~|@] pattern{……} 1、没有修饰符 表示:必须以指定模式开始,如: server { server_name baidu.com; location /abc { root /web/qf; index index.html index.htm index.php; …… } } 那么,如下是对的(即能模糊匹配到的访问): 28/34 http://baidu.com/abc http://baidu.com/abc?p1 http://baidu.com/abc/ http://baidu.com/abcde 2、=表示:必须与指定的模式精确匹配 server { server_name sish location = /abc { …… } } 那么,如下是对的: http://baidu.com/abc http://baidu.com/abc?p1 警告:?p1中的?号是从数据库中请求信息,p1是数据库表中的字段名。 如下是错的: http://baidu.com/abc/ http://baidu.com/abcde 3、~ 表示:指定的正则表达式要区分大小写 server { server_name baidu.com; location ~ ^/abc$ { …… } } 匹配以/开头,中间是ab,以c结尾且区分大小写的请求 那么,如下是对的: http://baidu.com/abc http://baidu.com/abc?p1=11&p2=22 如下是错的: http://baidu.com/ABC http://baidu.com/abc/ http://baidu.com/abcde 4、~ 表示:指定的正则表达式不区分大小写 server { server_name baidu.com; location ~* ^/abc$ { …… } } 匹配以/开头,中间是ab,以c结尾且不区分大小写的请求
那么,如下是对的: http://baidu.com/abc http://baidu..com/ABC http://baidu..com/abc?p1=11&p2=22 如下是错的: http://baidu..com/abc/ http://baidu..com/abcde 5、^~ 类似于无修饰符的行为,也是以指定模式开始,不同的是,如果模式匹配,那么就停止搜索其他 模式了。(必记) 6、@ :定义命名location区段,这些区段客户端不能访问,只可以由内部产生的请求来访问,如try_files 或error_page等 查找顺序和优先级 1:带有“=“的精确匹配优先 2:没有修饰符的精确匹配 3:正则表达式按照他们在配置文件中定义的顺序 29/34 4:带有“^~”修饰符的,开头匹配 5:带有“~” 或“~” 修饰符的,如果正则表达式与URI匹配 6:没有修饰符的,如果指定字符串与URI开头匹配 location优先级顺序示意图: = > ^~ > ~ ~ > / URL:是统一资源定位符(Uniform Resource Locators),对可以从互联网上得到的资源的位置和访问方 法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的 信息指出文件的位置以及浏览器应该怎么处理它。 例如:http://www.baidu.com/music/index.html就是一个URL地址。 URI:统一资源标识符(Uniform Resource Identifier,或URI)是一个用于标识某一互联网资源名称的字符 串。 ----------- Location区段匹配示例 location = / { [ configuration A ] }
只匹配 / 的查询.
location / { [ configuration B ] }
匹配任何以 / 开始的查询,但是正则表达式与一些较长的字符串将被首先匹配。
location ^~ /images/ { [ configuration C ] }
匹配任何以 /images/ 开始的查询并且停止搜索,不检查正则表达式。
location ~* .(gif|jpg|jpeg)$ { [ configuration D ] }
匹配任何以gif, jpg, or jpeg结尾的文件,但是所有 /images/ 目录的请求将在Configuration C中处理。
各 请求的处理如下例: ■/ → configuration A ■/documents/document.html → configuration B ■/images/1.gif → configuration C ■/documents/1.jpg → configuration D
动静分离 动:动态脚本请求;静:静态页面请求;分离:动态的请求和静态的请求在一台服务器分离出来,由nginx-webserver 处理静态页面请求,由 PHP 处理动态请求. 使用fastcgi: CGI:通用网关接口,web-server和动态的脚本语言之间进行通信的接口. fastCGI:高速的运行在web-server上的和动态的脚本语言之间进行通信的接口. 运行原理: fastcgi在linux下是socket,为了调用CGI程序,还需要一个应用程序-wrapper,这个wrapper绑定在 socket上. 30/34 (1)nginx将动态的HTTP请求交给 socket,通过 fastcgi接口,由wrapper接受请求,然后派生出一个线 程,调用请求数据; (2)wrapper将得到的数据通过 fastcgi接口通过 socket交给 nginx; (3)nginx把数据交给客户端. 请求过程:client客户端--->nginx代理服务器--->socket--->fastcgi--->数据服务器 (LAMP或Tomcat) 响应过程:client客户端<---nginx代理服务器<---socket<---fastcgi<---数据服务器 (LAMP或Tomcat) alias与root用法 Nginx的alias与root的用法区别 alias与root的用法区别: 最基本的区别:alias指定的目录是准确的,root是指定目录的上级目录,并且该上级目录要含有 location指定名称的同名目录。 location /abc/ { alias /home/html/abc/; } 这个配置实际上指向的是/home/html/abc/目录。 location /abc/ { root /home/html/abc/; } 这个指向的是/home/html/abc/abc/这个目录 URL-URI URL和URI 简单理解是这样的: 理解URI和URL的区别,我们引入URN这个概念。 URI = Universal Resource Identifier 统一资源标志符 URL = Universal Resource Locator 统一资源定位符 URN = Universal Resource Name 统一资源名称 这三者的关系如下图: 31/34 也就是说,URI分为三种,URL or URN or (URL and URI) URL代表资源的路径地址,而URI代表资源的名称。 通过URL找到资源是对网络位置进行标识,如: · http://example.org/absolute/URI/with/absolute/path/to/resource.txt · ftp://example.org/resource.txt 通过URI找到资源是通过对名称进行标识,这个名称在某命名空间中,并不代表网络地址,如: · urn:issn:1535-3613 例如: http://www.baidu.com/music/a/b/c/d/a.html location /URI_music/ { root /web/qf; } 译者:华科小涛:http://www.cnblogs.com/hust-ghtao/: 初学http协议,就被这两个相似的术语搞蒙了,查了很多资料,总算搞清楚了。(找资料还是英文啊,靠 谱。。。)。 本篇博客翻译自:https://danielmiessler.com/study/url_vs_uri/,是在是一片简单实用的好文,对帮我们 弄清概念很有帮助: 译文:
一直存在很多技术上的争论,其中最为妙的恐怕就是web地址应该叫什么的问题。通常情况就是这样: 有人把地址栏的内容叫“URL”,这时候有些人就来劲了:“不!其实那时URI。。。” 对于这种纠正的反应呢,通常也有这么几种情况,心眼小的就寻思这人赶紧走吧,淡定点的就耸耸肩表 示同意,火气大的就拔刀相向了好不? 那这篇文章呢,就对这个只是提供一个简单的总结,毕竟互黑也要黑到点子上是吧。 URI,URL,URN 从上面的那幅图可以看出来,一共有三个不同的概念URI,URL,URN。这讨论这样的问题时,最好的方法就 32/34 是回到原点啊,这里我们在RFC 3986: Uniform Resource Identifier (URI): Generic Syntax里面收集了点 资料: “A Uniform Resource Identifier (URI) 是一个紧凑的字符串用来标示抽象或物理资源。” “A URI 可以进一步被分为定位符、名字或两者都是. 术语“Uniform Resource Locator” (URL) 是URI的子 集, 除了确定一个资源,还提供一种定位该资源的主要访问机制(如其网络“位置”)。“ 那我们无所不知的维基百科把这段消化的很好,并描述的更加形象了: “URI可以分为URL,URN或同时具备locators 和names特性的一个东西。URN作用就好像一个人的名字,URL 就像一个人的地址。换句话说:URN确定了东西的身份,URL提供了找到它的方式。” 通过这些描述我们可以得到一些结论: · 首先,URL是URI的一种(通过那个图就看的出来吧)。所以有人跟你说URL不是URI,他就错了 呗。但也不是所有的URI都是URL哦,就好像蝴蝶都会飞,但会飞的可不都是蝴蝶啊,你让苍蝇怎么想! · 让URI能成为URL的当然就是那个“访问机制”,“网络位置”。e.g. http:// or ftp://.。 · URN是唯一标识的一部分,就是一个特殊的名字。 下面就来看看例子吧,当来也是来自权威的RFC: · ftp://ftp.is.co.za/rfc/rfc1808.txt (also a URL because of the protocol) · http://www.ietf.org/rfc/rfc2396.txt (also a URL because of the protocol) · ldap://[2001:db8::7]/c=GB?objectClass?one (also a URL because of the protocol) · mailto:John.Doe@example.com (also a URL because of the protocol) · news:comp.infosystems.www.servers.unix (also a URL because of the protocol) · tel:+1-816-555-1212 · telnet://192.0.2.16:80/ (also a URL because of the protocol) · urn:oasis:names:specification:docbook:dtd:xml:4.1.2 这些全都是URI, 其中有些事URL. 哪些? 就是那些提供了访问机制的. 总结 下面到了回答问题的时候了: 当我们替代web地址的时候,URI和URL那个更准确? 基于我读的很多的文章,包括RFC,我想说URI更准确。 别急,我有我的理由: 我们经常使用的URI不是严格技术意义上的URL。例如:你需要的文件在files.hp.com. 这是URI,但不是 URL--系统可能会对很多协议和端口都做出正 确的反应。 你去http://files.hp.com 和ftp://files.hp.com.可能得到完全不同的内容。这种情况可能更加普遍,想想不 同谷歌域名上的不同服务啊。 所以,用URI吧,这样你通常技术上是正确的,URL可不一定。最后“URL”这个术语正在被弃用。所以明智 吧少年! 结语 If you don’t mind being “that guy”, URI is probably the more accurate term to use. But if you are in the linguist / “use what’s understood” camp, feel free to go with URL. 标签: Network 平滑升级 平滑升级1.8.1到1.10.2:(必会) 可以在不中断服务的情况下,新的请求也不会丢失,使用新的 nginx 可执行程序替换旧的(当升级新 版本或添加/删除服务器模块时). 33/34 准备工作:下载nginx-1.10.3.tar.gz源码包 cd wget http://120.52.51.15/nginx.org/download/nginx-1.10.3.tar.gz tar xf nginx-1.10.3.tar.gz cd nginx-1.10.3 ls 1.查看老版本的编译选项: [root@clone1 ~]# /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.8.1 built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) built with OpenSSL 1.0.1e-fips 11 Feb 2013 TLS SNI support enabled configure arguments: --user=nginx --group=nginx --prefix=/usr/local/nginx --withhttp_stub_status_module --with-http_ssl_module 2.编译新版: [root@clone1 nginx]# cd nginx-1.10.2 [root@clone1 nginx-1.10.2]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx -- with-http_stub_status_module --with-http_ssl_module [root@clone1 nginx-1.10.2]# make 编译 3.用新编译的命令替换原来的命令 [root@clone1 nginx-1.10.2]# mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak 备份 旧版本 [root@clone1 nginx-1.10.2]# cp -av objs/nginx /usr/local/nginx/sbin/ 复制新版本的nginx可 执行程序 4.启用新的,关闭旧的(平滑将旧版本的进程转移到新版本上) [root@clone1 ~]# cat /usr/local/nginx/logs/nginx.pid [root@clone1 ~]# kill -USR2 $(cat /usr/local/nginx/logs/nginx.pid) 主进程将重命名它的 .pid 文件为 .oldbin,然后执行新的可执行程序,依次启动新的主进程和新的工作进 程. [root@clone1 ~]# cat /usr/local/nginx/logs/nginx.pid.oldbin [root@clone1 ~]# kill -WINCH $(cat /usr/local/nginx/logs/nginx.pid.oldbin) 给旧的主进发WINCH信号,把旧的主进程关闭,把所有请求转到新的主进程,但是原有的请求不会中断,有 新请求的时候发到新进程 注意:如果无法出现nginx.pid.oldbin文件,就无法做nginx进程的平滑迁移,那就只能做非平滑启动新版 本,即直接执行nginx -s quit退出服务,然后执行nginx来启动新版本的服务程序。
这时,因为旧的服务器还尚未关闭它监听的套接字,所以,通过下面的几步,你仍可以恢复旧的服务器: (kill -l) 1.发送 HUP (kill -1 nginx的pid等同于nginx -s reload)信号给旧的主进程 - 它将在不重载配置文件的 情况下启动它的工作进程 2.发送 QUIT (退出)信号给新的主进程,要求其从容关闭其工作进程 3.发送 TERM (终止)信号给新的主进程,迫使其退出 4.如果因为某些原因新的工作进程不能退出,向其发送 KILL 信号 新的主进程退出后,旧的主进程会由移除 .oldbin 前缀,恢复为它的 .pid 文件,这样,一切就都恢复到升级之前 了.
[root@clone1 ~]# kill -QUIT cat /usr/local/nginx/logs/nginx.pid.oldbin
34/34
如果尝试升级成功,而你也希望保留新的服务器时,发送 QUIT 信号给旧的主进程使其退出而只留下新的
服务器运行.
特殊情况的重新平滑升级测试流程:
如果做nginx平滑升级时,在“启用新的,关闭旧的 ”步骤kill无法生成nginx.pid.oldbin文件时,请将虚拟机
快照恢复到env-ok状态,然后重新编译安装nginx1.8.1版,再做nginx的平滑升级操作。因为这个问题是系
统某些程序冲突而导致无法生成nginx.pid.oldbin文件。