1. 关于mime type
HTTP request里面有一个头叫 Accept,列出浏览器可以接受的mime type,HTTP response 的Content-Type 的值 在Accept 里面。我的理解是Nginx 会根据请求的文件的扩展名来决定返回什么 Content-Type,除非后端Web程序手动设置了Content-Type,如果Web程序没设置,Nginx也没找到对应文件的扩展名的话,就使用默认的Type,这个在Nginx 里用 default_type定义,比如 default_type application/octet-stream; 。
mime type 和 文件扩展名的对应关系一般放在 mime.types 里,然后 用 include mime.types; 加载,mime.types 文件里其实就是用 types 指令来定义的,比如下面是一个完整的定义:
types {
# Audio
audio/midi mid midi kar;
audio/mp4 aac f4a f4b m4a;
audio/mpeg mp3;
audio/ogg oga ogg opus;
audio/x-realaudio ra;
audio/x-wav wav;
# Images
image/bmp bmp;
image/gif gif;
image/jpeg jpeg jpg;
image/png png;
image/svg+xml svg svgz;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/webp webp;
image/x-icon ico cur;
image/x-jng jng;
# JavaScript
application/javascript js;
application/json json;
# Manifest files
application/x-web-app-manifest+json webapp;
text/cache-manifest manifest appcache;
# Microsoft Office
application/msword doc;
application/vnd.ms-excel xls;
application/vnd.ms-powerpoint ppt;
application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;
# Video
video/3gpp 3gpp 3gp;
video/mp4 mp4 m4v f4v f4p;
video/mpeg mpeg mpg;
video/ogg ogv;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
# Web feeds
application/xml atom rdf rss xml;
# Web fonts
application/font-woff woff;
application/font-woff2 woff2;
application/vnd.ms-fontobject eot;
application/x-font-ttf ttc ttf;
font/opentype otf;
# Other
application/java-archive jar war ear;
application/mac-binhex40 hqx;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.wap.wmlc wmlc;
application/xhtml+xml xhtml;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-chrome-extension crx;
application/x-opera-extension oex;
application/x-xpinstall xpi;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-bittorrent torrent;
application/zip zip;
application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;
application/octet-stream safariextz;
text/css css;
text/html html htm shtml;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/vtt vtt;
text/x-component htc;
text/x-vcard vcf;
}
那么一般在Nginx 里面这么配置即可:
# Define the MIME types for files.
include mime.types;
default_type application/octet-stream;
# Update charset_types due to updated mime.types
charset_types text/xml text/plain text/vnd.wap.wml application/x-javascript application/rss+xml text/css application/javascript application/json;
2. 关于gzip
# Compression
# Enable Gzip compressed.
gzip on;
# Setup gzip http version 1.0
gzip_http_version 1.0;
# Disable gzip compression for IE6, because IE6 supports gzip not friendly.
gzip_disable “MSIE [1-6].”;
# Compression level (1-9).
# 5 is a perfect compromise between size and cpu usage, offering about
# 75% reduction for most ascii files (almost identical to level 9).
gzip_comp_level 5;
# Don’t compress anything that’s already small and unlikely to shrink much
# if at all (the default is 20 bytes, which is bad as that usually leads to
# larger files after gzipping).
gzip_min_length 256;
# Compress data even for clients that are connecting to us via proxies,
# identified by the “Via” header (required for CloudFront).
gzip_proxied any;
# Tell proxies to cache both the gzipped and regular version of a resource
# whenever the client’s Accept-Encoding capabilities header varies;
# Avoids the issue where a non-gzip capable client (which is extremely rare
# today) would display gibberish if their proxy gave them the gzipped version.
gzip_vary on;
# Compress all output labeled with one of the following MIME-types.
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
# text/html is always compressed by HttpGzipModule
# This should be turned on if you are going to have pre-compressed copies (.gz) of
# static files available. If not it should be left off as it will cause extra I/O
# for the check. It is best if you enable this in a location{} block for
# a specific directory, or on an individual server{} level.
# gzip_static on;
注意几点:
1) gzip_http_version 默认是1.1,对于 1.0 的请求就不会压缩 (我们设置成1.0,表示HTTP1.0以上的版本都启动gzip)。
如果我们使用了proxy_pass 进行反向代理,那么 nginx 和后端的 upstream server 之间默认是用HTTP/1.0协议通信的。
The ngx_http_proxy_module makes it possible to transfer requests to another server.
It is an HTTP/1.0 proxy without the ability for keep-alive requests yet. (As a result, backend connections are created and destroyed on every request.) Nginx talks HTTP/1.1 to the browser and HTTP/1.0 to the backend server. As such it handles keep-alive to the browser.
此时如果 Nginx 连接后端,后端 也是1.1的话,Nginx 和 后端 之间就不会启用gzip了。
多说一句,在upstream 里,连接backend 如果想使用HTTP1.1,使用 proxy_http_version 指令(ngx_http_proxy_module 模块的指令;设置为1.1),一般配合 keepalive 指令使用来实现长连接(还要把header Connection 清空)。
2) IE6的某些版本对gzip的压缩支持很不好,会造成页面的假死,所以关闭IE6的gzip 。
3) gzip_types 定义哪些mime type 被gzip,mime type需要在types 指令当中被定义才可。
4) gzip_vary 指令的意义:
Enables or disables inserting the “Vary: Accept-Encoding” response header field if the directives gzip, gzip_static, or gunzip are active.
假设CDN/缓存 向Nginx 请求资源,Nginx 在响应头里插入“Vary: Accept-Encoding” , CDN/缓存会把 Accept-Encoding 的值 作为 传入参数 来做hash 计算,这样 Accept-Encoding 不一样,就代表 「资源」是不一样的(即使文件是一样的)。它的好处是可以根据客户端请求的 Accept-Encoding 来返回不一样的资源,包括是不是压缩 和 各种压缩格式。如果没有“Vary: Accept-Encoding”,CDN/缓存 可能给客户端错误的资源,比如客户端不支持压缩,却收到gzip压缩的资源,客户端就解析不了了。
这里多说两个指令:
sendfile on;
tcp_nopush on;
这两个用于优化文件传输,sendfile on 表示 通过文件描述符直接拷贝,而不是用read()/write();tcp_nopush on 这个选项只有在sendfile on的情况下才有效,tcp_nopush = on 会设置调用tcp_cork方法,意思是数据包不会马上传送出去,等到数据包最大或时,一次性的传输出去(说法可能不准)。
http://wiki.nginx.org/ReadMoreAboutTcpNopush
http://blog.csdn.net/hairetz/article/details/6549306
http://www.pagefault.info/?p=228
参考
nginx.conf 配置参考:
https://github.com/h5bp/server-configs-nginx/blob/master/nginx.conf
mime.types 参考:
https://github.com/h5bp/server-configs-nginx/blob/master/mime.types