nginx 初学者指引
off999 2025-01-09 15:19 17 浏览 0 评论
本文会简单介绍 nginx 并演示相关的简单任务。首先你需要安装好 nginx。
nginx 拥有一个主进程和几个 worker 进程。主进程的主要工作是读取和处理配置,维护 worker 进程。worker 进程负责处理实际的用户请求。nginx 采用 event-based 模型和 OS-dependent 机制对用户请求进行高效的分发。worker 进程的数量在配置文件中定义,可在配置中修改,或者根据可用的 CPU 核心数进行自动调整。
参考 http://nginx.org/en/docs/ngx_core_module.html#worker_processes
Syntax: worker_processes number | auto;
Default: worker_processes 1;
Context: main
Defines the number of worker processes.
worker 进程的最佳个数受许多因素影响,比如 CPU 核心数,磁盘驱动的个数,nginx 负载模式等。如果不确定设为多少合适,可设置为 CPU 核心数。如果设置为 auto,nginx 会尝试自动检测CPU核心数并设置为 worker 进程数。(auto 参数从 1.3.8 和 1.2.5 版开始支持)
nginx 及其模块的工作由配置文件定义,默认的配置文件为 nginx.conf,该配置文件可能位于:
/usr/local/nginx/conf, /etc/nginx, or /usr/local/etc/nginx.
nginx 启动、停止、重新加载配置
-------------------------------
执行 nginx 命令启动 nginx。启动 nginx 之后,可使用如下命令:
nginx -s stop 快速关闭 nginx
nginx -s quit 优雅的关闭 nginx
nginx -s reload 重新加载配置
nginx -s reopen 重新打开日志文件
优雅地关闭 nginx,这是说 nginx 主进程会等待 worker 进程完成当前用户请求的处理。
执行:nginx -s quit (以启动 nginx 时的用户身份执行该命令)
更改配置之后,必须执行重新加载配置的命令,或者重新启动 nginx,以使得配置生效:
nginx -s reload
当主进程接收到 reload 信号,它会检查配置文件的语法,然后尝试应用该配置。如果成功,主进程启动新的 worker 进程,并发送消息给原来的 worker 进程要求他们关闭。如果加载配置失败,主进程会对改动进行回滚,继续以原来的配置进行工作。当原来的 worker 进程接收到消息要他们关闭,他们会停止接收新的连接,并继续处理当前的请求直到完成。完成之后,原来的 worker 进程将会退出。
给 nginx 发送信号,可借助于 kill 命令。kill 命令使用进程 pid 发送信号。nginx 主进程的 pid 存储在pid 文件中,默认为 nginx.pid,位于 /usr/local/nginx/logs 或 /var/run 目录下。
例如,如果 nginx 主进程 pid 为 1628,使用 kill 命令发送 QUIT 信号给 nginx,使其优雅地关闭:
kill -s QUIT 1628
如果要获取所有运行中的 nginx 进程的列表,使用 ps 命令:
ps -ax | grep nginx
关于发送信号给 nginx 的更多信息,请参考:http://nginx.org/en/docs/control.html
配置文件的结构
-------------------
nginx 由许多模块组成,这些模块可在配置文件中进行配置。nginx 的配置指令分为:简单配置指令,区块配置指令。
简单配置指令由 “名称” 和 “参数” 组成, “名称” 和 “参数” 以空格分隔,指令的最后以分号 “;” 为结尾。
区块配置指令和简单配置指令拥有同样的结构,区块指令不以分号结尾。区块指令使用花括号 “{}” 将一组设置包含于其中。如果在区块指令的括号中包含其他指令,这个区块指令就被称为 “context” (上下文)。例如 events,http,server,location 指令。
所有在 context 之外的指令,被认为处于 main context 之中。
events 和 http 指令用于 main context 之中。
server 指令用于 http 之中。
location 指令用于 server 指令之中。
配置文件中以 # 起始的行为注释行。
nginx 提供静态内容的服务
---------------------------
web 服务器的重要任务之一是提供文件服务(比如 image 文件、静态 HTML 页面等)。
我们将实现一个示例,根据请求的不同,nginx 通过不同的目录提供文件给用户。我们通过
/data/www 目录提供 HTML 文件,通过 /data/images 目录提供 image 文件。
为达到这个目标,需要在配置文件中设置 server 区块,并在 server 区块中设置两个 location 区块。server 区块位于 http 区块之中。首先,创建 /data/www 目录,并在其中创建 index.html 文件,文件内容任意,比如:
echo "<h1>HTML File</h1>" > /data/www/index.html
然后创建 /data/images 目录,放一些图像文件到该目录中。之后打开配置文件。默认的配置文件已经包含一些 server 区块的示例,大多数被注释了。
现在将所有 server 区块注释掉,然后创建一个新的 server 区块:
http {
server {
}
}
一般来说,配置文件可能包含几个 server 区块,它们拥有不同的监听端口和 server name。
一旦 nginx 决定好使用哪一个 server 处理用户请求,nginx 测试请求首部的 URI 字段,
将它与 server 区块中的 location 指令定义的参数进行对比。
在 server 区块中添加如下 location 区块:
location / {
root /data/www;
}
这个 location 区块指定 “/” 前缀,并将它和请求首部中的 URI 进行比较。对于匹配的请求,
URI 将被添加到 root 指令所指定的路径的末尾,这里 root 指令定义的路径是 /data/www,
这样形成用户所请求的文件的本地路径。如果有多个 location 区块与请求的 URI 匹配,nginx
选择其中前缀最长的那个 location 区块。
这里的 location 提供了最短的前缀,长度为 1,所以只有当所有其他 location 区块都匹配失败,
才会选择这个 location 区块。
下一步,添加第二个 location 区块:
location /images/ {
root /data;
}
这个 location 区块能够匹配 URI 以 /images/ 起始的请求 (location / 也能匹配这样的请求,但它的
前缀比 /images/ 短,所以优先匹配 location /images/)
我们的 server 区块的配置是这样的:
server {
location / {
root /data/www;
}
location /images/ {
root /data;
}
}
这已经是一个可工作的服务配置,nginx 监听于 80 端口,可通过本地访问 http://localhost/ 。
对于 URI 以 /images/ 起始的请求,nginx 会将 /data/images 目录中的文件发送给客户端。
例如,对于访问请求:http://localhost/images/example.png,nginx 会发送 /data/images/example.png 文件。如果这个文件不存在,nginx 会发送 404 error 响应给客户端。
对于 URI 不是以 /images/ 起始的请求,会被映射到 /data/www 目录。
例如,对于访问请求:http://localhost/some/example.html,nginx 会发送 /data/www/some/example.html 文件。
修改了配置文件之后,为使新配置生效,可重启 nginx ,或者使用 nginx 命令发送 reload 信号给 nginx 主进程:
nginx -s reload
Note:
当出现了错误,请查看 access.log 和 error.log 文件寻找可能的原因。
这两个文件的位置如果是 yum 安装,在 /var/log/nginx 目录下,如果是编译安装,
默认在 prefix/logs/ 目录下。
将 nginx 配置为简单的代理服务器
--------------------------------
nginx 经常被用来设置成一个代理服务器,这时 nginx 接收请求,然后将请求转发给被代理的后端服务器,并从后端服务器取回响应报文,然后发送给客户端。
我们将配置一个基础的代理服务器,服务器对于 image 文件的请求选择从本地响应,对于其他请求,服务器转发给一个后端服务器。在这个示例中,这两个服务器将被定义在同一个 nginx 实例之上。首先定义后端服务器,添加一个 server 区块定义:
server {
listen 8080;
root /data/up1;
location / {
}
}
这个服务器监听在 8080 端口(在前一小节的配置中,我们并没有指定 listen 指令,nginx 默认使用 80 端口),并将所有请求映射到本地的 /data/up1 目录中。创建 /data/up1 目录,并在其中创建一个 index.html 文件。注意 root 指令被放置于 server context 中,这样只有当一个没有包含自己的 root 指令的 location 区块被选中时,这个 server 区块中的 root 指令才会被使用。
[root@lamp1 nginx]# mkdir /data/up1[root@lamp1 nginx]# echo "<h1>backend server</h1>" > /data/up1/index.html
下一步,沿用前一小节的配置,将其修改为一个代理服务器的配置。在第一个 locaiton 区块中加入 proxy_pass 指令,指定后端服务器的:协议、主机名、端口(本例中,指定为 http://localhost:8080):
server {
location / {
proxy_pass http://localhost:8080/;
}
location /images/ {
root /data;
}
}
我们将修改第二个 location 区块,目前这个 location 区块将 URI 以 /images/ 起始的请求映射到
/data/images 目录。将其修改为能够匹配对于典型图像文件的请求,这些图像文件有典型的后缀名:
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
在 “location ~ \.(gif|jpg|png)$” 语句中, ~ EXPRESSION 表示使用正则表达式匹配,
正则表达式为:\.(gif|jpg|png)$。
这个正则表达式能够匹配所有以 .gif, .jpg, .png 结尾的 URI。匹配的请求将被映射到 /data/images 目录中。
当 nginx 选择以哪个 location 区块匹配请求时,nginx 首先检查指定了 prefix 前缀的 location 指令,nginx 会记住被匹配的拥有最长 prefix 的 location 指令,然后开始检查正则表达式。
如果有一个正则表达式被匹配了,nginx 会选择这个正则表达式的 location,如果没有正则表达式被匹配,它选择之前记下的那个拥有最长前缀的 location。
最终我们的配置文件是这样的:
server {
location / {
proxy_pass http://localhost:8080/;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
nginx 服务器会过滤以 .gif, .jpg, .png 为结尾的 URI 的请求,将它们映射到 /data/images 目录中(将 URI 添加到 root 指令的参数后面),并将其他请求转发给后端服务器。
使新的配置生效,执行 nginx -s reload。
在另一个 Linux 虚拟机中测试访问:
[root@vm1 nginx]# curl http://192.168.0.171<h1>backend server</h1>
在浏览器中访问:
http://192.168.0.171/p1035007771.jpg
关于配置代理连接,更深入的探讨可参考:
http://nginx.org/en/docs/http/ngx_http_proxy_module.html
设置 FastCGI 代理
------------------------
nginx 可用于将请求路由到 FastCGI 服务器,在 FastCGI 服务器上运行着以各种框架和编程语言构建的应用,比如 PHP。
配置 nginx 与 FastCGI 服务器协同工作,最基础的配置包括:使用 fastcgi_pass 指令替代 proxy_pass指令,并使用 fastcgi_param 指令设置传递给 FastCGI 服务器的参数。
假设 FastCGI 服务器可通过 localhost:9000 访问,我们以前面的配置为基础,首先将 proxy_pass 指令替换为 fastcgi_pass 指令,指令参数修改为 localhost:9000。在 PHP 中,SCRIPT_FILENAME 参数被用于决定脚本的名称,QUERY_STRING 参数被用于传递请求参数。最终的配置如下:
server {
location / {
fastcgi_pass localhost:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
}
location ~ \.(gif|jpg|png)$ {
root /data/images;
}
}
通过这个配置,对于静态图形文件的请求由本地服务响应,除此之外的请求将通过 FastCGI 协议
被路由到工作于 localhost:9000 的服务器上。
相关推荐
- 让 Python 代码飙升330倍:从入门到精通的四种性能优化实践
-
花下猫语:性能优化是每个程序员的必修课,但你是否想过,除了更换算法,还有哪些“大招”?这篇文章堪称典范,它将一个普通的函数,通过四套组合拳,硬生生把性能提升了330倍!作者不仅展示了“术”,更传授...
- 7 段不到 50 行的 Python 脚本,解决 7 个真实麻烦:代码、场景与可复制
-
“本文整理自开发者AbdurRahman在Stackademic的真实记录,所有代码均经过最小化删减,确保在50行内即可运行。每段脚本都对应一个日常场景,拿来即用,无需额外依赖。一、在朋...
- Python3.14:终于摆脱了GIL的限制
-
前言Python中最遭人诟病的设计之一就是GIL。GIL(全局解释器锁)是CPython的一个互斥锁,确保任何时刻只有一个线程可以执行Python字节码,这样可以避免多个线程同时操作内部数据结...
- Python Web开发实战:3小时从零搭建个人博客
-
一、为什么选Python做Web开发?Python在Web领域的优势很突出:o开发快:Django、Flask这些框架把常用功能都封装好了,不用重复写代码,能快速把想法变成能用的产品o需求多:行业...
- 图解Python编程:从入门到精通系列教程(附全套速查表)
-
引言本系列教程展开讲解Python编程语言,Python是一门开源免费、通用型的脚本编程语言,它上手简单,功能强大,它也是互联网最热门的编程语言之一。Python生态丰富,库(模块)极其丰富,这使...
- Python 并发编程实战:从基础到实战应用
-
并发编程是提升Python程序效率的关键技能,尤其在处理多任务场景时作用显著。本文将系统介绍Python中主流的并发实现方式,帮助你根据场景选择最优方案。一、多线程编程(threading)核...
- 吴恩达亲自授课,适合初学者的Python编程课程上线
-
吴恩达教授开新课了,还是亲自授课!今天,人工智能著名学者、斯坦福大学教授吴恩达在社交平台X上发帖介绍了一门新课程——AIPythonforBeginners,旨在从头开始讲授Python...
- Python GUI 编程:tkinter 初学者入门指南——Ttk 小部件
-
在本文中,将介绍Tkinter.ttk主题小部件,是常规Tkinter小部件的升级版本。Tkinter有两种小部件:经典小部件、主题小部件。Tkinter于1991年推出了经典小部件,...
- Python turtle模块编程实践教程
-
一、模块概述与核心概念1.1turtle模块简介定义:turtle是Python标准库中的2D绘图模块,基于Logo语言的海龟绘图理念实现。核心原理:坐标系系统:原点(0,0)位于画布中心X轴:向右...
- Python 中的asyncio 编程入门示例-1
-
Python的asyncio库是用于编写并发代码的,它使用async/await语法。它为编写异步程序提供了基础,通过非阻塞调用高效处理I/O密集型操作,适用于涉及网络连接、文件I/O...
- 30天学会Python,开启编程新世界
-
在当今这个数字化无处不在的时代,Python凭借其精炼的语法架构、卓越的性能以及多元化的应用领域,稳坐编程语言排行榜的前列。无论是投身于数据分析、人工智能的探索,还是Web开发的构建,亦或是自动化办公...
- Python基础知识(IO编程)
-
1.文件读写读写文件是Python语言最常见的IO操作。通过数据盘读写文件的功能都是由操作系统提供的,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个...
- Python零基础到精通,这8个入门技巧让你少走弯路,7天速通编程!
-
Python学习就像玩积木,从最基础的块开始,一步步搭建出复杂的作品。我记得刚开始学Python时也是一头雾水,走了不少弯路。现在回头看,其实掌握几个核心概念,就能快速入门这门编程语言。来聊聊怎么用最...
- 一文带你了解Python Socket 编程
-
大家好,我是皮皮。前言Socket又称为套接字,它是所有网络通信的基础。网络通信其实就是进程间的通信,Socket主要是使用IP地址,协议,端口号来标识一个进程。端口号的范围为0~65535(用户端口...
- Python-面向对象编程入门
-
面向对象编程是一种非常流行的编程范式(programmingparadigm),所谓编程范式就是程序设计的方法论,简单的说就是程序员对程序的认知和理解以及他们编写代码的方式。类和对象面向对象编程:把...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python进度条 (67)
- python吧 (67)
- python的for循环 (65)
- python格式化字符串 (61)
- python静态方法 (57)
- python列表切片 (59)
- python面向对象编程 (60)
- python 代码加密 (65)
- python串口编程 (77)
- python封装 (57)
- python写入txt (66)
- python读取文件夹下所有文件 (59)
- python操作mysql数据库 (66)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python多态 (60)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)