# nginx实用笔记 * 这是什么 * 为什么用选择nginx * 安装及使用nginx * 站点配置 * 域名绑定 * 配置php-fpm * http代理模块 * 正向代理 * 什么是代理 * http通讯原理 * 抛开nginx代理模块的本质,ngx_http_proxy_module原理 * 反向代理 * 负载均衡 * url重写(未写待续) * url重定向(未写待续) * 实战高负载高并发 (nginx+php性能优化) (未写待续) # 这是什么 > Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、新浪、网易、腾讯等。 这里都是吹牛逼的,更多吹牛逼资料请看: 百度百科,http://baike.baidu.com/view/926025.htm nginx官网,http://nginx.org/en/ ## 一句话总结 > 这是一个http服务器,同apache一样,提供web服务。 > 可以做静态资源服务器,存放html,js,css文件等等, > 还可以配合FastCGI,完成对php文件的解析,实现nginx+php的动态服务。 > 还可以拿来做反向代理,做负载均衡。 # 为什么用选择nginx Nginx 是一个高性能的 Web 和反向代理服务器, 它具有有很多非常优越的特性: 作为 Web 服务器:相比 Apache,Nginx 使用更少的资源,支持更多的并发连接,体现更高的效率,能够支持高达 50,000 个并发连接数的响应。 作为负载均衡服务器:Nginx 既可以在内部直接支持 Rails 和 PHP,也可以支持作为 HTTP代理服务器 对外进行服务。 ## 一句话总结 > 因为爱所以爱,爱就选吧~ # 安装及使用nginx 我是用Ubuntu的,在安装软件之前要更新源. ## 更新源 `apt-get update` ## 安装nigx `apt-get install nginx` 等到他安装成功 输入 `nginx -v` ,查看安装的版本, ``` nginx version: nginx/1.4.6 (Ubuntu) ``` ## 一句话总结 无惊无险的安装完成,能够愉快的玩耍了。如果没有错,直接访问服务器的ip即可看到, ``` Welcome to nginx! ``` 我这里用的是 `Ubuntu 14.04.4LTS` , 所以安装的版本是 nginx 1.4.6 。 这里科普下,`LTS`,指,长期支持维护版本。所以在生产环节下,装软件都尽量装带LTS标志的。而不是安装最新版。 这样子出现bug也只是需要更新一下,就可以堵上bug啦 # 站点配置 ## 最基本的站点配置 站点的配置文件夹在这里,`/etc/nginx/sites-available/` 默认的站点文件 `vim /etc/nginx/sites-available/default` 我们可以通过,复制default,这个文件建立一个新的站点。可以理解吧~ ### 最基本的html静态资源服务器 ``` server { # 监听的端口 listen 80; # www目录 root /www/default; # 默认首页(访问时,没有指定文件,会自动寻找这些文件,用作显示) index index.php index.html index.htm; # 域名 http://localhost/ server_name localhost; } ``` 这就是一个最简单的http静态资源服务器了。 可以在`/www/default/index.html`,建立文件,然后访问服务器的ip,如果是本地搭建的,访问 `127.0.0.1` ## 绑定域名(也可以说是配置虚拟主机) server_name,就是为了绑定域名的。 接到请求后的匹配规则 格式是这样的 `server_name 域名 域名 域名 域名` ### 准确的匹配 ``` server_name localhost localhost2 localhost3; ``` ### 通配符匹配 ``` server_name *.c2567.com; 或者 server_name c2567.*; ``` 很显然` * ` 就代表任意字符啦. ### 正则表达式匹配 ``` server_name ~^(\d)\.c2567\.com$; ``` > `~` 使用正则表达式 > `()` 匹配内容存起来(所谓的子匹配) > `\d` 匹配数字 > `.+?` 匹配一个或者多个字符, `?`是 非贪婪匹配 > `$` 字符串末尾 > 就先科普这点吧。基本够用了 ## 配置php-fpm ``` server { # 监听的端口 listen 80; # www目录 root /www/default; # 默认首页(访问时,没有指定文件,会自动寻找这些文件,用作显示) index index.php index.html index.htm; # 域名 http://localhost/ server_name localhost; # 在默认的nginx配置中就有下面这段 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ \.php$ { # pathinfo的配置 fastcgi_split_path_info ^(.+\.php)(/.+)$; # 这里就是使用php-fpm sock的连接方式 fastcgi_pass unix:/var/run/php5-fpm.sock; # 默认解析文件名 fastcgi_index index.php; include fastcgi_params; } } ``` ### 显然现在依然不能运行 因为连php都没有安装 安装吧,依然是简简单单一步到位的~ `apt-get install php5` `apt-get install php5-fpm` ### 稍微普及下vim的使用方法 狂按esc,可以退回命令模式,命令模式可以输入命令 #### 文件保存方面 :w 保存 :q 退出 :wq 保存并退出 #### 输入方面 命令模式下输入 a , 当前位置输入 o ,新起一行输入 #### 一句话总结 会这些已经足够了完成编辑文件了。 ### 建立一个index.php吧 那么安装好了以后,建立文件在,`/www/default/index.php` 写入内容 `vim /usr/share/nginx/html/index.php` 复制下面内容,在vim中, 1. 用方向键移动到要输入的位置 2. 按a进入输入模式 3. 粘贴内容 4. 按esc,进入vim的命令模式 5. 输入`:wq` 保存 ``` <?php phpinfo(); ?> ``` 那么,如果没有意外,访问服务器地址,`http://127.0.0.1/index.php` , 就会出现phpinfo的信息咯. ### 一句话总结 配置nginx和php,非常简单,难就难在优化啊,后面我会给讲解怎么做基本的优化,在有限的服务器资源下,做到高并发,高负载,依然屹立不倒。 # http代理模块 ## 参考资料 > ngx_http_proxy_module http://nginx.org/en/docs/http/ngx_http_proxy_module.html # 正向代理 ## 什么是代理 这里就不说 正向代理跟反向代理有什么区别了,直入主题,代理是什么?代理相当于一个中介,中介是什么鬼,应该都知道吧。 ### http的通讯原理 http协议属于一问一答的的,所以就是 1对1的通讯。我问你答。 客户端(问) <-> 服务器(答) 具体点 客户端->发送报文->服务器->收到报文->处理->服务器返回报文->客户端收到 ### 一句话总结 形象点说, 我问小明: 你吃饭了吗。 小明答: 我吃了。 ## 这跟正向代理有什么鬼关系。 既然http是一问一答形式,那么代理服务器是不是起了中转作用了。 客户端(问) -> 代理服务器(再问) -> 服务器(答) 具体一点 客户端->发送报文到代理服务器->代理服务器收到报文 代理服务器(发送客户端报文)->真正的服务器收到报文并处理->服务器返回处理好的报文给代理服务器 代理服务器收到(把真正服务器返回的报文)-> 发送给客户端 -> 客户端收到 ### 一句话总结 形象点说, `我`问`小红`:小明吃饭了吗。 `小红`问`小明`: 吃饭了吗。 `小明`答`小红`说:吃了。 `小红`答`我`说;小明吃了。 ## 最简单的正向代理 简单的过程, 客户端->代理服务器(nginx)->服务器->代理服务器(nginx)->客户端 ``` server { # 设置dns服务器 resolver 114.114.114.114 114.114.114.115; # 监听端口 listen 2222; location / { # 传入nginx的变量,实际上是拼接后就是一串url proxy_pass $scheme://$host$request_uri; } } ``` ### 设置 DNS 解析 `resolver dns地址 dns地址 dns地址` 如果改成8.8.8.8是不是就能上谷歌了啊,嘿嘿 #### 注意 这不支持https,因为https走的是443端口,是安全传输协议,服务器需要同客户端建立连接,才可以通讯,所以无法中转的,证书问题。 ## 抛开nginx代理模块的本质,ngx_http_proxy_module原理 先看这个配置 ``` server { listen 99; server_name localhost; location / { proxy_pass http://blog.c2567.com; } } ``` 我快速的解释下, 监听了`99`端口 域名绑定为`localhost`, 访问地址 http://localhost:99/ http://localhost:99/1.html http://localhost:99/2.html 出现的内容是不是,对应了,我博客的内容啊 http://blog.c2567.com http://blog.c2567.com/1.html http://blog.c2567.com/2.html > ok,了解了这些,那么所谓的正向代理和反向代理,我也不知道这词是哪里冒出来词的,反正我读了好多次都不明白是什么意思,但是这都不重要!因为他本质,即将赤裸裸的展现在我们面前。 再来看看 我们前面做的http代理服务器(正向代理) ``` location / { proxy_pass $scheme://$host$request_uri; } ``` $scheme 是不是相当于,客户端传过来的 http啊 $host 是不是相当于,客户端传过来的 域名啊 $request_uri 是不是相当于,客户端传过来的 域名后面的参数啊 > 现在应该看穿nginx的代理了吧,他的本质是不是 客户端访问nginx,nginx访问`proxy_pass`拼接的地址,得到结果,再传回给客户端。 > 既然如此,了解了他的本质,是不是改什么都不怕错了。 > 还有什么鬼,正向代理,反向代理,http代理。各种代理,这词是不是都不用害怕了。 # 反向代理 > Nginx 作为 web 服务器一个重要的功能就是反向代理。Nginx 反向代理的指令不需要新增额外的模块,默认自带 proxy_pass 指令,只需要修改配置文件就可以实现反向代理。 ## 最简单的反向代理 ``` server { listen 99; server_name localhost; location / { proxy_pass http://blog.c2567.com; } } ``` 访问,`http://localhost:99/` , 就是我的博客啦.这种过程就叫反向代理了. ### 举个例子 访问 `http://localhost:99/?page_id=2` 相当于访问 `http://blog.c2567.com/?page_id=2` 其他的也雷同。 只是吧参数也一同访问了。实质就是做了一次中转。 # 负载均衡 简单来说,就是高级一点的中转代理。专业点叫 `负载均衡` 。呵呵。 ## 最简单的配置 ### 显示内容的服务器 ``` server { listen 83; server_name localhost; location / { root html/3; index index.html index.htm; } } ``` 端口设置为81,82,83, web目录为, ``` html/1 html/2 html/3 ``` 建立文件 index.html 内容为 ``` 我是端口81 我是端口82 我是端口83 ``` 以此类推,做出3个服务器,修改端口号和目录,页面内容 ### 均衡用的服务器 ``` server { listen 99; server_name localhost; location / { proxy_pass http://ss; } } upstream ss { server 127.0.0.1:81; server 127.0.0.1:82; server 127.0.0.1:83; } ``` 正如你所看到的,这里定义了3个服务器的地址,对应的访问内容为。 端口81内容为,`我是端口81` 端口81内容为,`我是端口82` 端口81内容为,`我是端口83` ``` server 127.0.0.1:81; server 127.0.0.1:82; server 127.0.0.1:83; ``` 很显然,现在访问,`http://localhost:99/` ,只要多刷新几次,就能发现内容在变化了,这就是负载均衡。 ## 负载均衡的模式 ### 权重设置 `weight=1` ``` upstream ss { server 127.0.0.1:81 weight=3; server 127.0.0.1:82 weight=2; server 127.0.0.1:83 weight=1; } ``` 显而易见,参数`weight`,就是权重啦,数值越高,访问比例越大。 ### 根据访问的ip分配服务器,`ip_hash` 如果你想,某一个ip访问某一个服务器,来保证SESSION不丢失。那么加入`ip_hash;`就可以达到目的了。 准确点的解释,将访问ip的hash结果分配,每个请求固定访问一个后端服务器, ``` upstream ss { ip_hash; server 127.0.0.1:81; server 127.0.0.1:82; server 127.0.0.1:83; } ``` ### 根据压力自动选择压力最小的,`fair` 简单来说,谁访问快就访问谁~ ``` upstream ss { fair; server 127.0.0.1:81; server 127.0.0.1:82; server 127.0.0.1:83; } ``` 反正我是没成功报错了,估计需要安装这个模块。 ``` nginx: [emerg] unknown directive "fair" ``` ## 更多参数 `down` 表示单前的server暂时不参与负载. `weight=1` 默认为1.weight越大,负载的权重就越大。 `max_fails` 允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误. `fail_timeout` 如果达到`max_fails`次失败后,暂停的时间。 ## 例子 ``` upstream backend { server 127.0.0.1:81 max_fails=3 fail_timeout=30s; server 127.0.0.1:81 max_fails=3 fail_timeout=30s; server 127.0.0.1:81 max_fails=3 fail_timeout=30s; } ``` # url重写(未写待续) # url重定向(未写待续) # 未完待续 > 一次性写了这么多东西真的好累啊~