2010年8月

使用Cygwin编译Windows上的Nginx

Nginx的官方最近也开始提供Windows版本的下载了


如果不需要附加的第三方模块的话,直接使用其提供的Windows版本就可以了


但我们线上运行的Nginx需要编译进好多附加的模块,所以只能自己动手了


上网Google一搜,好多关于在Cygwin下编译Nginx的文章


但真正自己动手去编译,发现还是出了很多的问题


我使用的编译选项如下:



折叠复制代码




  1. ./configure --prefix=.--sbin-path=nginx--with-cc-opt="-D FD_SETSIZE=4096"--with-debug --with-mail --with-mail_ssl_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module--add-module=../nginx-upload-progress-module--add-module=../nginx_passport--add-module=../ngx_cache_purge-1.0--add-module=../headers-more-nginx-module





 


在编译过程中,遇到了以下问题:



  1. prefix的选项,如果我们指定--prefix=/cygdrive/d/nginx,那么最后脱离Cygwin环境运行,会发现root无法指向其它磁盘上的目录,所以这里使用了相对路径,而且指定了可执行文件nginx在根目录下,而不是默认的sbin/nginx

  2. FD_SETSIZE=4096,网上都说了,是将select模式的最大worker_connections加大

  3. 编译mod_passport之前,最好执行dos2unix.exe mod_passport/config转换一下格式

  4. 编译mod_passport时,会报错:cc1: warnings being treated as errors,需要修改objs/Makefile文件,把其中的-Werror删除即可

  5. 编译成功后,在Cygwin下运行正常,但如果要脱离Cygwin,需要从cygwin/bin下拷贝cygwin1.dll,cyggcc_s-1.dll,cygz.dll,cygcrypto-0.9.8.dll,cygssl-0.9.8.dll,cygpcre-0.dll,cygcrypt-0.dll这几个dll到nginx目录下

  6. 最后,不使用Cygwin,在普通Dos下运行nginx时,会报错:emerge: getpwnam("nobody") fail。这也是最令我郁闷的一个错误了,看了网上很多人的帖子,似乎都很顺利就成功了,但用我的Cygwin编译出来的nginx,就一直报这个错误,尝试不加第三方模块,指定user为本机的administrator,依然报错...郁闷了很久之后,最后还是找到nginx源码中相关逻辑,做如下修改:
    nginx-0.8.49/src/core/nginx.c,把getpwnam和getgrnam相关逻辑判断注释掉

    nginx-0.8.49/src/os/unix/ngx_process_cycle.c把setgid和setuid相关逻辑判断注释掉
    最后重新编译运行,才成功了

  7. 当引用外部的目录时,需要用cygwin格式的路径,如:root /cygdrive/d/work/git/python_mail/web;


 


最后,写了一个restart.bat脚本,用来重启nginx



折叠复制代码




  1. @echo off

  2. echo Stoping nginx...

  3. taskkill /F /IM nginx.exe

  4. echo Validating nginx.conf...

  5. nginx.exe -t -c conf/nginx.conf

  6. echo Starting nginx...

  7. nginx.exe -c conf/nginx.conf

  8. tasklist | findstr nginx




 


 

开启Nginx的gzip压缩功能

默认情况下,Nginx的gzip压缩是关闭的


同时,Nginx默认只对text/html进行压缩


所以,开启gzip的指令如下:



折叠复制代码




  1. gzip on;

  2. gzip_http_version 1.0;

  3. gzip_disable "MSIE [1-6].";

  4. gzip_types text/plain application/x-javascript text/css text/javascript;




注意:


1. 其中的gzip_http_version的设置,它的默认值是1.1,就是说对HTTP/1.1协议的请求才会进行gzip压缩


如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间是用HTTP/1.0协议通信的



This 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通过反向代理做Cache Server,而且前端的nginx没有开启gzip


同时,我们后端的nginx上没有设置gzip_http_version为1.0,那么Cache的url将不会进行gzip压缩


 


2. gzip_disable的设置是禁用IE6的gzip压缩,又是因为杯具的IE6


IE6的某些版本对gzip的压缩支持很不好会造成页面的假死,今天产品的同学就测试出了这个问题


后来调试后,发现是对img进行gzip后造成IE6的假死,把对img的gzip压缩去掉后就正常了


为了确保其它的IE6版本不出问题,所以就加上了gzip_disable的设置

Nginx的Cache和Set-Cookie的冲突

上周,让NO同学帮忙检测了一下mail登录的数据


最后发现,结果很不理想,平均登录时间在50s左右


看了相关的数据后,发现以前的CDN也有一定的问题


首先,以前的CDN缓存时间太小,只有12个小时,几乎没啥用


再次,CDN似乎不太稳定,有时用户访问CDN的时间很长


经过和NO的同学讨论后,准备更改CDN


从js.sohu.com迁移到js.mail.sohu.com上


新的url是我们自己的服务器,上面存储一些静态的资源


NO同学负责更改该url的DNS解析,在全国范围内就近解析到最近的CDN上


他们的CDN实现似乎也很简单,Nginx+ProxyPass+Cache就搞定了


 


在测试过程中,有一个问题,郁闷2天了


静态的js文件,首次访问,CDN正常返回200


但按F5刷新后,CDN不是返回的304,而是继续返回200


但设置js.mail.sohu.com的host到我们的服务器,就能返回304


和NO同学调试了一天,才发现是Set-Cookie的header惹的祸


我们的js.mail.sohu.com上装了passport的module


当用户登录后访问,会设置相应的cookie,所以每个请求都会有这个header


但Nginx的Cache模块貌似是,发现有这个Set-Cookie的heaer后,就不cache了


所以,当用户按F5后,它不会返回304,而是向后台去请求返回200


 


最后,是这么解决的:


在nginx上配置清除那个header:



折叠复制代码




  1. more_clear_headers 'Set-Cookie';




当然,你的nginx需要编译进去headers-more-nginx-module这个模块

昕昕三岁了

今天是昕昕三周岁的生日

 

时间过的可真快,一晃三年就过去了

 

昕昕也已经慢慢长大懂事了

 

这段时间他对托马斯比较感兴趣,家里原来有一套小的轨道系列

 

所以,这次送给他的生日礼物是一套大的托马斯小火车:

 

 

生日蛋糕,生日之前他就一直在念叨

 

8月2日,农历6月22,也是他的农历生日

 

那天奶奶给他订了一个小蛋糕,晚上据说他吃的还不少

 

 

 

今天,我休了一天假,带他去了中国科技馆儿童科技乐园

 

早上9点半就到了那里,里面还真是不小,有无数的项目

 

这些项目基本都是给孩子灌输一些科技知识,将玩和学合理的结合了起来

 

不过,很多项目都需要大一些的孩子才能去玩,去理解

 

他这个年龄的,也就是去凑凑热闹,玩一少部分项目

 

昕昕今天玩的还挺开心的,尤其喜欢玩拔萝卜,钻山洞,怕迷宫

 

还有盖房子,水闸这些项目,一遍一遍的玩

 

今天一直玩到了下午3点半,才出去回家,刚上公交,就睡着了...

 

 

 

晚上,带着他去了育新小区那边的“黄记煌”,吃的焖鱼

 

本来是给他过生日的,但昕昕其实没吃多少东西,其它东西都是我们吃了

 

呵呵,打着给昕昕过生日的名号,我们出去大吃了一顿

 

其实,自从生了昕昕后,我们基本都没在外面吃过东西,总共也就3,4次吧...

讨厌鬼赫克托

晚上,不知道昕昕因为什么事


一直缠着昕昕妈妈不放手


昕昕妈就来了一句:


你真是个烦人精!


昕昕不示弱,回了妈妈一句:


你是个淘气包!


昕昕妈跟着说:


你是个讨厌鬼!


没想到,昕昕来了一句:


你是个赫克托~


昕昕妈一下子愣住了:


赫克托是个什么东西?


昕昕答道:


赫克托是个讨厌鬼!


原来,我前几天给他讲的托马斯里面


有这么一个故事:“讨厌鬼赫克托”


这小子还用到地方了呢,呵呵


 


 

Web中Cache相关的header

1. 控制页面缓存相关:



折叠复制代码




  1. #Request相关的Headers:

  2. #HTTP/1.0协议,不缓存页面

  3. Pragma: no-cache

  4. #HTTP/1.1协议,不缓存,请求后得到200的响应值

  5. Cache-Control: no-cache


  6.  

  7. #response相关的Headers:

  8. #相对的过期时间,20s后过期

  9. Cache-Control: max-age=20

  10. #固定的过期时间,等同max-age,但是如果同时存在,则被Cache-Control的max-age覆盖

  11. Expires: Mon, 02 Aug 2010 05:15:16 GMT




2. 检查页面缓存相关:



折叠复制代码




  1. #以下是Response的headers:

  2. #页面最后的修改时间

  3. Last-Modified: Wed, 28 Jul 2010 09:46:14 GMT

  4. #页面的Etag,因为Last-Modified只能精确到秒,如果某个文件在一秒内修改了多次,那么Cache的判断可能就不准确了,所以才增加了Etag的判断

  5. Etag: "a21619-7e76-4b03666f"


  6. #以下是Request的headers:

  7. #check文件是否修改

  8. If-Modified-Since: Wed, 18 Nov 2009 03:13:51 GMT

  9. #check对应的Etag

  10. If-None-Match: "eae2fb-7e76-4b03666f"




3. 页面cache的检查流程:



  • Client首次请求页面,Server端返回200 OK,同时,返回如下的header,表明该文件20s后过期:


  • 折叠复制代码




    1. 00:00:04.494 ! 0.009 924 1550 GET 200 gif http://mail.sohu.com/test/test.gif

    2.  

    3. #Response headers

    4. Etag: "a21619-7e76-4b03666f"

    5. Last-Modified: Wed, 28 Jul 2010 09:46:14 GMT

    6. Expires: Mon, 02 Aug 2010 05:15:16 GMT

    7. Cache-Control: max-age=20




  • 用户如果在cache失效之前,在地址栏按回车,则Client会直接从Cache中读取,此时不会往Server发请求。如果Cache已经过期,则发送的请求和按F5的一样:


  • 折叠复制代码




    1. 00:01:07.468 ! 0.002 0 0 GET (Cache) gif http://mail.sohu.com/test/test.gif




  • 用户按F5刷新,此时Client会带着If-Modified-Since和Etag到Server端去请求,Server会检查页面的Last-Modified和Etag是否有变化,若没有变化,则返回304,同时重新设置新的Expires时间。如果文件有变化,则会返回200


  • 折叠复制代码




    1. 00:00:00.000 ! 0.012 949 220 GET 304 gif http://mail.sohu.com/test/test.gif

    2.  

    3. #Request header:

    4. If-Modified-Since: Wed, 28 Jul 2010 09:46:14 GMT

    5. If-None-Match: "a2161c-7fbb-4b26ed49"

    6.  

    7. #Response header:

    8. Expires: Mon, 02 Aug 2010 06:46:40 GMT

    9. Cache-Control: max-age=20

    10. Etag: "a2161c-7fbb-4b26ed49"




  • 用户按Ctrl+F5刷新,此时Client会加上no-cache的header去请求,Server端直接返回200


  • 折叠复制代码




    1. 00:02:13.149 ! 0.008 924 1550 GET 200 gif http://mail.sohu.com/test/test.gif

    2.  

    3. #Request header;

    4. Cache-Control: no-cache

    5.  

    6. #Response header:

    7. Last-Modified: Wed, 28 Jul 2010 09:46:14 GMT

    8. Expires: Mon, 02 Aug 2010 06:48:53 GMT

    9. Cache-Control: max-age=20




  •   用户清除本地缓存后再请求,则和首次请求该页面一样,Server端返回200

最新文章

最近回复

  • feifei435:这两个URI实际是不一样的
  • zsy: git push origin 分支 -f 给力!
  • 冼敏兵:简单易懂,good fit
  • Jack:无需改配置文件,看着累! # gluster volume se...
  • Mr.j:按照你的方法凑效了,折腾死了。。。。
  • zheyemaster:补充一句:我的网站路径:D:\wamp\www ~~菜鸟站长, ...
  • zheyemaster:wamp2.5(apache2.4.9)下局域网访问403错误的...
  • Git中pull对比fetch和merge | 炼似春秋:[…] 首先,我搜索了git pull和git fe...
  • higkoo:总结一下吧, 性能调优示例: gluster volume s...
  • knowaeap:请问一下博主,你维护的openyoudao支持opensuse吗

分类

归档

其它