基本命令
start nginx
nginx -s stop(当即中止)
nginx -s quit(平缓中止,有请求事不会意外中止)
nginx -s reload
遇到的坑:不要重复地去启动多个nginx进程,这样会致使你修改的nginx对应不上,能够经过资源管理器杀掉进程javascript
短链接:TCP创建链接->请求资源->响应资源-> 关闭链接 每次请求都要经历这样的过程
长链接:创建一次链接后,每次请求都复用该链接。
并行链接:并发的短链接
http1.0中为了支持长链接必须在请求头中指定css
Connection:keep-alive
在 HTTP 1.1 中 全部的链接默认都是持续链接,除非特殊声明不支持;如今大多数浏览器都默认是使用HTTP/1.1,因此keep-alive都是默认打开的html
Connection:close 指定不使用长链接
怎么判断一个请求数据接收完?
在响应头中若是有Tansfer-Encoding:chunked则表示body为流式输出,会被分红多个块,每一个块开始都会标识当前块的长度,此时body不须要长度;若是是非chunked则按照content-length来接收数据;不然等到服务端主动断开链接。
nginx中关于transfer-encoding的设置chunked_transfer_encoding on | off;
创建链接后服务端不是一直在等待下一次请求,经过nginx设置最大等待时间
nginx: http模块中能够设置超大等待时间 keepalive_timeout 65;
java
pipeline流水线做业
http1.1新特性,一个链接作屡次请求;
在keepaiive中第二个请求要等第一个请求响应彻底接受以后才能发起。
在pipeline中没必要等待第一个请求处理后就能够发起第二个请求,nginx会把读取的数据放在buffer中,在nginx处理完第一个请求时发现buffer中还有数据,就会任务剩下的数据是下一个请求的开始,而后处理下一个请求,不然设置为keepalivenode
扩展:TCP的keepalive:
AB在三次握手创建TCP链接以后,B忽然宕机了,可是A内核还会维护着AB之间的链接,浪费系统资源。引入keepalive机制,A定时给B发送空数据包,称为心跳包,一旦发现B网络不通则关闭链接。
Nginx涉及到tcp层面的keepalive只有一个:so_keepalivenginx
Http处理过程
初始化http request(读取客户端数据,生成HTTP Request对象,该对象包含了全部请求信息)
处理请求头
处理请求体
调用此请求的url或者location关联的handle
依次调用各phase handler处理(phase handler是指包含某阶段若干个handler)正则表达式
一个phase handler处理的任务chrome
当nginx读取到一个http Request的header时,首先寻找与请求关联的虚拟主机配置,若是找到则经历如下几个phase handler
1.server级别的url重写阶段,在读取请求头过程当中nginx会根据host和端口寻找对应的虚拟主机配置:json
server{ rewrite 规则 定向路径 重写类型 # 访问 /last.html 的时候,页面内容重写到 /index.html 中 rewrite /last.html /index.html last; } 规则:字符串或者正则来匹配目标url 定向路径:匹配到规则后要定向的url 重写类型: 1. last 完成重写浏览器地址栏url不变 2. break终止后面的匹配,地址栏url不变 3. redirect 302临时重定向,地址栏显示跳转后的url 4. permanent 301永久重定向,显示跳转后的url
2.location rewrite浏览器
location 与 location rewrite的区别:
rewrite regex replacement [flag]; 1.重写带http:// location /{ # 当匹配 正则表达式 /test/(.*)时 请求将被临时重定向到 http://www.$1.com rewrite /test/(.*) http://www.$1.com return 200 'ok' } # 在浏览器中输入 127.0.0.1:8080/test1/baidu # 则临时重定向到 www.baidu.com # 后面的 return 指令将没有机会执行了 2.重写不带http:// location / { rewrite /test/(.*) www.$1.com; return 200 "ok"; } # 发送请求以下 # curl 127.0.0.1:8080/test/baidu # ok # 此处没有带http:// 因此只是简单的重写。请求的 uri 由 /test/baidu 重写为 www.baidu.com # 由于会顺序执行 rewrite 指令 因此 下一步执行 return 指令 响应了 ok
TCP优化
http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60; ... ...
senfile on能够提升静态资源托管效率,是一个系统调用,不须要先read再write,没有上下文切换开销
tcp_nopush 在sendfile开启后才生效,启用后数据包累计必定的大小才会发送,提升了网络效率,减小了开销
tcp_nodelay 数据包累计到必定大小后尽快发送,nginx只会针对处于keepalive的TCP链接启用tcp_nodelay
keepalive_timeout 表示每一个tcp链接能够保持多少秒,默认是75秒,有些浏览器最可能是保持60秒,因此设置为60秒
TFO(TCP Fast open)优化策略
客户端第一次创建链接仍是要三次握手,不一样的是客户端会在第一个SYN设置一个fast-open的标志,服务端会生成fast-open cookie并放在SYN-ACK中,客户端就能够把cookie存起来之后syn用;
在这以后用户再创建TCP链接,发送syn包的同时会把cookie带上,而后能够直接带上http数据。换句话说在发送SYN包的时候把应用层数据发送出来,减小了一个RTT对性能的影响。
可是这种优化成本很是高须要操做系统、内核的支持(服务端和用户端都要支持)。
开启gzip
http { gzip on; gzip_vary on; gzip_comp_level 6; gzip_buffers 16 8k; gzip_min_length 1000; gzip_proxied any; gzip_disable "msie6"; gzip_http_version 1.0; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript; ... ... }
gzip_vary 用来输出vary响应头解决某些服务缓存问题
//请求头 Accept:*/* 接受任何MIME类型资源 Accept-Encoding:gzip,deflate,sdch 接受gzip,deflate,sdch压缩过的资源 Accept-Language:zh-CN,en-US;q=0.8,en;q=0.6 能够接受zh-ch,en-us,en;其中zh-cn的优先级最高(q 取值 0 - 1,最高为 1,最低为 0,默认为 1),服务端应优先返回zh-cn //响应头 Content-Type: text/javascript 表示文档确切的类型是text/javascript Content-Encoding: gzip 文档使用了gzip压缩 //没有content-language一般表示返回的是Accept-language权重最高的那种语言
Accept字段并不够用,若是要针对特定浏览器,如ie6就要使用到user-agent;cookie也可能做为服务器输出内容差别的依据。
若是服务器和客户端之间存在有缓存服务器,而服务器根据不一样的user-agent返回不一样的内容,缓存服务器却把针对特定浏览器的内容缓存下来统一返回,就会有问题。
因此http协议规定,若是服务器提供的内容是取决于user-agent(Accept以外的字段)请求头字段,响应头中必需要包含vary字段,并且vary字段必须包含user-agent。
//当内容取决于User-Agent和cookie时,vary字段应该相似于这样,也就是列出一个响应字段列表,告诉缓存服务器遇到同一个url的时候如何缓存和筛选合适的版本。 Vary:User-Agent, Cookie;
Content-Encoding在缓存服务器的问题
缓存服务器应该根据不一样的Content-Encoding缓存不一样的内容,再根据请求头的Accept-Encoding来返回合适的版本。为了不给客户端返回不合适的版本:
1.将请求头的Cache-control改成private
2.增长vary:Accept-Encoding明确告诉缓存服务器按照Accept-Encoding字段内容缓存不一样的版本。
以上的工做nginx都以gzip_vary: on搞定,至关于在启用了gzip的响应上加vary:Accept-Encoding
gzip_disable
接受一个正则匹配,请求的User-Agent匹配到后响应不会启用gzip。是为了解决某些浏览器启用gzip带来的问题。
gip_http_version
nginx默认启用http版本是Http/1.1,由于早期Http/1.0启用gzip有bug,如今基本忽略,全部能够指定gzip_http_version: 1.0;
开启缓存
优化代码逻辑的极限是移除全部极限;优化请求的极限是不发送任何请求。
http{ proxy_cache_path /home/nginx/proxy_cache_path levels=1:2 keys_zone=pnc:300m inactive=7d max-size=10g; }
/home/nginx/proxy_cache_path: 本地路径,缓存文件存放的路径
levels:默认全部文件放在/home/nginx/proxy_cache_path下,影响缓存性能,大部分场景是推荐使用2级目录来缓存文件。
post请求提交数据的四种格式
http协议规定post方法提交的数据主体必须方式消息主体中(entity-body),可是协议并无规定数据必须使用什么编码格式。开发者能够本身决定主体内容。服务器都内置了解析常见数据格式的功能,根据请求头的content-type来获取消息中的请求消息主体是以何种方式编码,再对主体进行解析。
Content-Type
application/x-www-form-urlencoded
原生的form提交不设置enctype属性时默认使用这种格式提交,提交格式按照val1=key1&val2=key2格式进行编码,key和val都进行了url转码。
POST http://www.example.com HTTP/1.1 Content-Type: application/x-www-form-urlencoded;charset=utf-8 title=test&sub%5B%5D=1&sub%5B%5D=2&sub%5B%5D=3
multipart/form-data
若是传输的是文件,还要包括文件名和文件类型信息。消息主体最后以--boundary--结束。
POST http://www.example.com HTTP/1.1 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="text" title ------WebKitFormBoundaryrGKCBY7qhFd3TrwA Content-Disposition: form-data; name="file"; filename="chrome.png" Content-Type: image/png PNG ... content of chrome.png ... ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
application/json