参考资源:
什么是 Nginx
==Nginx== 是一款轻量级的 ==Web== 服务器/反向代理服务器及电子邮件 ==(IMAP/POP3)== 代理服务器,并在一个 ==BSD-like == 协议下发行。
其特点是占有内存少,并发能力强,事实上 ==nginx== 的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用 ==nginx== 网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
——百度词条
Nginx 使用基于事件驱动架构,使得其可以支持数以百万级别的 TCP 连接
高度的模块化和自由软件许可证是的第三方模块层出不穷
Nginx 是一个跨平台服务器,可以运行在 Linux, FreeBSD, Solaris, AIX, Mac OS, Windows 等操作系统上
这些优秀的设计带来的极大的稳定性。
Web 服务器
lighttpd
Lighttpd 是一个具有非常低的内存开销,cpu 占用率低,效能好,以及丰富的模块等特点。lighttpd 是众多 OpenSource 轻量级的 web
server 中较为优秀的一个。支持 FastCGI, CGI, Auth, 输出压缩(output compress), URL 重写,
Alias 等重要功能。
Lighttpd 使用 fastcgi 方式运行 PHP,它会使用很少的 PHP 进程响应很大的并发量。
Fastcgi 的优点在于:
- 从稳定性上看, fastcgi 是以独立的进程池运行来 cgi,单独一个进程死掉,系统可以很轻易的丢弃,然后重新分配新的进程来运行逻辑.
- 从安全性上看, fastcgi 和宿主的 server 完全独立, fastcgi 怎么 down 也不会把 server 搞垮,
- 从性能上看, fastcgi 把动态逻辑的处理从 server 中分离出来, 大负荷的 IO 处理还是留给宿主 server, 这样宿主 server 可以一心一意作 IO,对于一个普通的动态网页来说, 逻辑处理可能只有一小部分,
大量的图片等静态 IO 处理完全不需要逻辑程序的参与
- 从扩展性上讲, fastcgi 是一个中立的技术标准, 完全可以支持任何语言写的处理程序 php,Java,Python
Apache
apache 是世界排名第一的 web 服务器, 根据 netcraft 所作的调查,世界上百分之五十以上的 web 服务器在使用 apache.
1995 年 4 月, 最早的 apache(0.6.2 版)由 apache group 公布发行. apache group
是一个完全通过 internet 进行运作的非盈利机构, 由它来决定 apache web 服务器的标准发行版中应该包含哪些内容.
准许任何人修改隐错, 提供新的特征和将它移植到新的平台上, 以及其它的工作. 当新的代码被提交给 apache group 时,
该团体审核它的具体内容, 进行测试 如果认为满意, 该代码就会被集成到 apache 的主要发行版中。
apache 的特性:
几乎可以运行在所有的计算机平台上
支持最新的 http/1.1 协议 简单而且强有力的基于文件的配置(httpd.conf)
支持通用网关接口(cgi)
支持虚拟主机
支持 http 认证
集成 perl
集成的代理服务器
可以通过 web 浏览器监视服务器的状态,
可以自定义日志
支持服务器端包含命令(ssi)
支持安全 socket 层(ssl)
具有用户会话过程的跟踪能力
支持 fastcgi
支持 Java
Nginx
Nginx 是俄罗斯人编写的十分轻量级的 HTTP 服务器,Nginx,它的发音为“engine X”,
是一个高性能的 HTTP 和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器.Nginx 是由俄罗斯人 Igor
Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发.
Nginx 以事件驱动的方式编写,所以有非常好的性能,同时也是一个非常高效的反向代理、负载平衡。其拥有匹配
Lighttpd 的性能,同时还没有 Lighttpd 的内存泄漏问题,而且 Lighttpd 的 mod_proxy 也有一些问题并且很久没有更新。但是 Nginx 并不支持 cgi 方式运行,原因是可以减少因此带来的一些程序上的漏洞。所以必须使用 FastCGI 方式来执行 PHP 程序。
nginx 做为 HTTP 服务器,有以下几项基本特性:
处理静态文件,索引文件以及自动索引;打开文件描述符缓冲 无缓存的反向代理加速,简单的负载均衡和容错 FastCGI,简单的负载均衡和容错
模块化的结构。包括 gzipping, byte ranges, chunked responses,以及
SSI-filter 等 filter。如果由 FastCGI 或其它代理服务器处理单页中存在的多个 SSI,则这项处理可以并行运行,而不需要相互等待。
Nginx 专为性能优化而开发,性能是其最重要的考量,实现上非常注重效率。它支持内核 Poll 模型,能经受高负载的考验,有报告表明能支持高达
50,000 个并发连接数。
Nginx 具有很高的稳定性。其它 HTTP 服务器,当遇到访问的峰值,或者有人恶意发起慢速连接时,也很可能会导致服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前 apache 一旦上到 200 个以上进程,web 响应速度就明显非常缓慢了。而 Nginx 采取了分阶段资源分配技术,使得它的 CPU 与内存占用率非常低。nginx 官方表示保持 10,000 个没有活动的连接,它只占 2.5M 内存,所以类似 DOS 这样的攻击对 nginx 来说基本上是毫无用处的。就稳定性而言,nginx 比 lighthttpd 更胜一筹。
Nginx 支持热部署。它的启动特别容易,
并且几乎可以做到 7X24 不间断运行,即使运行数个月也不需要重新启动。你还能够在不间断服务的情况下,对软件版本进行进行升级。
三种服务器比较
Nginx 安装
Homebrew
1 | man brew |
安装 Homebrew
1 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" |
卸载
1 | ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" |
其他常用命令:
1 | localhost:~ wany$ brew --version (查看当前电脑所安装的brew版本) |
通过 brew
安装 Nginx
1 | sudo /usr/local/sbin/nginx |
注意事项:
安装 nignx, brew
所安装的软件都保存在 :/usr/local/Cellar/
nginx
配置文件保存到了:/usr/local/etc/nginx/nginx.conf
建立软连接
1 | ln -s /usr/local/bin/nginx /usr/local/bin/nginx |
启动
1 | sudo nginx |
重启
1 | sudo nginx -s reload |
Nginx 反向代理
什么是跨域以及产生的原因
跨域是指 a 页面想获取 b 页面资源,如果 a、b 页面的协议、域名、端口、子域名不同,或是 a 页面为 ip 地址,b 页面为域名地址,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。
跨域情况如下:
跨域常见的解决方法
目前来讲没有不依靠服务器端来跨域请求资源的技术
1.jsonp 需要目标服务器配合一个 callback 函数。
2.window.name+iframe 需要目标服务器响应 window.name。
3.window.location.hash+iframe 同样需要目标服务器作处理。
4.html5 的 postMessage+ifrme 这个也是需要目标服务器或者说是目标页面写一个 postMessage,主要侧重于前端通讯。
5.CORS 需要服务器设置 header :Access-Control-Allow-Origin。
6.nginx 反向代理 这个方法一般很少有人提及,但是他可以不用目标服务器配合,不过需要你搭建一个中转 nginx 服务器,用于转发请求。
Nginx 反向代理解决跨域
修改配置文件:
路径
1 | luoyecs-iMac:nginx luoyec$ pwd |
修改 nginx.conf
1 | listen 9000; #监听9000端口号, |
重启 nginx
1 | sudo nginx -s reload |
在浏览器中访问:http://localhost:9000/
配置说明
首先找到 nginx.conf 或者 nginx.conf.default 或者是 default 里面的这部份
其中 server 代表启动的一个服务,location 是一个定位规则。
1 | location /{ #所有以/开头的地址,实际上是所有请求 |
从上面可以看出 location 是 nginx 用来路由的入口,所以我们接下来要在 location 里面完成我们的反向代理。
假如我们我们是 www.a.com/html/msg.html 想请求 www.b.com/api/?method=1¶=2;
我们的 ajax:
1 | var url = 'http://www.b.com/api/msg?method=1¶=2'; |
上面的请求必然会遇到跨域问题,这时我们需要修改一下我们的请求 url,让请求发在 nginx 的一个 url 下。
1 | var url = 'http://www.b.com/api/msg?method=1¶=2'; |
再在刚才的路径中匹配到这个请求,我们在 location 下面再添加一个 location。
1 | location ^~/proxy/html/{ |
以下做一个解释:
'^~ /proxy/html/ '
就像上面说的一样是一个匹配规则,用于拦截请求,匹配任何以 /proxy/html/开头的地址,匹配符合以后,停止往下搜索正则。
rewrite ^/proxy/html/(.*)$ /$1 break;
代表重写拦截进来的请求,并且只能对域名后边的除去传递的参数外的字符串起作用,例如 www.c.com/proxy/html/api/msg?method=1¶=2 重写。只对/proxy/html/api/msg 重写。
rewrite 后面的参数是一个简单的正则 ^/proxy/html/(.*)$ ,$1 代表正则中的第一个(),$2 代表第二个()的值,以此类推。
break 代表匹配一个之后停止匹配。
- proxy_pass
既是把请求代理到其他主机,其中 http://www.b.com/ 写法和 http://www.b.com写法的区别如下:
不带/
1 | location /html/ |
带/
1 | location /html/ |
上面两种配置,区别只在于 proxy_pass 转发的路径后是否带 “/”。
针对情况 1,如果访问 url = http://server/html/test.jsp,则被nginx代理后,请求路径会便问http://proxy_pass/html/test.jsp,将test/ 作为根路径,请求 test/路径下的资源。
针对情况 2,如果访问 url = http://server/html/test.jsp,则被nginx代理后,请求路径会变为 http://proxy_pass/test.jsp,直接访问server的根资源。