一、文件说明
html:放静态文件
conf:配置文件
logs:日志
sbin:nginx 启动
二、命令
nginx #启动
nginx -s stop / nginx -s quit #停止服务
nginx -t 检查配置文件
nginx -s reload # 重启 nginx
nginx -c /usr/local/nginx/conf/nginx.conf #启动指定加载的配置文件
三、nginx.conf
user nobody; #主模块命令, 指定Nginx的worker进程运行用户以及用户组,默认由nobody账号运行。
worker_processes 1; #指定Nginx要开启的进程数。
#用来定义全局错设日志文件的路径和日志名称。
#日志输出级别有debug,info,notice,warn,error,crit 可供选择,其中debug输出日志最为详细,面crit(严重)输出日志最少。默认是error
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
pid logs/nginx.pid; #用来指定进程id的存储文件位置。当解开这个命令时,查看 nginx.pid 文件即可查看 nginx 运行的 pid
#use 其中参数use用来指定nginx的工作模式(这里是epoll,epoll是多路复用IO(I/O Multiplexing)中的一种方式),nginx支持的工作模式有select ,poll,kqueue,epoll,rtsig,/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,对于linux系统,epoll是首选。
#event.worker_connection 是设置nginx每个进程最大的连接数,默认是1024,所以nginx最大的连接数max_client=worker_processes * worker_connections。进程最大连接数受到系统最大打开文件数的限制,需要设置ulimit。
events {
worker_connections 1024;
}
http {
include mime.types; #主模块命令,对配置文件所包含文件的设定,减少主配置文件的复杂度,相当于把部分设置放在别的地方,然后在包含进来,保持主配置文件的简洁
default_type application/octet-stream; #默认文件类型,当文件类型未定义时候就使用这类设置的。
#指定nginx日志的格式
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路径 这里的 main 和log_format的 main 一致。
#能access_log 使用 log_format的日志格式
access_log logs/access.log main;
sendfile on;#开启高效文件传输模式(zero copy 方式),避免内核缓冲区数据和用户缓冲区数据之间的拷贝。
#tcp_nopush on;#开启TCP_NOPUSH套接字(sendfile开启时有用)
#客户端连接超时时间
keepalive_timeout 65;
#设置是否开启gzip模块
#gzip on;
server {
#虚拟主机的服务端口
listen 80;
#用来指定ip或者域名,多个域名用逗号分开
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
#地址匹配设置,支持正则匹配,也支持条件匹配,这里是默认请求地址,用户可以location命令对nginx进行动态和静态网页过滤处理
#虚拟主机的网页根目录
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;
#}
}
# 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;
# }
#}
}
四、 http
1.log_format 的格式参数:
五、 server
本机配置:
/usr/local/nginx/conf/nginx.conf 在 http 内层,与server同级添加
include /usr/local/nginx/conf/extra_conf/*.conf;
在/usr/local/nginx/conf/extra_conf 中添加 **.conf 文件,内配置单个 server 配置项
server{
listen 80;
server_name localhost;
location .......
}
1.location匹配
匹配规则
~ 波浪线表示执行一个正则匹配,区分大小写
~* 表示执行一个正则匹配,不区分大小写
^~ ^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
= #进行普通字符精确匹配
1.精准匹配
访问地址必须为 url/a/。如果是 url/a 那么这个不匹配
location =/a/ {
rewrite ^/ /a.html break;
root html/static/;
}
2.一般匹配
访问地址可为
url/b/a
url/b/a/
url/b/a/任何值…
但是下面不可
url/任何值/b/a
location /b/a {
rewrite ^/ /c.html break;
root html/static/;
}
访问地址如果是直接访问 html
html 文件路径:html/static/a.html
浏览器路径:http://127.0.0.1:8003/static/a.html
location /static {
#root声明,在html文件夹,查找/static/a.html文件
root html/;
}
3.正则匹配
访问地址可为:
url/b/c
url/b/c/
url/b/c/任何值…
url/任何值…/b/c/任何值…
location ~/b/c/* {
rewrite ^/ /e.html break;
root html/static/;
}
地址会先匹配 一般匹配,如果一般匹配匹配上了,还会再走正则匹配。最终走正则匹配
如上面 那个location 与下面这个 location 并存,则下面这个会失效。
location /b/c/a {
return 401;
}
url/b/d/a 访问 f.html
url/b/d/a/ 访问 g.html
url/b/d/a/ss 访问 g.html
location ^~ /b/d/a/ {
rewrite ^/ /g.html break;
root html/static/;
}
location ~ /b/d/* {
rewrite ^/ /f.html break;
root /usr/local/nginx/html/static/;
}
注:… 代表中间可以多级目录
2.nginx 指令
root
root 后的 test_html(默认是 html) 代表 nginx/html 文件夹
location / {
root test_html;
index index.html index.htm;
}
alias
寻址时/test 就相当于test_html文件夹的别称。如nginx 中有如下目录:test_html/test_static/a.html。
那么浏览器地址栏中输入如下地址即可找到a.html:/test/test_static/a.html
location /test {
alias test_html;
index index.html index.htm;
}
proxy_pass
反向代理
如原服务地址为:
http://127.0.0.1:9003/user/abc/bbc/select
nginx配置:
http://127.0.0.1:9003/user/abc/
最后浏览器访问地址:
http://127.0.0.1:8002/test/bbc/select
注:反向代理地址 有无『/』都不影响。只会对upstream 分发地址的时候有影响
location /test {
proxy_pass http://127.0.0.1:9003/user/abc/;
}
如果是如下配置,那么遵循下面 upstream 注2 的规则
location /test {
proxy_pass http://127.0.0.1:9003;
}
upstream
proxy_pass 后的 http://adminservice/; 对应upstream后的adminservice
注1:upstream 的被代理地址只能写到端口,不可127.0.0.1:9003/xx 这样,配置文件会不通过
注2:如果proxy_pass http://adminservice(不带"/"),那么最后拼接的地址会带上 location 中的/test。 如:浏览器地址为:http://127.0.0.1:8002/user/abc,那么最后的地址会为 127.0.0.1:9003/test/user/abc
如果 proxy_pass http://adminservice/(带"/"),那么最后的拼接地址就会不带 location 的 /test。如:浏览器地址为:http://127.0.0.1:8002/user/abc,那么最后的地址会为 127.0.0.1:9003/user/abc
因为请求接口时,端口后的域名段不可能都一样,所以实际中,proxy_pass必须带『/』
负载均衡
1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。
2、weight
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。down 暂时不参与负载
3、ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。
http{
upstream adminservice {
server 127.0.0.1:9003 weight=2;
server 127.0.0.1:9002;
}
server {
listen 8002;
server_name 127.0.0.1;
location /test {
proxy_pass http://adminservice/;
}
}
}
3.rewrite
格式:
rewrite regex replacement [flag]; flag=【break/last/redirect/permanent】
regex 是正则表达式
replacement 是替换值,新值
flag – 是处理标志
简单例子
浏览器 url:http://127.0.0.1:80/aa.html
最终访问:html/a.html
正则:『^/』表示适配任何值。
location 匹配了aa.html 进入 location中。 rewrite 的正则匹配为任何值。所以最终访问的页面是 a.html.root 指向 html 所以最终访问的是 html/a.html
location /aa.html {
rewrite ^/ a.html break;
root html;
}
rewrite没有命中
浏览器 url:http://127.0.0.1:80/aa.html
最终访问:html/aa.html
location 的匹配是 aa.html 的 url,而 rewrite 的匹配是 xx.js 的 url,所以 rewrite 会永远匹配不上。相当于没有 rewrite,所以最终访问的是html/aa.html ,html 下没有 aa.html 页面就会返回404
location /aa.html {
rewrite /*.js a.html break;
root html;
}
flag
/redirect(状态码302)/permanent(状态码301)
如果rewrite命中,发页面重定向,浏览器地址栏会变
浏览器初始地址栏:http://127.0.0.1:8004/bb
发送请求后地址栏:http://127.0.0.1:8004/b.html
location /bb {
rewrite ^/ /b.html permanent;
root html/;
}
break/last 内部重定向,换path值
break标记,停止执行后续命令
浏览器 url:http://127.0.0.1:8004/aa.html
进入页面:html/static/b.html
当进入到当前 location 中后,首先匹配到 b.html,然后执行 break。那么后面 rewrite a.html 命令就不会再执行了。
location /aa.html {
rewrite ^/ /b.html break;
rewrite ^/ /a.html break;
root html/static/;
}
last标记,会引发location重新匹配
浏览器 url:http://127.0.0.1:8004/ab.html
最终结果:页面报错
当通过匹配进入到了 ab.html的 location 中,但是 rewrite 又重定向到了 a.html 而且使用 last 修饰,发生了 location 重新匹配。这就相当于浏览器的 url 是http://127.0.0.1:8004/a.html 。所以就又进入到了 a.html location 当中,之后又 last 到了 ab.html,所以就引发了死循环。而且使用 last,以后中断他下面的语句。
ps:不要轻易使用last标签
location /a.html {
rewrite ^/ /ab.html last;
}
location /ab.html {
#rewrite ^/ /a.html last;
root html/static/;
}
4.nginx执行过程
说明:
1.通过域名、端口 进入对应的 server
2.path分为两部分:path1(匹配 location 部分)+path2
3.代理转发:
root:在目录里找path1+path2路径
alias:在目录里找path2路径
index:
#root/alias,若页面以 『/』结尾,则认为 path 只到目录,此时启动 index,找目录内 index 的文件
server{
listen 8005;
server_name 127.0.0.1;
#文件存放位置 html/static/a.html、b.html
#访问 http://127.0.0.1:8005/static 会报301(使用 curl 命令查看)
#访问 http://127.0.0.1:8005/static/ 访问到 a.html 页面
location /static {
root html/;
index a.html;
}
#访问 http://127.0.0.1:8005/target 会报301(使用 curl 命令查看)
#访问 http://127.0.0.1:8005/target/ 访问到 b.html 页面
location /target {
alias html/static/;
index b.html;
}
}
proxy_pass:
当后面跟的是 ip:端口
有『/』:那么就去对应服务器找 path2
没有『/』:那么就去对应服务器找 path1+path2
location /test {
#有 / 和没有 /
proxy_pass http://127.0.0.1:9003/;
proxy_pass http://127.0.0.1:9003;
}
当后面跟的是 ip:端口/aa/bb…
无论有没有 『/』,都去找对应服务器的 path2
六、nginx 内置变量
七、跨域
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,
从而克服AJAX只能同源使用的限制。
简单请求:
浏览器在跨源AJAX请求的头信息之中,自动在添加一个Origin字段(本次请求来自哪个源 )。
服务器根据这个值,在许可范围内,则在头信息包含 Access-Control-Allow-Origin 。
复杂请求:
会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求OPTIONS
需要跨域的原因
1.浏览器向A 域名发起请求 请求到了 father 页面,服务器将 html 页面发给浏览器,显示在浏览器当中
2.html 页面 再次发起 ajax 请求,向 B 域名发起请求。返回数据后浏览器发现第一次请求是从 A 域名发起的,第二次请求是从 B 域名发起的。两次请求域名不一样,发生了跨域问题。浏览器机制不允许这样的,所以会在 console 中报错:
注:第二次请求实际已经发送出去了,但是返回结果浏览器是不允许加载的。
解决方法:
1.浏览器第一次发起请求:
http://static.mynginx.com/static/
页面存在 nginx 位置:html/static/cors.html
本次请求 服务器 nginx 配置
server{
listen 80;
server_name static.mynginx.com;
location / {
root html/static/;
index cors.html;
}
}
2.请求到的页面
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<br />
<h2>a页面</h2>
<br />
<div id = "testcors"></div>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script type="text/javascript">
//$("#testcors").text("Hello world!");
$.ajax({
url:"http://www.mynginx.com/static/",
async :false,
type:"GET",
success:function(data){
console.log(data);
$("#testcors").html(data);
}
});
</script>
3.浏览器通过 ajax 发起第二次请求
http://www.mynginx.com/static/
页面存在 nginx 位置:html/static/cors.html
本次请求服务器 nginx 配置
发生作用地方:add_header Access-Control-Allow-Origin $allow_url;把请求第一次请求的域名记录注册,允许此域名可跨域访问。
server {
listen 80;
server_name www.mynginx.com;
# nginx 校验网址来源,符合那么把$http_origin 赋值给 $allow_url
if ( $http_origin ~ http://(.*).mynginx.com){
set $allow_url $http_origin;
}
#是否允许请求带有验证信息
add_header Access-Control-Allow-Credentials true;
#允许跨域访问的域名,可以是一个域的列表,也可以是通配符*
add_header Access-Control-Allow-Origin $allow_url;
#允许脚本访问的返回头
add_header Access-Control-Allow-Headers 'x-requested-with,content-type,Cache-Control,Pragma,Date,x-timestamp';
#允许使用的请求方法,以逗号隔开
add_header Access-Control-Allow-Methods 'POST,GET,OPTIONS,PUT,DELETE';
#允许自定义的头部,以逗号隔开,大小写不敏感
add_header Access-Control-Expose-Headers 'WWW-Authenticate,Server-Authorization';
#P3P支持跨域cookie操作
add_header P3P 'policyref="/w3c/p3p.xml", CP="NOI DSP PSAa OUR BUS IND ONL UNI COM NAV INT LOC"';
add_header test 1;
if ($request_method = 'OPTIONS') {
return 204;
}
location /static {
root html/;
index a.html;
}
}
八、防盗链
浏览器地址:http://www.mynginx.com/untitled.html可加载出所有图片
如果单独访问:http://www.mynginx.com/mall.jpg 显示404
conf
# /mall* 的走这个
location ^~ /mall {
# 验证 网址
valid_referers *.mynginx.com;
# 为 true 返回404
if ($invalid_referer) {
return 404;
}
root html;
}
untitled.html
<html>
<title>10:53:13 PM</title>
<head></head>
<body>
<img src='http://www.mynginx.com/qq.png' />
<img src='http://www.mynginx.com/chrome.png' />
<img src='http://www.mynginx.com/mall.jpg' />
</body>
</html>
九、缓存
location ^~ /qq.png {
expires 2s;#缓存2秒
# expires 2m;#缓存2分钟
# expires 2h;#缓存2小时
# expires 2d;#缓存2天
root html/gzip;
}
location ^~ /chrome.png {
expires 2m;#缓存2分钟
root html/gzip;
}
如下 qq.png 只缓存了2s,chrome.png 缓存了2分钟,所以在多次刷新浏览器后,chrome.png 图片
十、压缩
配置如下即可
location ~ /(.*)\.(html|js|css|jpg|jpeg|png|gif)$ {#覆盖/re/a.htm路径
gzip on; # 启用gzip压缩,默认是off,不启用
# 对js、css、jpg、png、gif格式的文件启用gzip压缩功能
gzip_types application/javascript text/css image/jpeg image/png image/gif;
gzip_min_length 1024; # 所压缩文件的最小值,小于这个的不会压缩
gzip_buffers 4 1k; # 设置压缩响应的缓冲块的大小和个数,默认是内存一个页的大小
gzip_comp_level 1; # 压缩水平,默认1。取值范围1-9,取值越大压缩比率越大,但越耗cpu时间
root html/gzip;
}
十一、https
生成密钥:
# 1、创建服务器私钥,命令会让你输入一个口令:
openssl genrsa -des3 -out server.key 1024
# 2、创建签名请求的证书(CSR):
openssl req -new -key server.key -out server.csr
# 3、在加载SSL支持的Nginx并使用上述私钥时除去必须的口令:
openssl rsa -in server.key -out server_nopass.key
# 4、最后标记证书使用上述私钥和CSR:
openssl x509 -req -days 365 -in server.csr -signkey server_nopass.key -out server.crt
conf
server {
listen 80;
listen 443 ssl;
server_name localhost;
//配置 https
ssl_certificate /usr/local/mytest/server.crt;
ssl_certificate_key /usr/local/mytest/server_nopass.key;
......
十二、 nginx 集群
未学习