Nginx 简明入门

Nginx 简明入门

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 的配置,可以对不同的请求内容,分发到不同的任务去。

比如配置一个目录为图像目录,那么我就可以使用

1
curl www.imang.com/image/xxxx.jpg -v

来进行一次图像的访问访问,这个内容便是通过 Nginx 进行配置的。

再者,我们可以是呀

1
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 相同

一个 Http 模块的配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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

1
2
3
4
5
6
7
8
9
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 是负责连接连接内容处理。

1
2
3
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发信号

1
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 发现使用

1
<?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 里面我们很容易的可以:

1
2


这样来个教科书式的 hello 。这里使用 php 这个 解释器对这个脚本进行了解释,输出了这样的结果。

这里就出现了 PHP-FPM (FastCGI Process Manager)。

这个就是 Nginx 使用FastCGI 最终所使用的东西。它负责创建管理 解释PHP 的进程。这个过程也越来越明了了


这里,便贴出来核心配置, 这样一看便懂了

1
2
3
4
5
6
7
8
9
10
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 这个配置项

1
master_process on | off

测过配置项如果 使用 off ,nginx 就会使用单进程模式运行,方便调试

PID 文件的作用

在配置里面会有这样一行

1
pid /var/log/xxx.pid

PID 从字面上理解这里是processID,这个文件也的确是保存的当前运行的PID 。这样我们如果运行了多个 Nginx 的进程, 我们想kill 掉其中的的一个,就可以很方便的使用这个 PID 文件

1
kill -HUP `cat /var/log/xxx.pid`

root 和 alias

1
2
3
4
5
6
7
location ^~ /admin {
root /vagrant/pro/static;
}

location ^~ /admin2 {
alias /vagrant/pro/static;
}

在对 一个虚拟服务器 的location 配置的时候,这里就需要涉及到其路由相关的配置。里面就有了 alias 和root 这两种指定路径的方式。

简单的讲,

  • alias 直接把我们请求的路径 直接替换为下面的绝对地址 正如其译意 别名

    1
    *.com/admin --> /vagrant/pro/static

    root 的意思是根, 这里意味着把下面指定的绝对路径作为访问的根目录,之后再在后面添加上我们请求的路径

    1
    *.com/admin --> /vagrant/pro/static/admin

在一般使用的时候使用alias ,同时可以使用正则,和参数。

这里配置一个下载的话使用如下配置文件。

1
2
3
location ~ ^/download/(.*)$ {
alias /data/files/$1;
}

这样可以实现一个匹配下载的功能,可以使用 get /download/xxx.exe的方式即可返回 xxx.exe

IPv4 到 IPv6

这里虽然不是很常用,现在国内的IPV6 还杳无音讯。不过这里记录一下。

在Listen 进行虚拟服务器的 端口绑定的时候

1
2
listen *:80; 	# 意味着所有本机地址的监听
listen loaclhost:8000;

IPv4 到 IPv6 的映射:

1
::ffff:127.0.0.1

使用这样的方法,可以实现把一个 v4 的流量转发到一个 v6 的监听端口上

问题

这里是自己的一些问题,和理解。是自问自答,和网上的问题的收集。

参考资料

-------------本文结束感谢您的阅读-------------
Thanks anyway!