前
Nginx 是个好东西。。。
Nginx 的wiki 定义
Nginx(发音同engine x)是一个异步框架的 Web服务器,也可以用作反向代理,负载平衡器 和 HTTP缓存。该软件由 Igor Sysoev 创建,并于2004年首次公开发布。[6] 同名公司成立于2011年,以提供支持。[7]
平时或多或少的在使用 Nginx 这个服务,但是很少系统的去学习它。作为OP这个东西肯定是十分重要的,所以抽个时间和机会,系统的了解吧~
这篇将是一个简明的入门笔记,也算得上的一本读书笔记了,陶利军老师的 《决战Nginx》
Nginx : 2004/10/4 类BSD C-language
web访问的顺序:web浏览器 -> web服务器(狭义)-> web容器 -> 应用服务器 -> 数据库服务器
这里强烈PICK 一下国内的 GITBOOK 平台 看云上的一个系列
NginX
nginx 的作用: HTTP svr
Nginx 严格意义上 称为 HTTP SEVRVER :: HTTP 协议层面的传输和访问控制,所以可以看到代理、负载均衡等功能。
客户端通过 HTTP Server 访问服务器上存储的资源(HTML 文件、图片文件等等)。通过 CGI 技术,可以实现对路由路径进行功能分发,但是一个 HTTP Server 始终只是把服务器上的文件如实的通过 HTTP 协议传输给客户端的这样的一个存在。
所以总结来讲, Nginx 严格意义上是一个 HTTP 服务器, 在主机上开放了HTTP 的响应端口,可以对我们的HTTP 的不同请求,进行不同的任务分发
,注意这里不是响应,是内容分发。通过 Nginx 的配置,可以对不同的请求内容,分发到不同的任务去。
比如配置一个目录为图像目录,那么我就可以使用
curl www.imang.com/image/xxxx.jpg -v
来进行一次图像的访问访问,这个内容便是通过 Nginx 进行配置的。
再者,我们可以是呀
curl www.imang.com/cgi-bin/xxxx -v
这里可以进行一次 CGI 的请求,这里一样的的是Nginx的配置,把 cgi-bin 里面的xxxx 配置为我们的 本地脚本执行
所以综上 Nginx 的作用就是把我们的HTTP 请求进行不同的任务下发,静态文件,CGI,负载均衡,etc
Nginx 的基本模块
Nginx 是基于模块化的构建方式。常用的用户配置有一些模块:
- 内核模块 CoreModule
事件驱动模块 EventModule
HTTP内核模块 HttpCoreModule
所以,我们的配置内容就存在上述的对应的三种配置,一些基本基本配置项
- CoreModule
- error_log logs/error.log 用日志记录指定
deamon on | off 是否是守护进程,否则Nginx 只能进行前台运行
include file | * 这里用于引入其他配置文件,包含上面的事件配置,HTTP 配置,但不限于
PID 指定Nginx 的 .pid 文件
worker_cpu_affinity worker cpu 亲和性,这个挺有意思,可以指定WOrker使用的CPU
$pid 这个是个变量,或者说是宏,用于表示当前运行的服务器的PID
EventModule 事件模块决定了 处理路由路径的 过程,一般缺省,对性能较大影响
HttpCoreModule Http服务器的基础配置模块
alias 定义路由结构 见后
root 定义路由结构 见后
error_page [404/500] 这个用于对不同的错误码的返回配置,所以就有了 404 页面,不再是单独那几个字了
internal 指定路径为内部访问,这里可以对路由路径进行内部连接,不允许用户从外部直接访问
limit_except [get/post] 这个可以对一个路径的 请求方式进行限制
listen [[ip]:port] 重要,指定虚拟服务器所监听的端口,见后
localtion [通配] url {} 重要,对指定的URL配置到不同的访问
post_action 一个请求完成之后所执行的URL,和Internal 连用
server {} 用于虚拟主机的配置
server_name [] 匹配请求头中的Host 字段,www.example.com
$args 变量,代表GET的请求行中的参数
$request_uri 用户当前请求的原始 URI
$uri 当前请求的URI ,可能发生内部重定向,所以不一定和上面的req 相同
- error_log logs/error.log 用日志记录指定
一个 Http 模块的配置示例
http {
server {
listen 80;
server_name www.domain1.com;
access_log logs/domain1.access.log main;
location / {
index index.html;
root /web/www/domain1.com/htdocs;
}
}
server {
listen 80;
server_name www.domain2.com;
access_log logs/domain2.access.log main;
location / {
index index.html;
root /web/www/domain2.com/htdocs;
}
}
include /opt/nginx/conf/vhosts/www.domain2.com.conf;
}
一个内部重定向的实现 post_action
location /dosomething {
internal;
proxy_pass http://127.0.0.1
post_action /afterdosomething
}
location /dosomething {
internal; # 内部路径,外部无法访问
fastcgi_pass 127.0.0.1/cgi # 这里也展现出了CGI
}
Master 与 Worker
Nginx 使用的是 Master-Worker 的这种结构。通俗讲,就是 包工头和工人。master负责端口服务,接收连接之后进行下发分配;worker 是负责连接连接内容处理。
ps auxf | grep nginx
root 6174 0.0 0.0 28876 428 ? Ss 14:35 0:00 nginx: master process ./sbin/nginx
root 6175 0.0 0.2 29364 2060 ? S 14:35 0:00 \_ nginx: worker process
这里可以看到,master和worker进程。
对于 Master 进程我们可以给他发信号
信号 | 功能 |
---|---|
WINCH | Master 关闭所有的worker |
HUP | 重新装载Nginx 配置(服务重启动,同reload),后面的PID使用了这个信号 |
这里有个很有趣的东西,我们对 master发信号
kill -WINCH `cat /var/log/myserver.pid`
之后,再进行我们的HTTP访问,发现可以进行连接,可是一直保持着加载,直到最后的超时。
因为,我们这里 让master kill 了所有的worker 。有人接活,没人干了,哈哈
nginx 与 PHP
在网上看到一句话:
Nginx 本身是不支持 PHP 的
毕竟不了解,一直很纳闷。php在在nginx 的主机上跑的好好的怎么就不支持了呢。
实际上 Nginx 上的PHP,严格意义上讲是通过第三方的支持,而本身是不能直接解释 PHP 脚本的。
LAMP 的经典架构下面,需要这几个东西:
- Linux
安装 Apache - 安装 php
- 安装 mysql
简简单单的几个 apt-get 发现使用
<?php phpinfo(); ?>
页面就已经得到了解析了。因为,当我们对目标php进行访问之后,apache 自动的开始 解释脚本,和渲染内容了,所以apache 是支持php 的。
然而,如果我们把 index.php 放在Nginx 的根目录下,打开是怎样的?
结果是完完全全的纯文本的形式打开了来。可见Nginx 并未对PHP脚本进行解析。所以说 Nginx 是不支持 php 是正确的。
那么一个 PHP 的页面要怎么跑上去呢?
在这里, Nginx 把他转换成了一个 CGI 问题 : FastCGI!
与为每个请求创建一个新的进程不同,FastCGI使用持续的进程来处理一连串的请求。这些进程由FastCGI服务器管理,而不是web服务器。 当进来一个请求时,web服务器把环境变量和这个页面请求通过一个socket比如FastCGI进程与web服务器(都位于本地)或者一个TCP connection(FastCGI进程在远端的server farm)传递给FastCGI进程。
Http服务其的作用是任务下发的
FastCGI 是 Nginx 下的一个模块 ngx_http_fastcgi_module 。通过这个模块,我们可以把对应路径的HTTP 请求,可以下发到 fastcgi 这个模块,这个模块会使用 语言对应的解释器,进行执行,并返回结果!,
这事就这样成了
php本身只是一种脚本语言,其良好的特性使其可以服务 web
在PHP 里面我们很容易的可以:
这样来个教科书式的 hello 。这里使用 php 这个 解释器对这个脚本进行了解释,输出了这样的结果。
这里就出现了 PHP-FPM (FastCGI Process Manager)。
这个就是 Nginx 使用FastCGI 最终所使用的东西。它负责创建管理 解释PHP 的进程。这个过程也越来越明了了
这里,便贴出来核心配置, 这样一看便懂了
server {
listen 8011;
server_name test.cn;
location ~ \.php?.*$ {
root /share/test;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
- root 代表以此为根
- fastcgi_pass 指定了fmp 的监听端口 (注意 FPM 是一个已经启动的服务)
- fastcgi_param 这个就是重要的参数了,这里传递给了fastcgi 一个SCRIPT_FILENAME的参数,其参数值 将要被执行的脚本的文件名 ,文件路径,
这样一个流程下来, PHP 就可以被执行了
一些值得注意的地方
master_process 这个配置项
master_process on | off
测过配置项如果 使用 off ,nginx 就会使用单进程模式运行,方便调试
PID 文件的作用
在配置里面会有这样一行
pid /var/log/xxx.pid
PID 从字面上理解这里是processID,这个文件也的确是保存的当前运行的PID 。这样我们如果运行了多个 Nginx 的进程, 我们想kill 掉其中的的一个,就可以很方便的使用这个 PID 文件
kill -HUP `cat /var/log/xxx.pid`
root 和 alias
location ^~ /admin {
root /vagrant/pro/static;
}
location ^~ /admin2 {
alias /vagrant/pro/static;
}
在对 一个虚拟服务器 的location 配置的时候,这里就需要涉及到其路由相关的配置。里面就有了 alias 和root 这两种指定路径的方式。
简单的讲,
-
alias 直接把我们请求的路径 直接替换为下面的绝对地址 正如其译意 别名
*.com/admin --> /vagrant/pro/static
root 的意思是根, 这里意味着把下面指定的绝对路径作为访问的根目录,之后再在后面添加上我们请求的路径
*.com/admin --> /vagrant/pro/static/admin
在一般使用的时候使用alias ,同时可以使用正则,和参数。
这里配置一个下载的话使用如下配置文件。
“`~
location ~ ^/download/(.*)$ {
alias /data/files/$1;
}
这样可以实现一个匹配下载的功能,可以使用 `get /download/xxx.exe`的方式即可返回 xxx.exe
#### IPv4 到 IPv6
这里虽然不是很常用,现在国内的IPV6 还杳无音讯。不过这里记录一下。
在Listen 进行虚拟服务器的 端口绑定的时候
listen *:80; # 意味着所有本机地址的监听
listen loaclhost:8000;
IPv4 到 IPv6 的映射:
::ffff:127.0.0.1
使用这样的方法,可以实现把一个 v4 的流量转发到一个 v6 的监听端口上
## 问题
这里是自己的一些问题,和理解。是自问自答,和网上的问题的收集。
- [tomcat 与 nginx,apache的区别是什么?](https://www.zhihu.com/question/32212996)
## 参考资料
- [web服务,服务器,容器,中间件](http://www.voidcn.com/article/p-odsszfoq-eh.html)