nginx gzip压缩提升网站速度
网页内容的压缩编码与传输速度优化
我们观察news.163.com的头信息
请求:
Accept-Encoding:gzip,deflate,sdch
响应:
Content-Encoding:gzip
Content-Length:36093
再把页面另存下来,观察,约10W字节,实际传输的36093字节
原因-------就在于gzip压缩上.
原理:
浏览器—请求----> 声明可以接受 gzip压缩 或 deflate压缩 或compress 或 sdch压缩
从http协议的角度看–请求头 声明 acceopt-encoding: gzip deflate sdch (是指压缩算法,其中sdch是google倡导的一种压缩方式,目前支持的服务器尚不多)
服务器–>回应—把内容用gzip方式压缩(类似于二进制文件)---->发给浏览器
浏览<-----解码gzip-----接收gzip压缩内容----
推算一下节省的带宽:
假设 news.163.com PV 2亿
210^8 * 910^4 字节 ==
210^8 * 9 * 10^4 * 10^-9 = 12K*G = 18T
节省的带宽是非常惊人的
gzip配置的常用参数
gzip on|off; #是否开启gzip
gzip_buffers 32 4K| 16 8K #缓冲(压缩在内存中缓冲几块? 每块多大?)
gzip_comp_level [1-9] #推荐6 压缩级别(级别越高,压的越小,越浪费CPU计算资源)
gzip_disable #正则匹配UA 什么样的Uri不进行gzip
gzip_min_length 200 # 开始压缩的最小长度(再小就不要压缩了,意义不在)
gzip_http_version 1.0|1.1 # 开始压缩的http协议版本(可以不设置,目前几乎全是1.1协议)
gzip_proxied # 设置请求者代理服务器,该如何缓存内容
gzip_types text/plain application/xml # 对哪些类型的文件用压缩 如txt,xml,html ,css,html是默认的可以不写
gzip_vary on|off # 是否传输gzip压缩标志
例子
配置可以写在http、server、location中都可以
,以server为例
server{
listen 80;
gzip on;
gzip_budders 32 4k;
gzip_comp_level 6;
gzip_min_length 200;
gzip_type text/css text/xml/ application/x-javascript
...
}
如果文件太小,压缩不会生效。
注意:
- 图片/mp3这样的二进制文件,不必压缩,因为压缩率比较小, 比如100->80字节,而且压缩也是耗费CPU资源的,因为图片/MP3是二进制文件,压缩率很小,文本文件压缩率很高。
- 比较小的文件不必压缩。
expires缓存提升网站负载
nginx的缓存设置 提高网站性能
对于网站的图片,尤其是新闻站, 图片一旦发布, 改动的可能是非常小的.我们希望 能否在用户访问一次后, 图片缓存在用户的浏览器端,且时间比较长的缓存.
可以, 用到 nginx的expires设置 .
nginx中设置过期时间,非常简单,
在location或if段里,来写.
格式
expires 30s;
expires 30m;
expires 2h;
expires 30d;
例子:
注意:这里的正则匹配,下面只需要访问192.168.11.xx即可,虽然没有访问具体的图片,但是页面中有,即这列的匹配其实不只是匹配地址栏,是通过前端页面调试后的network里的所有东西。
locatin ~ image{
//location ~* \.(jpg|jpej|gif|png)就会匹配任何图片,但是如果
//location ~* \.(jpg|jpej|gif|png|)最后的”|“,相当于|”“,即只要访问,包括
//”.“,比如index.html,jquery.js等都能匹配上。
root html;
//1天
expires 1d;
}
可以看到上图中的cache-control 是一天的秒数,即缓存1天;date是十月一号;expires,是十月二号,即过期时间是十月二号。
虽然上限的jquery.js也有from cache,但是点进去查看详细信息,只有png有expires,而jquery.js没有。
(注意:服务器的日期要准确,如果服务器的日期落后于实际日期,可能导致缓存失效)
另: 304 也是一种很好的缓存手段
原理是: 服务器响应文件内容是,同时响应etag标签(内容的签名,内容一变,他也变), 和 last_modified_since 2个标签值
浏览器下次去请求时,头信息发送这两个标签, 服务器检测文件有没有发生变化,如无,直接头信息返回 etag,last_modified_since
浏览器知道内容无改变,于是直接调用本地缓存.
这个过程,也请求了服务器,但是传着的内容极少.
对于变化周期较短的,如静态html,js,css,比较适于用这个方式
反向代理实现nginx+apache动静分离
nginx反向代理服务器+负载均衡
用nginx做反向代理和负载均衡非常简单,
支持两个用法 1个proxy, 1个upstream,分别用来做反向代理,和负载均衡
以反向代理为例, nginx不自己处理php的相关请求,而是把php的相关请求转发给apache来处理.
----这不就是传说的”动静分离”,动静分离不是一个严谨的说法,叫反向代理比较规范.
修改配置文件
location ~ \.php{
//全部注释掉
}
这个时候再去访问 192.xx.xx.xx/test.php,会提示下载,因为此时的php对于nginx来说只是一个可以下载的php文本文件而已。
cd /usr/local/http
vim conf/httpd.conf
//Listen 8080
Listen 8080
# Virtual hosts
//打开这个注释,引入下面即将编辑的配置文件
Include conf/extra/httpd-vhosts.conf
//将所有的允许覆盖
<Directory />
AllowOverride all
//将Deny from all 改为allow from all
Allow from all
<Directory>
vim conf/extra/httpd-vhosts.conf
NameVirtualHost *:8080
//配置虚拟主机
<VirtualHost *:8080>
DocumentRoot ”/usr/local/nginx/html“
ServerName "192.xx.xx.xx"
</VirtualHost>
./bin/apachectl restart//重启apache
浏览器访问: http://192.xx.x.xx:8080/indexheml
apache配置成功
设置反向代理
//之前的依赖是nginx,这里重新添加依赖
cd php-5.4.19
make clean
./configure --prefix=/usr/local/fastphp \
--with-mysql=mysqlnd \
--enable-mysqlnd \
--with-gd \
--enable-gd-native-ttf \
--enable-gd-jis-conv
//一定要这一行,说明是fpm形式运行
//为什么一定要用fpm形式,因为php和nginx是两个独立的进程
//--enable-fpm
//如果安装过程中穿什么问题就把/usr/local/fastphp \文件删除重新开始
//将--enable-fpm替换为下面这句话,--enable-fpm意思是php是一个独立进程,
//下面这句话的意思是php是apache的一个模块
--prefix=/usr/local/php --with-apxs2=/usr/local/httpd/bin/apxs
cd /usr/local/nginx
vim conf/nginx.conf
//修改为
location ~ \.php{
proxy_pass 192.xx.xx.xx:8080
}
浏览器访问:http://192.xx.xx.xx/test.php
查看apache日志
more /usr/local/httped/logs/dummy-host.example.com-access.log
....
...GET /ecshop/index.html ...
说明本次访问是apache完成的。
查看nginx日志
more logs/access.log
...
...GET /image/logo.png
说明图片是nginx访问的
nginx实现负载均衡
如果:
location ~ \.php{
proxy_pass 192.xx.xx.xx:8080
proxy_pass 192.xx.xx.xx:8081
}
执行reload配置文件,发现报错,因为proxy_pass只允许配置一个
反向代理后端如果有多台服务器,自然可形成负载均衡,
但proxy_pass如何指向多台服务器?
把多台服务器用 upstream指定绑定在一起并起个组名,
然后proxy_pass指向该组
//添加上游服务器
upstream imgserver{
server 192.xx.xx.xx:81 weight=1(权重) max_fails=2 (两次连不上就算失败了)fail_time=3(几秒钟算是服务器连不上);
server 192.xx.xx.xx:82 weight=1(权重) max_fails=2 (两次连不上就算失败了)fail_time=3(几秒钟算是服务器连不上);
}
//添加新的虚拟主机
server{
listen 81;
server_name localhost;
root html/image;
access_log logs/81-access.log mian;
}
server{
listen 82;
server_name localhost;
root html/image;
access_log logs/82-access.log mian;
}
//配置完上面两个访问 http://192.xx.xx.xx:81(82)/logo.png,检验是否能够成功访问
//下面是原来的80虚拟主机
server{
listen 80;
location ~* \.(jpg|jpeg|gif|png)${
//将原来代理给主机,变成上面定义的上游服务器,具体的负载均衡在上游服务器进行
proxy_pass http://imgserver;
}
}
./sbin/nginx -s reload
地址栏访问http://xxxx.png
查看日志
cd logs
ls
//发现有如下的目录
81-access.log 82-access.log
只要是图片,就会走这里
不断访问,发现两个日志分布均匀
默认的均衡的算法很简单,就是针对后端服务器的顺序,逐个请求.
也有其他负载均衡算法,如一致性哈希,需要安装第3方模块.
(自行预习nginx第3方模块的安装,以安装ngx_http_upstream_consistent_hash为例)
假如本地的ip为 xxx.xx.xx.100,通过access.log,发现是100,可是通过81-access.log,发现是通过xxx.xx.xx.200访问的
因为后端经过了nginx代理,客户端的ip被前端所接受,但是前端多了代理请求后端,后端只能识别到nginx。
反向代理导致了后端服务器的IP,为前端服务器的IP,而不是客户真正的IP,怎么办?
location ~ \.php${
//传递请求给代理的时候,设置头信息,X_Forwarded_For为访问的地址
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://xx.xx.xx.xx:8080;
}
./sbin/nginx -s reload
tail logs/81-access.log
//发现开始显示的还是200,可是每行日志的字后有一个“xxx.xxx.xx.100”,
//即将真实的ip复制给了头信息X_Forwarded_For