标签归档:nginx

Linux使用unzip命令解压其中的部分文件到指定文件夹

相信很多人都遇到过Candy的情况:

公司电商平台备份后文件大小多达10个G!海量小文件、图片、js、css等等……;

这造成了一种情况,如果不小心删除了一个文件而无法恢复的情况! 那就只能从备份文件中提取咯! 但是一想到为了提取几KB的一个文件,而unzip整个压缩文件。



请谨记以下命令:

unzip <Your zip file> “*mobile/要解压的文件” -d <要解压的目录>

如:unzip www.dnsdizhi.com.zip “Nginx/* ” Nginx/

* : 可以使用*做通配符,具体使用我就不废话了!
-d : -d 参数后面跟上你要解压文件到哪个目录;

使用 Nginx 实现灰度发布

灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式。AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来。

灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现、调整问题,以保证其影响度。

灰度发布常见一般有三种方式:

  • Nginx+LUA方式
  • 根据Cookie实现灰度发布
  • 根据来路IP实现灰度发布

本文主要将讲解根据Cookie和来路IP这两种方式实现简单的灰度发布,Nginx+LUA这种方式涉及内容太多就不再本文展开了。

A/B测试流程

Nginx根据Cookie实现灰度发布

根据Cookie查询Cookie键为version的值,如果该Cookie值为V1则转发到hilinux_01,为V2则转发到hilinux_02。Cookie值都不匹配的情况下默认走hilinux_01所对应的服务器。

两台服务器分别定义为:

1 2 
hilinux_01  192.168.1.100:8080 hilinux_02  192.168.1.200:8080 
  • 用if指令实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 
upstream hilinux_01 {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }  upstream hilinux_02 {  server 192.168.1.200:8080 max_fails=1 fail_timeout=60; }  upstream default {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }  server {  listen 80;  server_name  www.hi-linux.com;  access_log  logs/www.hi-linux.com.log  main;   #match cookie  set $group "default";  if ($http_cookie ~* "version=V1"){  set $group hilinux_01;  }   if ($http_cookie ~* "version=V2"){  set $group hilinux_02;  }   location / {   proxy_pass http://$group;  proxy_set_header   Host             $host;  proxy_set_header   X-Real-IP        $remote_addr;  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  index  index.html index.htm;  }  } 
  • 用map指令实现

在Nginx里面配置一个映射,$COOKIE_version可以解析出Cookie里面的version字段。$group是一个变量,{}里面是映射规则。

如果一个version为V1的用户来访问,$group就等于hilinux_01。在server里面使用就会代理到http://hilinux_01上。version为V2的用户来访问,$group就等于hilinux_02。在server里面使用就会代理到http://hilinux_02上。Cookie值都不匹配的情况下默认走hilinux_01所对应的服务器。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
upstream hilinux_01 {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }  upstream hilinux_02 {  server 192.168.1.200:8080 max_fails=1 fail_timeout=60; }  upstream default {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }   map $COOKIE_version $group { ~*V1$ hilinux_01; ~*V2$ hilinux_02; default default; }  server {  listen 80;  server_name  www.hi-linux.com;  access_log  logs/www.hi-linux.com.log  main;   location / {   proxy_pass http://$group;  proxy_set_header   Host             $host;  proxy_set_header   X-Real-IP        $remote_addr;  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  index  index.html index.htm;  }  } 

Nginx根据来路IP实现灰度发布

如果是内部IP,则反向代理到hilinux_02(预发布环境);如果不是则反向代理到hilinux_01(生产环境)。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 
upstream hilinux_01 {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }  upstream hilinux_02 {  server 192.168.1.200:8080 max_fails=1 fail_timeout=60; }  upstream default {  server 192.168.1.100:8080 max_fails=1 fail_timeout=60; }  server {  listen 80;  server_name  www.hi-linux.com;  access_log  logs/www.hi-linux.com.log  main;    set $group default;  if ($remote_addr ~ "211.118.119.11") {  set $group hilinux_02;  }  location / {   proxy_pass http://$group;  proxy_set_header   Host             $host;  proxy_set_header   X-Real-IP        $remote_addr;  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;  index  index.html index.htm;  } } 

如果你只有单台服务器,可以根据不同的IP设置不同的网站根目录来达到相同的目的。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 
server {  listen 80;  server_name  www.hi-linux.com;  access_log  logs/www.hi-linux.com.log  main;   set $rootdir "/var/www/html";  if ($remote_addr ~ "211.118.119.11") {  set $rootdir "/var/www/test";  }   location / {  root $rootdir;  } } 

到此最基本的实现灰度发布方法就讲解完了,如果要做更细粒度灰度发布可参考ABTestingGateway项目。

ABTestingGateway是新浪开源的一个动态路由系统。ABTestingGateway是一个可以动态设置分流策略的灰度发布系统,工作在7层,基于nginx和ngx-lua开发,使用redis作为分流策略数据库,可以实现动态调度功能。

ABTestingGateway:https://github.com/CNSRE/ABTestingGateway

https://www.hi-linux.com/posts/34319.html

nginx+php-fpm,使用Unix Socket还是tcp方式连接?

将Nginx与FastCGI的通信方式由TCP改为Unix Socket。TCP在高并发访问下比Unix Socket稳定,但Unix Socket速度要比TCP快”,看来这是真的存在。两者各有优缺点啊

1.worker_processes 越大越好(一定数量后性能增加不明显)


2.worker_cpu_affinity 所有cpu平分worker_processes 要比每个worker_processes 都跨cpu分配性能要好;不考虑php的执行,测试结果worker_processes数量是cpu核数的2倍性能最优

3.unix domain socket(共享内存的方式)要比tcp网络端口配置性能要好
不考虑backlog,请求速度有量级的飞跃,但错误率超过50%
加上backlog,性能有10%左右提升

4.调整nginx、php-fpm和内核的backlog(积压),connect() to unix:/tmp/php-fpm.socket failed (11: Resource temporarily unavailable) while connecting to upstream错误的返回会减少
nginx:
配置文件的server块
listen 80 default backlog=1024;

php-fpm:
配置文件的
listen.backlog = 2048

kernel参数:
/etc/sysctl.conf,不能低于上面的配置
net.ipv4.tcp_max_syn_backlog = 4096
net.core.netdev_max_backlog = 4096

5.增加单台服务器上的php-fpm的master实例,会增加fpm的处理能力,也能减少报错返回的几率
多实例启动方法,使用多个配置文件:
/usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm.conf &
/usr/local/php/sbin/php-fpm -y /usr/local/php/etc/php-fpm1.conf &

nginx的fastcgi配置
    upstream phpbackend {
#      server   127.0.0.1:9000 weight=100 max_fails=10 fail_timeout=30;
#      server   127.0.0.1:9001 weight=100 max_fails=10 fail_timeout=30;
#      server   127.0.0.1:9002 weight=100 max_fails=10 fail_timeout=30;
#      server   127.0.0.1:9003 weight=100 max_fails=10 fail_timeout=30;
      server   unix:/var/www/php-fpm.sock weight=100 max_fails=10 fail_timeout=30;
      server   unix:/var/www/php-fpm1.sock weight=100 max_fails=10 fail_timeout=30;
      server   unix:/var/www/php-fpm2.sock weight=100 max_fails=10 fail_timeout=30;
      server   unix:/var/www/php-fpm3.sock weight=100 max_fails=10 fail_timeout=30;
#      server   unix:/var/www/php-fpm4.sock weight=100 max_fails=10 fail_timeout=30;
#      server   unix:/var/www/php-fpm5.sock weight=100 max_fails=10 fail_timeout=30;
#      server   unix:/var/www/php-fpm6.sock weight=100 max_fails=10 fail_timeout=30;
#      server   unix:/var/www/php-fpm7.sock weight=100 max_fails=10 fail_timeout=30;
    }

        location ~ \.php* {
            fastcgi_pass   phpbackend;
#           fastcgi_pass   unix:/var/www/php-fpm.sock;
            fastcgi_index index.php;
       ……….
       }

6.测试环境和结果

内存2G
swap2G
cpu 2核 Intel(R) Xeon(R) CPU E5405  @ 2.00GHz
采用ab远程访问测试,测试程序为php的字符串处理程序


1)在开4个php-fpm实例,nginx 8个worker_processes 每个cpu4个worker_processes ,backlog为1024,php的backlog为2048,内核backlog为4096,采用unix domain socket连接的情况下,其他保持参数不变

性能和错误率较为平衡,可接受,超过4个fpm实例,性能开始下降,错误率并没有明显下降
结论是fpm实例数,worker_processes数和cpu保持倍数关系,性能较高
影响性能和报错的参数为
php-fpm实例,nginx worker_processes数量,fpm的max_request,php的backlog,unix domain socket


10W请求,500并发无报错,1000并发报错率为0.9%

500并发:
Time taken for tests:   25 seconds avg.
Complete requests:      100000
Failed requests:        0
Write errors:           0
Requests per second:    4000 [#/sec] (mean) avg.
Time per request:       122.313 [ms] (mean)
Time per request:       0.245 [ms] (mean, across all concurrent requests)
Transfer rate:          800 [Kbytes/sec] received avg.

1000并发:
Time taken for tests:   25 seconds avg.
Complete requests:      100000
Failed requests:        524
   (Connect: 0, Length: 524, Exceptions: 0)
Write errors:           0
Non-2xx responses:      524
Requests per second:    3903.25 [#/sec] (mean)
Time per request:       256.197 [ms] (mean)
Time per request:       0.256 [ms] (mean, across all concurrent requests)
Transfer rate:          772.37 [Kbytes/sec] received

2)在其他参数不变,unix domain socket换为tcp网络端口连接,结果如下

500并发:
Concurrency Level:      500
Time taken for tests:   26.934431 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Requests per second:    3712.72 [#/sec] (mean)
Time per request:       134.672 [ms] (mean)
Time per request:       0.269 [ms] (mean, across all concurrent requests)
Transfer rate:          732.37 [Kbytes/sec] received

1000并发:
Concurrency Level:      1000
Time taken for tests:   28.385349 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Requests per second:    3522.94 [#/sec] (mean)
Time per request:       283.853 [ms] (mean)
Time per request:       0.284 [ms] (mean, across all concurrent requests)
Transfer rate:          694.94 [Kbytes/sec] received

与1)比较,有大约10%的性能下降

7. 5.16调整fpm的max_request参数为1000,并发1000报错返回降到200个以下,
Transfer rate在800左右

使用nginx配置多个php-fastcgi负载均衡

配置还是非常简单的,充分体现了nginx的强大与配置的简单。

应用的最前端是一台nginx服务器,所有静态的内容都由nginx来处理,而将所有php的 请求都分摊到下游的若干台

运行PHP fastcgi守护进程的服务器中,这样可以以一种廉价的方案来实现对系统负载的分摊,扩展系统的负载能力。

三台php-fastcgi服务器的ip地址分别为:

          172.16.236.110 ,   172.16.236.111,     172.16.236.112

运行php-fastcgi进程时,需要让php-cgi监听到服务器的局域网地址(分别如上所示),而不是之前一般都是监听的

本地地址(127.0.0.1)。

以 172.16.236.110这台服务器为例:

 
/usr/local/php5/bin/php-cgi -b 172.16.236.110:9000

或许你用spawn-fcgi来启动php-fcgi,那么就是这样(供参考,其实也就是修改监听的地址和端口即可):

 
/usr/local/lighttpd/bin/spawn-fcgi -f /usr/local/php5/bin/php-cgi -a 172.16.236.110 -p 9000

又或许你是用php-fpm来管理php-fcgi,那么你需要修改php-fpm的配置:

 
vim  /usr/local/php5/etc/php-fpm.conf

找到这个配置项(其中的地址可能需要根据你自己环境来调整)



<value< span=”” style=”word-wrap: break-word;”> name=”listen_address“>127.0.0.1:9000>

修改为:

<value< span=”” style=”word-wrap: break-word;”> name=”listen_address>172.16.236.110:9000>



修改完毕后,重启你的php-fpm进程。

然后按照上面的步骤,依次修改其他php fastcgi服务器。

php方面的工作暂时就是这些,下面修改nginx。

 
vim  /usr/local/nginx/conf/nginx.conf

在配置文件的http段内增加类似如下的配置:

1
2
3
4
5
upstream myfastcgi { server 172.16.236.110 weight=1; server 172.16.236.111 weight=1; server 172.16.236.112 weight=1; }

我这里三台php fastcgi服务器的权重是相同的,所以其中的weight值都是1,如果你的php fastcgi服务器需要分主次,那么

可以通过调整其weight值来达到目的。比如以第一台服务器为主,其他两台为辅,则就是这样:

1
2
3
4
5
upstream myfastcgi { server 172.16.236.110 weight=1; server 172.16.236.111 weight=2; server 172.16.236.112 weight=2; }

然后找到原来nginx关于php fastcgi配置的部分,比如:

1
2
3
4
5
6
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }

将其中的fastcgi_pass那一段改为:



fastcgi_pass myfastcgi;

其中的myfastcgi也就是上面刚刚配置的php fastcgi均衡器的名字了。

完了以后,重启nginx即可。

简单吧,就通过这么几个简单的配置,就可以实现一个经济高效的nginx、多php-fcgi的负载均衡解决方案了。

当然了,这样的方案运用到实际项目中 还需要进行一些细化的配置,主要是php方面还需要进一步配置

Caddy nginx服务器QUIC部署

Caddy 简介

Caddy是一个Go语言写的,易于使用的通用Web服务器。它具有如下的一些功能:

  • 配置简单:Caddy服务器的运行可以通过Caddyfile配置文件进行配置,Web服务配置起来非常简单。
  • 自动的HTTPS:它可以自动地为我们申请 Let’s Encrypt 域名证书,管理所有的密码学设施,并进行配置。
  • HTTP/2:默认支持HTTP/2(由Go标准库支持)
  • 虚拟主机托管:Caddy支持TLS的SNI。SNI是在2006年加入TLS的一个TLS扩展。客户端在TLS握手的Client Hello消息中,通过SNI扩展将请求的资源的域名发送给服务器,服务器根据SNI的域名来下发TLS证书。这样就可以在具有单个公网IP的同一台主机上部署多个不同的域名的服务。可以为Caddy服务的不同域名配置不同的证书和密钥。
  • QUIC支持:Caddy实验性地支持QUIC协议,以获取更好的性能。
  • TLS session ticket key rotation for more secure connections
  • 良好的可扩展性:因此Caddy非常方便针对自己的需求做定制。
  • 随处运行:这主要与Go应用程序的特性有关。Go的模块都被编译为静态库,这使得Go的应用程序在编译为可执行文件时都是静态链接的,因而依赖的动态库极少,这使得部署使用非常方便。

自动的HTTPS、HTTP/2支持、QUIC支持和随处运行这些特性非常有吸引力,特别是对QUIC的支持。

此外,Caddy的性能非常好。下面两幅图是我的静态个人博客站点,分别是用Caddy和nginx作为Web服务器,打开主页所需的加载时间对比:
Service with Caddy

Service with nginx

上面的图显示了以Caddy作为Web服务器,主页的加载时间只有680ms;下面的图显示以nginx作为Web服务器,主页的加载时间则长达1.99s,要慢接近2倍。

Caddy部署

Caddy应用程序不依赖于其它组件,且官方已经为不同的平台提供了二进制可执行程序。可以通过如下三种方式之一安装Caddy:

  • 在 下载页,通过浏览器定制自己需要的功能集,并下载相应的二进制可执行程序。
  • 预编译的 最新发行版 二进制可执行程序。
  • curl getcaddy.com 来自动安装:curl https://getcaddy.com | bash

将caddy的路径加如PATH环境变量中。之后可以 cd 进入网站的文件夹,并运行 caddy来提供服务。默认情况下,Caddy在2015端口上为网站提供服务。

要定制网站提供服务的方式,可以为网站创建名为Caddyfile的文件。当运行 caddy 命令时,它会自动地在当前目录下寻找并使用Caddyfile文件来为自己做配置。

要了解更多关于Caddyfile文件的写法,可以参考 Caddyfile 文档

注意生产环境网站默认是通过HTTPS提供服务的。

Caddy还有命令行接口。运行caddy -h 可以查看基本的帮助信息,或参考 CLI文档 来了解更多详情。

以Root运行:建议不要这样做。但依然可以通过像这样使用setcap来监听端口号小于1024的端口:sudo setcap cap_net_bind_service=+ep ./caddy

由源码运行

注意:需要安装 Go 1.7或更新的版本才可以。

  1. go get github.com/mholt/caddy/caddy
  2. cd 进入网站的目录
  3. 执行caddy(假设 $GOPATH/bin 已经在 $PATH 中了)

Caddy的 main() 再caddy子目录下。要编译Caddy,可以使用在那个目录下找到的 build.bash

在生产环境运行

Caddy项目官方不维护任何系统特有的集成方法,但下载的文档中包含了社区共享的 非官方资源,用以帮助在生产环境运行Caddy。

以何种方式运行Caddy全由自己决定。许多用户使用 nohup caddy & 就可以满足需求了。其他人使用 screen。有些用户需要再重启之后就运行Caddy,可以在触发重启的脚本中来做到这一点,通过给init脚本添加一个命令,或给操作系统配置一个service。

可以看一下我的个人博客站点的完整Caddyfile内容:

					
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
					
wolfcstech.com:80 www.wolfcstech.com:80 {
root /home/www-data/www/hanpfei-documents/public
redir 301 {
if {>X-Forwarded-Proto} is http
/ https://{host}{uri}
}
}
wolfcstech.com:443 www.wolfcstech.com:443 {
tls /home/www-data/www/ssl/chained.pem /home/www-data/www/ssl/domain.key
#tls test@admpub.com
root /home/www-data/www/hanpfei-documents/public
gzip
log ../access.log
}

启用QUIC

Caddy 0.9 已经实验性地提供了对QUIC的支持,这主要通过 lucas-clemente/quic-go 来实现。要尝试这个特性,可以在运行caddy时加上 -quic 标记:

					
1
					
$ caddy -quic

这样执行之后,则带有TLS加密的Web服务,在客户端支持QUIC时,将默认通过QUIC协议来完成数据的传输。

不启用QUIC时,在启动caddy之后,在服务器端查看已打开的端口号:

					
1
2
3
4
5
6
7
					
# lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
AliYunDun 1120 root 10u IPv4 2023899 0t0 TCP 139.196.224.72:40309->106.11.68.13:80 (ESTABLISHED)
. . . . . .
caddy 6163 root 6u IPv6 2338478 0t0 TCP *:80 (LISTEN)
caddy 6163 root 8u IPv6 2338479 0t0 TCP *:443 (LISTEN)
. . . . . .

而在通过如下命令:

					
1
					
# nohup ./caddy -quic &

启用QUIC提供Web服务之后,在服务器端查看已打开端口号,则可以看到如下内容:

					
1
2
3
4
5
6
7
8
9
					
# lsof -i -P
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
AliYunDun 1120 root 10u IPv4 2023899 0t0 TCP 139.196.224.72:40309->106.11.68.13:80 (ESTABLISHED)
. . . . . .
caddy 6222 root 6u IPv6 2338880 0t0 TCP *:80 (LISTEN)
caddy 6222 root 8u IPv6 2338881 0t0 TCP *:443 (LISTEN)
caddy 6222 root 9u IPv6 2338883 0t0 UDP *:80
caddy 6222 root 10u IPv6 2338885 0t0 UDP *:443
. . . . . .

Caddy 除了监听http的TCP 80端口和https 的TCP 443端口之外,还监听了UDP的80和443端口。

客户端支持

Chrome 52+ 支持QUIC而无需白名单,但需要确认 #enable-quic 标记已经被启用了。通过在Chrome浏览器的地址栏输入chrome://flags/

Enable QUIC

并根据需要启用QUIC。

然后通过Chrome打开你的网站,则它应该是以QUIC提供服务的!可以通过打开inspector 工具并进入Security tab来验证这一点。重新加载页面并点击来查看连接详情:

caddy005.png

如果你使用老版的Chrome,则为了省事,可以升级一下。

如果你不想升级,则可以:你将需要以特殊的参数来运行Chrome。再Mac上 (将YOUR_SITE替换为你的网站的实际域名)执行如下命令:

					
1
2
3
4
5
					
$ /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--user-data-dir=/tmp/chrome \
--no-proxy-server \
--enable-quic \
--quic-host-whitelist="YOUR_SITE" "YOUR_SITE"

QUIC的好处

QUIC是基于UDP的TLS+HTTP的可靠传输协议。它加速了TLS握手为只有一个往返,避免了TCP慢启动,并提供了网络切换时的可靠性。通过QUIC可以让网站加载更快且更可靠。

问题排解

首先,确保在Caddyfile文件中为域名做了适当的设置,还要确保在启动Chrome的命令行中为域名做了适当的设置。

接着,网站必须使用一个真实的可信的证书(至少,是在写的时候)。

如果那都是好的,而且你对Go语言比较了解,则你可以添加 import "github.com/lucas-clemente/quic-go/utils",并在Caddy的main()函数的某个地方调用utils.SetLogLevel(utils.LogLevelDebug)。那将提供非常详细的输出。(注意这个log设施不是一个公共的API)。

当你进入chrome://net-internals/#events,你应该看到一些QUIC事件被标为红色。

Net Events

坚持原创技术分享,您的支持将鼓励我继续创作!

https://www.wolfcstech.com/2017/01/09/Caddy%20Web%E6%9C%8D%E5%8A%A1%E5%99%A8QUIC%E9%83%A8%E7%BD%B2/

nginx 对文件(动态页面) 进行缓存 ( nginx content caching)

refer to: http://nginx.com/resources/admin-guide/caching/ 首先看一个完整的例子:

  proxy_cache_path /tmp/nginx_cache keys_zone=cache_one:100m
                       loader_threshold=300 loader_files=200 max_size=200m;
  server {
          listen 80;
          server_name  www.tidev.in tidev.in;
          client_max_body_size 500m;
          charset utf-8;
          location / {
              proxy_hide_header "cache-control";
              proxy_hide_header Expires;

              proxy_ignore_headers Set-Cookie;
              proxy_ignore_headers Cache-Control;
              proxy_ignore_headers Expires;
              proxy_ignore_headers X-Accel-Expires;

              proxy_cache cache_one;
              proxy_cache_valid any 60s; # 任何内容,都缓存60秒钟 proxy_pass          http://tidev_servers; proxy_redirect default;
              proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header    X-Real-IP $remote_addr;
              proxy_set_header    Host $http_host;
              proxy_next_upstream http_502 http_504 error timeout invalid_header;

              proxy_cache_key $host$uri$is_args$args;
          }
          location ~ ^/assets/ {
              root /opt/app/tidev.in/public;
              expires 1y;
              add_header Cache-Control public;
              add_header ETag ""; break;
          }
  }

  upstream tidev_servers{
         server localhost:3600;
         server localhost:3601;
         server localhost:3602;
         server localhost:3603;
  }

注意:  

1. nginx 建议使用 1.7.9 以上版本, 亲测 1.7.9, 1.8.0 可用. 1.4.x 不可用. 所以,不要使用ubuntu 默认的 apt-get install 方式的nginx. 它是1.4的.

2. proxy_cache_path 务必出现在 proxy_cache 关键字之前, (也就是说,如果你用了include sites-enabled/*; , 那么,这句话要放在 proxy_cache_path之后!) 否则会报错: nginx: [emerg] the size 10485760 of shared memory zone “cache_one” conflicts with already declared size 0  

3. proxy_cache_key 是关键. 

          location / { proxy_hide_header "cache-control"; proxy_hide_header Expires; proxy_ignore_headers Set-Cookie; proxy_ignore_headers Cache-Control; proxy_ignore_headers Expires; proxy_ignore_headers X-Accel-Expires; proxy_cache cache_one; proxy_cache_valid any 60s; # 任何内容,都缓存60秒钟 proxy_pass http://tidev_servers; proxy_redirect default; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_next_upstream http_502 http_504 error timeout invalid_header; proxy_cache_key $host$uri$is_args$args;
          }

nginx可以对某个请求进行缓存,

例子:

http {
    ...
    proxy_cache_path /data/nginx/cache keys_zone=one:10m; server {
        proxy_cache one;
        location / {
            proxy_pass http://localhost:8000;
        }
    }
}

设置好了允许缓存后,进一步可以设置它的过期时间: (iteration 如何解释。。需要动手弄一下)

参与cache 过程 的,有两个角色, cache manager 和 cache loader:

1. cache manager 会循环的检查 cache的状态。当它发现 缓存的文件超过了 max_size 这个数目后,就会删掉最少访问的cache page. 

2. cache loader: 仅仅在nginx启动后 随之启动一次。它把之前的cache 信息加载到 shared memory中去。这在nginx启动的前几分钟会拖累nginx的速度。

以上的iteration, 比 loader_threshold(默认是200ms) 要少。 每次加载的文件数目小于 loader_files(默认是100),每个iteration 间隔 loader_sleeps (默认50ms)。 

下面是个例子: 

proxy_cache_path /data/nginx/cache keys_zone=one:10m
                 loader_threshold=300 loader_files=200; 

指定某个URL 要缓存

如果某个response来自 proxy_server, 并且request是 GET/HEAD 方法,则nginx 默认会把它做缓存. 

而且默认使用的key就是 url ,你也可以指定这个key, 例如:

proxy_cache_key “$host$request_uri$cookie_user”;

如果我们希望某个 url 至少被请求5次之后才被缓存,就这样:

proxy_cache_min_uses 5;

如果希望对POST和 DELETE进行缓存:

proxy_cache_methods GET HEAD POST;

下面的例子:对于 200 , 302的response, 缓存 10分钟, 

proxy_cache_valid 200 302 10m;  # 对于 200, 302,缓存10分钟
proxy_cache_valid 404 1m;       # 缓存1分钟 
proxy_cache_valid any 10m;      # 对于所有的响应,都缓存10分钟。

也可以根据条件来判断是否使用cache: ( cookie 中的变量:nocache, parameter中的变量:nocache 或者 comment, 只要有一个 不是空,也不是 0, 那么这个request就不会使用cache) 

proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment;

对于下面的例子:压根就不使用cache:

proxy_no_cache $http_pragma $http_authorization;

下面是一个更大的例子:

http {
    ... # 定义了一个 proxy_cache_path, : proxy_cache_path /data/nginx/cache keys_zone=one:10m
                     loader_threshold=300 loader_files=200 max_size=200m; # 这个server中有两个backend, 对应两种不同的cache策略 server {
        listen 8080; # cache的名字叫做 one (注意上面的 keys_zone=one:10m) proxy_cache one; # 对所有的 / 请求,都尽可能长久的缓存,不存在过期 location / {
            proxy_pass http://backend1; }

        
        location /some/path {
            proxy_cache_valid any 1m; # 任何内容,都缓存1分钟 proxy_cache_min_uses 3; # 访问3次后,触发缓存 proxy_cache_bypass $cookie_nocache $arg_nocache$arg_comment; # 设置好不使用缓存的规则 proxy_pass http://backend2; }
    }
}

注意: 如何调试呢?

1. 要设置log format, 把日志打印出来. 例如,配置文件为: (注意其中的 $upstream_cache_status, 这个变量最重要, 从它我们可以知道, 是HIT 还是MISS )

    log_format my_format '$remote_addr - $remote_user [$time_local]  ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" $upstream_cache_status'; access_log logs/my_access.log my_format;

2. 要有对应的 ignore headers, 如果后端返回的结果中,增加了 cache-control (也有一说是 set-cookie) 或者 啥的,就不行了. 

server{
            proxy_ignore_headers "cache-control";
            proxy_hide_header "cache-control";
} 

下面是一个完整的 nginx.conf例子;

http{ # 其他内容  proxy_cache_path /tmp/nginx_cache keys_zone=cache_one:10m
                     loader_threshold=300 loader_files=200 max_size=200m; log_format my_format '$remote_addr - $remote_user [$time_local]  ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" $upstream_cache_status';

    access_log logs/my_access.log my_format;

    server {
        listen 80; 

        location / { 
            proxy_ignore_headers "cache-control";
            proxy_hide_header "cache-control";
            proxy_cache cache_one;
            proxy_cache_valid any 10s; # 任何内容,都缓存10秒钟 proxy_pass http://rails_api;
        }

    }
    upstream rails_api{
        server localhost:3000;
    }

缓存用的哪些文件?

我们可以在 proxy_cache_path中设置, 例如:

    proxy_cache_path /tmp/nginx_cache keys_zone=cache_one:10m loader_threshold=300 loader_files=200 max_size=200m;

然后, 找到 /tmp/nginx_cache 目录, 如果某个 cache被命中过, 就会看到出现一个以md5 结果命名的文件:

:/tmp/nginx_cache$ ll
total 20 drwxrwxrwx 2 nobody sg552 4096 Sep 10 11:39 ./
drwxrwxrwt 10 root   root 12288 Sep 10 11:38 ../
-rw------- 1 nobody nogroup 594 Sep 10 11:39 f8924891f34a941a8342ccd19c4cf290 

上面中, 这个文件 “f89…” 就是缓存文件. 它的内容如下.

���U���������Ud����0""b4945c5f2d4b62faae53f44f44a5e946"
KEY: http://rails_api/prices/say_hi
HTTP/1.1 200 OK
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: text/html; charset=utf-8
ETag: "b4945c5f2d4b62faae53f44f44a5e946" Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 90fbc91b-e5a4-4279-8832-5d484cba7ba8
X-Runtime: 0.007120 Connection: close Server: thin 1.6.2 codename Doc Brown time is: 2015-09-10 11:39:58 +0800 

可以看出, 该静态文件, 以文本的形式缓存了 所有的response信息.


来源;http://siwei.me/blog/posts/nginx-nginx-content-caching

Nginx配置支持HTTP2

从 2015 年 5 月 14 日 HTTP/2 协议正式版的发布到现在已经快有一年了,越来越多的网站部署了 HTTP2,HTTP2 的广泛应用带来了更好的浏览体验,只要是 Modern 浏览器都支持,所以部署 HTTP2 并不会带来太多困扰。

虽然 h2 有 h2c (HTTP/2 Cleartext) 可以通过非加密通道传输,但是支持的浏览器初期还是比较少的,所以目前部署 h2 还是需要走加密的,不过由于 Let’s Encrypt 大力推行免费证书和证书的廉价化,部署 h2 的成本并不高。

介绍

HTTP 2.0即超文本传输协议 2.0,是下一代HTTP协议。是由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis (httpbis)工作小组进行开发。是自1999年http1.1发布后的首个更新。

HTTP/2 协议是从 SPDY 演变而来,SPDY 已经完成了使命并很快就会退出历史舞台(例如 Chrome 将在「2016 年初结束对 SPDY 的支持」;Nginx、Apache 也已经全面支持 HTTP/2 ,并也不再支持 SPDY)。

一般的大家把 HTTP2 简称为 h2,尽管有些朋友可能不怎么愿意,但是这个简称已经默认化了,特别是体现在浏览器对 HTTP2 都是这个简写的。

配置

普通的 HTTPS 网站浏览会比 HTTP 网站稍微慢一些,因为需要处理加密任务,而配置了 h2 的 HTTPS,在低延时的情况下速度会比 HTTP 更快更稳定!

现在电信劫持事件频发,网站部署了 HTTPS 加密后可以杜绝大部分劫持,但不是完全。像电子商务行业对 HTTPS 加密可是标配啊,因此部署 h2 更是势在必行。

证书

这里是 免费和便宜 SSL 证书介绍 ,大家可以从这里购买或者申请免费的 SSL 证书,免得 Chrome 弹出红色的页面令人不悦,从而拒绝了大多数访客。

Web 服务器

说明

默认编译的 Nginx 并不包含 h2 模块,我们需要加入参数来编译,截止发文,Nginx 1.9 开发版及以上版本源码需要自己加入编译参数,从软件源仓库下载的则默认编译。 Tengine 可以同时部署 h2 和 SPDY 保证兼容性,Nginx 则是一刀切不再支持 SPDY。

安装/编译

如果你编译的 Nginx 不支持,那么在 ./configure 中加入:--with-http_v2_module ,如果没有 SSL 支持,还需要加入 --with-http_ssl_module

然后 make && make install 即可。

配置

主要是配置 Nginx 的 server 块, 。
修改相关虚拟机的 .conf 文件,一般在 /usr/local/nginx/conf/vhost/ 或者 /etc/nginx/conf/,具体参考你的环境指导,不懂请回复。

server { listen 443 ssl http2 default_server; server_name www.mf8.biz; ssl_certificate /path/to/public.crt; ssl_certificate_key /path/to/private.key; 

注:将 server_name www.mf8.biz; 中的 www.mf8.biz 替换为你的域名。

然后通过 /usr/local/nginx/sbin/nginx -t 或者 nginx -t 来检测是否配置正确,然后重启 Nginx ,即可。

检验

在 Chrome 浏览器上可以通过,HTTP/2 and SPDY indicator 来检验,如果地址栏出现蓝色的闪电就是 h2

也可以在 chrome://net-internals/#http2 中检查。注意版本要新,姿势要帅!

配置进阶

大家都知道去年的心血漏洞将 SSL 推到了风口浪尖,所以单单支持了 h2 ,我们任然需要对 SSL 做一些安全的优化!

配置赫尔曼密钥

openssl dhparam -out dhparam.pem 2048 // 在 ssh 运行, openssl 生成 2048 位的密钥而不是当作参数写入 nginx.conf 文件。 ssl_dhparam /path/to/dhparam.pem; //在 .conf 中配置 

禁止不安全的 SSL 协议,使用安全协议

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

禁止已经不安全的加密算法

ssl_ciphers
'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4';

也可以参考:ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;

缓解 BEAST 攻击

ssl_prefer_server_ciphers on;``` **启用 HSTS**

此举直接跳过 301 跳转,还降低了中间人攻击的风险!配置在 .conf 中即可 `add_header Strict-Transport-Security max-age=15768000;` **301 跳转** 80 端口跳转到 443 端口

server {
listen 80;
add_header Strict-Transport-Security max-age=15768000;
return 301 https://www.yourwebsite.com$request_uri;
}

 **缓存连接凭据** 

ssl_session_cache shared:SSL:20m;
ssl_session_timeout 60m;

 **OCSP 缝合** 

ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/cert/trustchain.crt;
resolver 119.29.29.29 233.6.6.6 valid=300s;

nginx支持http2,openssl 升级openssl-1.1.0h https A+

首先升级openssl 到 openssl-1.1.0h

wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz

tar -zxvf openssl-1.1.0h.tar.gz
cd openssl-1.1.0h

./config –prefix=/usr

make

make install

openssl version -a

nginx配置参考:

listen 443 ssl http2;
add_header Strict-Transport-Security max-age=15768001;
ssl_certificate /usr/local/nginx/conf/vhost/Nginx/1_www.dnsdizhi.com_bundle.crt;
ssl_certificate_key /usr/local/nginx/conf/vhost/Nginx/2_www.dnsdizhi.com.key;
ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  10m;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
ssl_prefer_server_ciphers   on;

完毕后可以用:https://www.ssllabs.com/ssltest/  或者 https://myssl.com/ 检查就是能达到A+,当然其实达到A就不错了。如facebook、v.qq.com、www.google.com都是A。区别在哪里?就是没有配置add_header Strict-Transport-Security max-age=15768001;,说真的就是不用配置的,没必要。

Nginx负载均衡的优缺点

Nginx的优点是:
1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是它目前广泛流行的主要原因之一,Nginx单凭这点可利用的场合就远多于LVS了。
2、Nginx对网络稳定性的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势之一;相反LVS对网络稳定性依赖比较大,这点本人深有体会;
3、Nginx安装和配置比较简单,测试起来比较方便,它基本能把错误用日志打印出来。LVS的配置、测试就要花比较长的时间了,LVS对网络依赖比较大。
3、可以承担高负载压力且稳定,在硬件不差的情况下一般能支撑几万次的并发量,负载度比LVS相对小些。
4、Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测。比如用户正在上传一个文件,而处理该上传的节点刚好在上传过程中出现故障,Nginx会把上传切到另一台服务器重新处理,而LVS就直接断掉了,如果是上传一个很大的文件或者很重要的文件的话,用户可能会因此而不满。
5、Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP也是近几年非常流行的web架构,在高流量的环境中稳定性也很好。
6、Nginx现在作为Web反向加速缓存越来越成熟了,速度比传统的Squid服务器更快,可以考虑用其作为反向代理加速器。
7、Nginx可作为中层反向代理使用,这一层面Nginx基本上无对手,唯一可以对比Nginx的就只有lighttpd了,不过lighttpd目前还没有做到Nginx完全的功能,配置也不那么清晰易读,社区资料也远远没Nginx活跃。
8、Nginx也可作为静态网页和图片服务器,这方面的性能也无对手。还有Nginx社区非常活跃,第三方模块也很多。
淘宝的前端使用的Tengine就是基于nginx做的二次开发定制版。
  Nginx的缺点是:
1、Nginx仅能支持http、https和Email协议,这样就在适用范围上面小些,这个是它的缺点。
2、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测不支持Session的直接保持,但能通过ip_hash来解决