分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 前端开发

高性能Web服务器Nginx使用指南

发布时间:2023-09-06 02:05责任编辑:苏小强关键词:Web
Nginx是一个高性能的http服务器和反向代理服务器,是一个高度模块化的web服务器,和Apache的模块化不同,Nginx的模块不支持动态编译,Nginx要加入新的第三方模块的时候,必须先下载模块,然后重新编译Nginx,而Apache只需要将新加入的模块编译成so文件,然后配置文件指定是否加载即可,无需重新编译Apache。并且Nginx的rewrite模块会使用正则表示式进行匹配,因此需要pcre软件库的支持,另外ssl加密需要openssl-devel软件库的支持,gzip压缩传输需要zlib-devel软件库的支持。编译安装Nginx之前确定这三个软件库已经安装。


目录

  • Nginx的配置文件结构

  • Nginx的配置文件参数

  • 虚拟主机

  • LNMP架构

  • 状态监控页面

  • URL重写

  • Nginx的负载均衡功能

  • Nginx的缓存服务器应用

  • Nginx的性能优化

  • Nginx的I/O模型


1.Nginx的配置文件结构

通过epel源安装的Nginx的配置文件在/etc/nginx/目录下,对于编译安装的Nginx,其配置文件在安装目录下的conf目录下,Nginx配置文件以block块的形式组织,每个block以{...}为界限,block块中包含各种指令。整体结构分为main层、events块、http块,main是最高层,从上到下继承,位于main层的指令会向下继承至events和http,events块指令会继承至http。http往下分为多个server块,server块再往下分为location块,继承关系是从外到内。

一个完整的Nginx的配置结构如下,

...#全局块,包含main层指令,同时包含events块和http块events{#events块,包含events指令...}http#http块,包含http指令和多个server块{...#http全局指令块server#server块{...#server全局指令块location[PATTERN]#location块{...}location[PATTERN]{...}}server{...}...#http全局块}


2.Nginx的配置文件参数

通过yum安装的Nginx,其配置文件类型如下图所示,当然了,Nginx都会默认为每种类型的配置文件提供一个.default结尾的文件用以参考。

主配置文件nginx.conf

对于rpm安装的Nginx而言,它的主配置文件是由/etc/sysconfig/nginx文件决定的,其中的NGINX_CONF_FILE参数定义主配置文件。

主配置文件的主要参数如下,关于main全局配置

user nginx nginx;定义Nginx的worker进程的用户和用户组,默认是nobody

worker_processes auto;定义开启worker进程的数量

error_log(日志错误级别debug|info|notice|warn|error|crit)定义全局错误日志文件

pid定义nginx的master进程ID的存储文件,防止程序启动多个实例

进程运行后会给pid文件加一个文件锁,只有获得该锁的进程才具有写权限,将自身的pid写入pid文件中,其他试图获得该锁的进程会退出。


关于events事件驱动配置

use epoll; 定义Nginx工作时的I/O模型,支持的I/O模型有select、poll、epoll等,其中select和poll是标准的方式,epoll是高效的工作方式,也是Nginx优先考虑的I/O模型。

work_connections 定义每个worker进程允许的最大的同时连接数,总之,Nginx能够同时打开的最大文件数=worker_processes*work_connections。

注意:Linux系统默认规定进程打开的最大文件数为1024,因此,如果work_connections的值大于1024的话,则无法生效。例如,设置worker_connnects 65535,Nginx在启动之前需要运行命令ulimit -n 65535将进程支持的最大文件数改为65535。


关于http块的配置

log_format定义Nginx的日志输出格式,main为该日志的输出格式名称,下面的指令如果想要调用该日志格式的话,直接引用main关键词即可。

access_log /var/log/nginx/access.log main;定义Nginx被访问的日志,同时引用log_format定义的以main为命名的日志格式。

日志格式中各变量的含义如下,

$remote_addr 客户端IP地址

$remote_user 客户端用户名称

$time_local 访问的时间与时区

$request请求的URL

$status 请求状态(http的请求状态码)

$body_bytes_sent 发送给客户端的文件主体大小

$http_referer 记录从哪个页面链接过来的

$http_user_agent 客户端浏览器的信息

$http_x_forwarded_for 客户端的IP地址

注意:$remote_addr和$http_x_forwarded_for同样都是访问服务器的客户端IP,但是这两者还是有区别的,对于前端设置了反向代理的服务器,$remote_addr是指反向代理服务器的IP地址,$http_x_forwarded_for是指真实的客户端IP地址

charset utf-8 设置网页的编码格式,默认编码为utf-8,还有gb2312等

server_names_hash_bucket_size

服务器名字的hash表大小,nginx的多个server_name是存放在哈希表中的。这样可以提高nginx速度

client_max_body_size客户端请求单个文件的最大字节数

当请求的文件数大于该值的时候,服务器会报出413(Request Entity Too Large)的错误

client_header_buffer_size指定客户端请求头的buffer大小,一般情况下1K大小足以

large_client_header_buffers <number> <size>

请求头大小超过client_header_buffer_size的值时,会将请求头的大小重新设置为large_client_header_buffers的值。例如large_client_header_buffers 4 128K,最大缓存量为4个128K。

上诉两个请求头的buffer的关系,受到http请求时,先根据client_header_buffer_size分配一个buffer,如果buffer无法容纳请求头,那么会根据large_client_header_buffers重新分配buffer。

keepalived_timeout客户端保持连接的超时时间

client_header_timeout客户端请求头读取超时时间

client_body_timeout客户端请求主体读取超时时间

上述请求头和请求主体的超时时间,如果超过时间客户端还没有发送数据,则Nginx返回408(Requesttimeout)的错误。

send_timeout服务端响应的超时时间,对于已经建立的连接,如果客户端在超时时间内没有任何动作,Nginx断开连接。

conf.d/和default.d/扩展配置文件目录
Nginx中引入扩展配置文件的目录是为了降低主配置文件nginx.conf的复杂度,Nginx的http块是由多个server块组成,每个server也是有多个location块组成的,这么多的server和location当然都可以放在一个主配置文件中,但还是server过多的情况下,会使得主配置文件变得十分庞大,而且也不便于管理与修改。因此引入了扩展配置文件目录。

conf.d/目录下存放server块的配置文件,default.d/目录下存放location块的配置文件,引用的时候使用include指令将相对应的server块配置文件和location配置文件加入各自的block块中即可。

http{...<http全局指令>...include/etc/nginx/conf.d/*.conf;}或者server{...<server全局指令>...include/etc/nginx/default.d/*.conf;}

fastcgi_params/fastcgi.conf

Nginx在fastcgi解析的时候,需要调用这两个文件中的服务器变量,内置的服务器变量如下,

这个文件的区别就是.conf比params多了一行fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

uwsgi_params

和fastcgi_params一样,这里是调用关于uwsgi协议的一些服务器变量。

scgi_params

这里是调用关于scgi协议的一些服务器变量。

mime.types

web资源类型配置文件,定义web资源的类型,即文件扩展名和资源类型的映射表,nginx就是根据这个映射表设置http请求响应头的Content-Type值。

mime.types在http块的全局配置中被引用,下面的指令的意思是根据mime.types定义web资源类型,如果在映射表中找不到对应关系,则使用default_type定义的默认资源类型。

koi-win/koi-utf/win-utf

这三个文件都是与编码转换映射相关的文件,用于在输出内容到客户端时,将一种编码转换到另一种编码。

koi-win: charset_map koi8-r < -- > windows-1251

koi-utf: charset_map koi8-r < -- > utf-8

win-utf: charset_map windows-1251 < -- > utf-8


3.虚拟主机

对Nginx而言,一个server块就是一个虚拟主机,我这里将每个server块的配置单独作为一个文件放入conf.d/目录下。然后在主配置文件中include命令包含进来即可。

关于虚拟主机的指令如下,

server {...}虚拟主机开始的关键字

listen address[:port] [default_server]

虚拟主机监听的IP和端口

default_server定义该server为默认,如果所有server段都没有使用该参数,则第一个server为默认

该参数通常在地址列没有输入server_name,而是输入IP地址的时候,Nginx会定位在default_server的虚拟主机。

例: listen 192.168.124.100:80 default_server

server_name指定虚拟主机的域名,可以定义多个域名,之间用空格隔开,可以使用通配符和正则表达式

server_name的作用:Nginx收到一个http请求的时候,会取出首部的server字段,然后和所有server_name字段进行比较,匹配则定位到对应的server块;

server可以是多个,相对应的server_name也会有多个,多个server_name之间的优先顺序是:

精确匹配www.linux.com

左侧通配符匹配*.linux.com

这个左侧通配符匹配实际应用场景很广,www.linux.com、bbs.linux.com、blog.linux.com等都可以通过一个左侧通配符来完成

右侧通配符匹配www.*

正则表达式匹配^.*\.linux\.com$

root 定义虚拟主机的网页根目录,可以是绝对路径,也可是相对路径

index定义虚拟主机默认的首页文件

charset 定义网页的默认编码格式,既可以用于http全局,也可以用于server全局

access_log同样既可以用于http全局,也可以用于server全局

location {...} 地址匹配开始的关键字,location块对URL地址匹配进行设置,支持正则表达式匹配

location和URL进行匹配,匹配成功则进行其中的处理。控制服务端的访问路径

=精确匹配

~正则表达式匹配,区分大小写

~* 正则表达式匹配,不区分大小写

^~URL前半部分匹配,忽略大小写

/ 通用匹配,因为所有的匹配都是以/为开始的

他们的优先级:

= -> ^~ -> ~或者~* -> /

例如:

location^~/bbs.txt{|location^~/bbs{alias/var/www/html/1.txt;|alias/var/www/html/1.txt;}|}location=/bbs.txt{|location=/bbs{alias/var/www/html/2.txt;|alias/var/www/html/2.txt;}|}结果会优先返回优先级高的匹配URL|结果会优先返回优先级高的匹配URL即2.txt的页面内容|即2.txt的页面内容

alias 定义Nginx中别名功能,只能用在location中

tips:

root既可以写在server中,也可以写在location,当同时存在时,内层会替换外层。例如

rootpath1;location/{rootpath2;}location~\.php${}

第一个location生效的是path2,第二个location生效的是path1.

root和alias的区别:

root指定的是根目录,alias指定的是当前目录,

location/html{root/data/web/;}#如果URL请求的是/html/index.html,则nginx会在/data/web/html/目录查找index.html文件location/html{alias/data/web/;}#如果URL请求的是/html/index.html,则nginx会在/data/web/目录下查找index.html文件location~^/download/(.*)${alias/data/web/$1;}#如果URL请求的是/download/nginx.tar.gz,则nginx会在/data/web/目录下查找nginx.tar.gz文件

nginx中配置文件中的正则表达式依赖于pcre库,这也是安装nginx之前为什么必须先安装pcre的原因。

http_geoip_module模块可以处理来自不同地区的访问

include /usr/share/nginx/modules/mod-http-geoip.conf

Nginx -V# 查看Nginx编译过程中的参数

--sbin-path定义开启Nginx的主进程的命令路径

--modules-path定义Nginx的模块的存储路径

--conf-path定义Nginx配置文件的路径

--error-log-path定义错误日志的路径

--http-client-body-temp-path客户端主体请求的临时文件的路径

--http-proxy-temp-pathNginx代理(负载均衡)的临时文件的路径

--http-fastcgi-temp-pathfastcgi的临时文件的路径

--with-file-aio文件的异步IO


4.LNMP架构

现在大多数的电子商务网站都是基于LNMP(Linux+Nginx+MySQL+PHP)架构设计的。LNMP的架构的简单的工作原理如下,

其中,Nginx作为web服务器,响应客户端发来的http请求,和Apache一样,本身只能处理静态请求,而对于动态请求,则需要Nginx与专门的语言解释器进行交互,例如PHP解释器,然后PHP解释器执行php脚本,其中会涉及到一些数据的操作,因此就需要到后端的数据库服务器中存取数据。最后php的执行结果交给nginx,nginx继而将结果返回给客户端。

fastcgi:

nginx收到的请求不能直接转发给php,因为php不认识,反过来,php处理后的结果也不能直接返回给nginx,因此需要在他们两者中间加入公共接口,即fastcgi,使得nginx和php都能够支持fastcgi,当nginx和php交互的时候,都需要通过fastcgi协议的处理。

PHP和php-fpm的关系:

php-fpm是php和fastcgi的管理器,它其实php的一个补丁,是为了将fastcgi的管理器整合到php中,这样一来,仅可以通过php-fpm服务,既可以管理fastcgi进程,也可以reload重新加载php(在修改php的配置文件php.ini后无需重新启动php)。

因此LNMP详细的工作流程是,Nginx收到浏览器的web请求后,Nginx自身处理其中的静态请求,例如图片、视频等,对于动态请求,Nginx将其通过fastcgi处理后转发给php-fpm进程,php-fpm调用php解析器执行fastcgi处理后的php脚本,期间php再连接数据库进行数据的操作,php解析器处理完毕后,将结果转发给php-fpm进程,php-fpm将结果通过fastcgi交付给Nginx,最后Nginx将最终的结果返回给浏览器。

LNMP搭建过程:

①安装Nginx,为了方便我这里使用yum安装,当然也可以使用源码编译安装,我使用的阿里云的epel源,直接在Linux中输入如下命令,就可以成功配置yum仓库。

[root@CentOS6~]#wget-O/etc/yum.repos.d/epel.repohttp://mirrors.aliyun.com/repo/epel-6.repo[root@CentOS6~]#yummakecache[root@CentOS6~]#yum-yinstallnginx

我这里安装的nginx版本是1.10.2

②安装数据库mysql,直接使用本地base源即可。

[root@CentOS6~]#yum-yinstallmysql-server

安装成功之后会发现也会为我们安装mysql客户端工具,用于连接mysql服务端。

然后创建用于存放数据的数据库wordpress,赋予用户wordpress使用该数据库的所有权限,并设置连接数据库的秘密centos,


[root@CentOS6~]#mysqlmysql>createdatabasewordpress;mysql>grantallonwordpress.*towordpress@'%'identifiedby'centos';mysql>flushprivileges;

③接下来就是php和及其扩展包的安装,同样使用base源即可

[root@CentOS6~]#yum-yinstallphpphp-mysql

④安装统一管理php解释器和fastcgi进程的工具php-fpm。

[root@CentOS6~]#yum-yinstallphp-fpm

修改php-fpm的工作进程的用户和用户组为nobody.nobody(需要同Nginx工作进程的用户/用户组一致,我这里设置的是nobody.nobody),这样做的目的是限制php-fpm和Nginx的权限。php-fpm的配置文件是/etc/nginx/php-fpm.d/www.conf

修改后的内容如下,其他的指令保持默认。

⑤修改Nginx的配置,使其能将动态请求转发给php-fpm。

Nginx主配置文件的内容如下:

[root@CentOS6nginx]#cat/etc/nginx/nginx.confusernobodynobody;worker_processesauto;error_log/var/log/nginx/error.log;pid/var/run/nginx.pid;events{useepoll;worker_connections1024;}http{log_formatmain'$remote_addr-$remote_user[$time_local]"$request"''$status$body_bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"';access_log/var/log/nginx/access.logmain;keepalive_timeout65;charsetutf-8;include/etc/nginx/mime.types;default_typeapplication/octet-stream;include/etc/nginx/conf.d/*.conf;#引用server块的扩展配置文件}

Nginx的server块的扩展配置文件内容如下,

[root@CentOS6conf.d]#cat/etc/nginx/conf.d/default.conf##Thedefaultserver#server{listen80;server_namewordpress.linux.com;root/data/web;location/{indexindex.php;}location~\.php${fastcgi_pass127.0.0.1:9000;#运行php-fpm进程的ip和端口fastcgi_indexindex.php;#定义网页的入口文件fastcgi_paramSCRIPT_FILENAME$document_root$fastcgi_script_name;include/etc/nginx/fastcgi_params;}}

⑥测试LNMP架构是否成功

在nginx服务器的/data/web/(由root指令决定)目录下,创建index.php文件,写入连接数据库和php的测试代码

[root@CentOS6~]#cd/data/web[root@CentOS6web]#catindex.php<?php$link=mysql_connect("192.168.239.129","wordpress","centos");#三个参数分别为运行数据库服务的IP地址,用户,密码if($link)echo"success";elseecho"failed";phpinfo();?>

在windows的hosts文件中添加记录,

192.168.239.129wordpress.linux.com

然后在浏览器中出现如下如所示的界面,表示LNMP架构已经搭建完成。


利用LNMP架构搭建博客,下载wordpress,将解压后的所有文件放在/data/web/目录下,需要保持这些文件的用户和用户组和nginx进程的保持一致,因此设置这些文件的用户和组为nobody。

[root@CentOS6web]#chown-Rnobody.nobody/data/web/*


然后修改其中的wp-config.php文件,该文件主要用于连接数据库配置,主要修改的内容如下,

/**ThenameofthedatabaseforWordPress*/define('DB_NAME','wordpress');/**MySQLdatabaseusername*/define('DB_USER','wordpress');/**MySQLdatabasepassword*/define('DB_PASSWORD','centos');/**MySQLhostname*/define('DB_HOST','192.168.239.129');

最后在浏览器中输入wordpress.linux.com,首次访问需要完成安装的步骤,按照指示一步步完成即可。最后再次访问该域名,出现如下界面表示博客搭建成功。这样LNMP的一个实际应用就已经实现了。



tips:

LNMP搭建网站的时候,首次都需要连接数据库的步骤,该步骤的完成通常都是修改源码中的config.php文件来完成的(例如该例中的wp-config.php),该文件中一般定义了要连接的数据库的名称,用户和用户口令等信息。

LNMP和LAMP的区别:

LAMP中的php是作为Apache的一个模块存在的,所以php和Apache共存亡;LNMP中的php是作为一个单独的服务存在的,通过php-fpm进行管理。


5.状态监控页面

Nginx内置了StubStatus的工作模块,该模块可以监控Nginx的工作状态。监控页面完成通过一个location就可以完成,location的配置如下,

location/status{stub_statuson;#开启状态监控的功能access_log/var/log/nginx/status.log;#定义状态页面的访问日志#采用auth_basic认证机制auth_basic"NginxStatus";#定义状态页面的名称auth_basic_user_file/etc/nignx/conf.d/htpasswd;#指定密码文件}

其实只需要stub_status on就可以开启Nginx的状态监控功能,和上边的区别就是没有日志记录文件,没有密码认证的功能。

另外auth_basic认证机制的密码文件需要Apache的htpasswd命令生成。

[root@CentOS6default.d]#htpasswd-c/etc/nignx/conf.d/htpasswdadmin#允许登录的用户为admin,然后根据指示设置密码#因为nginx的工作进程为nobody,因此需要将密码文件对nobody用户有r--权限[root@CentOS6default.d]#chownnobody.nobody/etc/nignx/conf.d/htpasswd[root@CentOS6conf.d]#chmod400htpasswd[root@CentOS6conf.d]#llhtpasswd-r--------.1nobodynobody20Jul1903:03htpasswd

然后在浏览器中输入wordpress.linux.com/status,输入正确的用户名和密码后,就可以看到状态页面。


Nginx的状态页面的参数含义:

Active connections 当前活动的客户端连接数

accepts 已经累计收到的客户端连接数量

handled 已经处理的客户端连接数量

requests 客户端的总的请求数量

accepts/handled/requests这三个参数的区别是:

客户端发起的总的请求数是requests,服务端可以不接受请求,也即实际接受的请求数是accepts,而服务器在接受的请求数中实际处理的请求数是handled

reading 正在读取的客户端请求数量

writing 正在发送响应报文的连接数量

waiting 等待发送请求的空闲连接数量

对于长连接,还需要等待用户发送数据等等的情况,因此会出现空闲连接。


6.URL重写

Nginx的配置文件支持类似shell编程的逻辑判断,对于不同的请求定义不同的规则。

URI/URN/URL的区别

URI统一资源标识符,URI由URN和URL组成,mailto:John.Doe@example.com

URN 统一资源名称,代表资源的名称,John.Doe

URL 统一资源定位符,代表资源的路径,mailto:example.com

if判断指令

if (condition) {...},仅仅在server和location块中使用

condition是一个变量的时候,为空或者以0开头的字符串都将被判定为false

逻辑判断表达式:

=或!=等于或不等于

正则表达式匹配:

~ 区分大小写的匹配

~* 不区分大小写的匹配

!~区分大小写的不匹配

!~* 不区分大小写的不匹配

文件/目录匹配:

-f/!-f 文件是否存在

-d/!-d 目录是否存在

-e/!-e 文件或者目录是否存在

-x/!-x 文件是否可以执行

Nginx内置的全局变量

$host 请求主机头字段,即server_name

$http_user_agent 客户端agent信息,即客户端使用的何种浏览器,这个值一定要根据日志access.log中显示的浏览器信息为依据,尤其是IE浏览器,之前我就以MSIE为IE的http_user_agent,结果实验老是失败。

$http_cookie 会话标识

$limit_rate 限制连接速率,例如网盘的限速

$request_meathod客户端请求的动作

$remote_addr 客户端的IP地址

$request_filename 当前请求的文件路径

$scheme http方法(http或者https)

$server_protocol http协议版本

$server_addr 服务器IP地址

$server_name 服务器名称

$server_port 服务器的端口号

$request_uri 包含参数的URI,例如www.xxx.com/xxx.php?xxx

rewrite指令

只能用在server、location、if中,并且只能对URL中的非传递参数的字符串起作用。

rewrite和location都能实现地址跳转,但是两者还是有区别的,rewrite是在同一域名内改变资源路径,而location是对一类路径做访问控制,他们的执行顺序是server中rewrite->location-

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved