企业高性能web服务器

web服务器介绍

Apache HTTP Server:也称为Apache,是一个开源的HTTP服务器,目前是全球使用最广泛的Web服务器

Nginx:Nginx是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器

Microsoft Internet Information Services (IIS):IIS是由微软开发的一种Web服务器软件,用于在Windows操作系统上提供服务

Lighttpd:Lighttpd是一个开源的Web服务器,具有低内存占用和高并发处理能力

Node.js:Node.js本身并不是一个HTTP服务器,但它可以通过HTTP模块创建一个HTTP服务器,因此也可以用作HTTP服务程序

Tomcat:Tomcat是一个开源的Java Servlet容器,用于在Java平台上提供HTTP服务

Jetty:Jetty是一个开源的Java HTTP服务器和Servlet容器,具有高性能和低内存占用的特点

Caddy:Caddy是一个现代的,易于使用的HTTP/2服务器,具有自动HTTPS功能

apache

Apache(或httpd)服务,是Internet上使用最多的Web服务器技术之一,通俗来讲就是一个用于搭建网站的服务。

有两个版本:1.x和2.x

http:超文本传输协议,通过线路以明文形式发送,默认使用80端口/TCP
https:经TLS/SSL安全加密的超文本传输协议,默认使用443端口/TCP

 Apache的配置文件

	配置文件   存放位置
服务目录	/etc/httpd
主配置文件	/etc/httpd/conf/httpd.conf
虚拟主机的配置文件目录
配置文件								存放位置
服务目录							   /etc/httpd
主配置文件					       /etc/httpd/conf/httpd.conf
虚拟主机的配置文件目录				   /etc/httpd/conf.d
基于用户的配置文件					   /etc/httpd/conf.d/userdir.conf
日志文件目录					       /etc/httpd/logs
默认的网站数据目录					   /var/www/html

主配置文件的重要参数 

主配置文件:/etc/httpd/conf/httpd.conf
参数	作用	参数	作用
serverRoot			服务目录			Servername				网站服务器的域名
Listen			监听的IP地址端口号		DocumentRoot			默认网站数据目录
User			运行服务的用户		Directory				文件目录权限
Group			运行服务的用户组		DirectoryIndex			默认的索引页面
Serveradmin		管理员邮箱			ErrorLog				错误日志文件

 Apache prefork 模型

  • 预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024
  • 每个子进程有一个独立的线程响应用户请求
  • 相对比较占用内存,但是比较稳定,可以设置最大和最小进程数
  • 是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景
优点:稳定
缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景

 

 Apache worker 模型

  • 一种多进程和多线程混合的模型
  • 有一个控制进程,启动多个子进程
  • 每个子进程里面包含固定的线程
  • 使用线程程来处理请求
  • 当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求,
  • 由于其使用了线程处理请求,因此可以承受更高的并发
优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在prefork模式下,同样会发生)

 Apache event模型

  • Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)
  • 每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
  • 它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题(某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
  • 当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场景下的请求处理能力
优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keepalive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制

 Nginx—高性能的web服务器

Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提IMAP/POP3/SMTP服务。 

Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、简单的配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx 是高性能的 HTTP 和反向代理的web服务器,处理高并发能力是十分强大的,能经受高负 载的考验,有报告表明能支持高达 50,000 个并发连接数。
Nginx支持热部署,启动简单,可以做到7*24不间断运行。几个月都不需要重新启动。

 基于Nginx的工作场景:

 nginx功能介绍

  • 静态的web资源服务器html,图片,jscsstxt等静态资源
  • http/https协议的反向代理
  • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
  • tcp/udp协议的请求转发(反向代理)
  • imap4/pop3协议的反向代理

nginx基础特性 

  • 模块化设计,较好的扩展性
  • 高可靠性
  • 支持热部署:不停机更新配置文件,升级版本,更换日志文件
  • 低内存消耗:10000keep-alive连接模式下的非活动连接,仅需2.5M内存
  • event-driven,aio,mmapsendfile

Web 服务相关的功能

  • 虚拟主机(server
  • 支持 keep-alive 和管道连接(利用一个连接做多次请求)
  • 访问日志(支持基于日志缓冲提高其性能)url rewirte
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须中断客户的工作进程

Nginx 架构和进程

 Nginx 进程结构
web请求处理机制
  • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求
  • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成。

主进程(master process)的功能:
  • 对外接口:接收外部的操作(信号)
  • 对内转发:根据外部的操作的不同,通过信号管理 Worker
  • 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
  • 读取Nginx 配置文件并验证其有效性和正确性
  • 建立、绑定和关闭socket连接
  • 按照配置生成、管理和结束工作进程
  • 接受外界指令,比如重启、升级及退出服务器等指令
  • 不中断服务,实现平滑升级,重启服务并应用新的配置
  • 开启日志文件,获取文件描述符
  • 不中断服务,实现平滑升级,升级失败进行回滚处理
  • 编译和处理perl脚本
工作进程(worker process)的功能:
  • 所有 Worker 进程都是平等的
  • 实际处理:网络请求,由 Worker 进程处理
  • Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争CPU资源,
  • 增加上下文切换的损耗
  • 接受处理客户的请求
  • 将请求依次送入各个功能模块进行处理
  • I/O调用,获取响应数据
  • 与后端服务器通信,接收后端服务器的处理结果
  • 缓存数据,访问缓存索引,查询和调用缓存数据
  • 发送请求结果,响应客户的请求
  • 接收主程序指令,比如重启、升级和退出等

Nginx 启动和 HTTP 连接建立  

Nginx 启动时, Master 进程,加载配置文件
Master 进程,初始化监听的 socket
Master 进程, fork 出多个 Worker 进程
Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求

nginx的源码编译

nginx官网:

 https://nginx.org/en/download.html

我们使用1.24.0.版本的

[root@nginx ~]# ll
总用量 1096
drwxr-xr-x. 2 root root       6  8月  9 05:33 公共
drwxr-xr-x. 2 root root       6  8月  9 05:33 模板
drwxr-xr-x. 2 root root       6  8月  9 05:33 视频
drwxr-xr-x. 2 root root       6  8月  9 05:33 图片
drwxr-xr-x. 2 root root       6  8月  9 05:33 文档
drwxr-xr-x. 2 root root       6  8月  9 05:33 下载
drwxr-xr-x. 2 root root       6  8月  9 05:33 音乐
drwxr-xr-x. 2 root root       6  8月  9 05:33 桌面
-rw-------. 1 root root    1235  8月  9 05:26 anaconda-ks.cfg
-rw-r--r--. 1 root root 1112471  8月 15 07:21 nginx-1.24.0.tar.gz
-rw-r--r--. 1 root root     597  8月  9 05:44 vmset.sh

我们将nginx压缩包解压缩

[root@nginx ~]# tar -zxvf  nginx-1.24.0.tar.gz
[root@nginx nginx-1.24.0]# ll
总用量 816
drwxr-xr-x. 6 1001 1001   4096  8月 15 07:22 auto
-rw-r--r--. 1 1001 1001 323312  4月 10  2023 CHANGES
-rw-r--r--. 1 1001 1001 494234  4月 10  2023 CHANGES.ru
drwxr-xr-x. 2 1001 1001    168  8月 15 07:22 conf
-rwxr-xr-x. 1 1001 1001   2611  4月 10  2023 configure
drwxr-xr-x. 4 1001 1001     72  8月 15 07:22 contrib
drwxr-xr-x. 2 1001 1001     40  8月 15 07:22 html
-rw-r--r--. 1 1001 1001   1397  4月 10  2023 LICENSE
drwxr-xr-x. 2 1001 1001     21  8月 15 07:22 man
-rw-r--r--. 1 1001 1001     49  4月 10  2023 README
drwxr-xr-x. 9 1001 1001     91  8月 15 07:22 src

创建名为nginx的用户和组 


[root@nginx objs]# useradd -s /sbin/nologin -M nginx
[root@nginx objs]# id nginx
用户id=1001(nginx) 组id=1001(nginx) 组=1001(nginx)

# 不可以登陆

其中有个文件configure,他的作用是环境检测,检测我们当前环境安装nginx缺少那些依赖

[root@Nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \  
# 指定我们的安装目录
--user=nginx \ # 指定nginx运行用户
--group=nginx \ # 指定nginx运行组
--with-http_ssl_module \ # 支持https://
--with-http_v2_module \ # 支持http版本2
--with-http_realip_module \ # 支持ip透传
--with-http_stub_status_module \ # 支持状态页面
--with-http_gzip_static_module \ # 支持压缩
--with-pcre \ # 支持正则
--with-stream \ # 支持tcp反向代理
--with-stream_ssl_module \ # 支持tcp的ssl加密
--with-stream_realip_module # 支持tcp的透传ip

我们可以通过执行这个文件,并在其后通过加一些参数来指定我们的nginx需要的功能,但是增加的参数越多,需要的依赖就越多,可以通过--help来查看我们需要的参数

[root@nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \
> --user=nginx \
> --group=nginx \
> --with-http_ssl_module \
> --with-http_v2_module \
> --with-http_realip_module \
> --with-http_stub_status_module \
> --with-http_gzip_static_module \
> --with-pcre \
> --with-stream \
> --with-stream_ssl_module
checking for OS
 + Linux 5.14.0-162.6.1.el9_1.x86_64 x86_64
checking for C compiler ... not found

./configure: error: C compiler cc is not found

根据报错信息可知,我们缺少了 C语言的编译器,yum安装即可:

[root@nginx nginx-1.24.0]# yum install gcc -y

安装完成后再次执行上一个命令

./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.

这次给的报错,发现少了一个PCRE,我们可以通过yum search 来找对应的包

[root@nginx nginx-1.24.0]# yum search PCRE
正在更新 Subscription Management 软件仓库。
无法读取客户身份

本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。

上次元数据过期检查:0:03:00 前,执行于 2024年08月15日 星期四 07时42分29秒。
============================= 名称 和 概况 匹配:PCRE =============================
pcre-cpp.i686 : C++ bindings for PCRE
pcre-cpp.x86_64 : C++ bindings for PCRE
pcre-devel.i686 : Development files for pcre
pcre-devel.x86_64 : Development files for pcre   # 这就是pcre的开发包
pcre-utf16.i686 : UTF-16 variant of PCRE
pcre-utf16.x86_64 : UTF-16 variant of PCRE
pcre-utf32.i686 : UTF-32 variant of PCRE
pcre-utf32.x86_64 : UTF-32 variant of PCRE
pcre2-devel.i686 : Development files for pcre2
pcre2-devel.x86_64 : Development files for pcre2
pcre2-syntax.noarch : Documentation for PCRE2 regular expressions
pcre2-utf16.i686 : UTF-16 variant of PCRE2
pcre2-utf16.x86_64 : UTF-16 variant of PCRE2
pcre2-utf32.x86_64 : UTF-32 variant of PCRE2
pcre2-utf32.i686 : UTF-32 variant of PCRE2
postfix-pcre.x86_64 : Postfix PCRE map support
================================= 名称 匹配:PCRE =================================
pcre.x86_64 : Perl-compatible regular expression library
pcre.i686 : Perl-compatible regular expression library
pcre2.x86_64 : Perl-compatible regular expression library
pcre2.i686 : Perl-compatible regular expression library

找到后继续安装,然后执行上一条命令

[root@nginx nginx-1.24.0]# yum install pcre-devel.x86_64 -y
./configure: error: SSL modules require the OpenSSL library.
You can either do not enable the modules, or install the OpenSSL library
into the system, or build the OpenSSL library statically from the source
with nginx by using --with-openssl=<path> option.

这次的报错发现少了一个OpenSSL,我们继续找他对应的包

[root@nginx nginx-1.24.0]# yum search openssl
正在更新 Subscription Management 软件仓库。
无法读取客户身份

本系统尚未在权利服务器中注册。可使用 subscription-manager 进行注册。

上次元数据过期检查:0:07:56 前,执行于 2024年08月15日 星期四 07时42分29秒。
===================================================================== 名称 精准匹配:openssl =====================================================================
openssl.x86_64 : Utilities from the general purpose cryptography library with TLS implementation
=================================================================== 名称 和 概况 匹配:openssl ===================================================================
apr-util-openssl.x86_64 : APR utility library OpenSSL crypto support
openssl-devel.i686 : Files for development of applications which will use OpenSSL
openssl-devel.x86_64 : Files for development of applications which will use OpenSSL
openssl-perl.x86_64 : Perl scripts provided with OpenSSL
openssl-pkcs11.x86_64 : A PKCS#11 engine for use with OpenSSL
openssl-pkcs11.i686 : A PKCS#11 engine for use with OpenSSL
perl-Crypt-OpenSSL-Bignum.x86_64 : Perl interface to OpenSSL for Bignum
perl-Crypt-OpenSSL-RSA.x86_64 : Perl interface to OpenSSL for RSA
perl-Crypt-OpenSSL-Random.x86_64 : OpenSSL/LibreSSL pseudo-random number generator access
rsyslog-openssl.x86_64 : TLS protocol support for rsyslog via OpenSSL library
xmlsec1-openssl.x86_64 : OpenSSL crypto plugin for XML Security Library
xmlsec1-openssl.i686 : OpenSSL crypto plugin for XML Security Library
======================================================================= 名称 匹配:openssl =======================================================================
compat-openssl11.i686 : Utilities from the general purpose cryptography library with TLS implementation
compat-openssl11.x86_64 : Utilities from the general purpose cryptography library with TLS implementation
openssl-libs.x86_64 : A general purpose cryptography library with TLS implementation
openssl-libs.i686 : A general purpose cryptography library with TLS implementation
======================================================================= 概况 匹配:openssl =======================================================================
perl-Net-SSLeay.x86_64 : Perl extension for using OpenSSL
qatengine.x86_64 : Intel QuickAssist Technology (QAT) OpenSSL Engine

然后安装对应的包openssl_devel.x86_64,我们的系统是x86_64的

[root@nginx nginx-1.24.0]# yum install openssl-devel.x86_64  -y

安装完成后,继续执行上一条命令

./configure: error: the HTTP gzip module requires the zlib library.
You can either disable the module by using --without-http_gzip_module
option, or install the zlib library into the system, or build the zlib library
statically from the source with nginx by using --with-zlib=<path> option.

根据报错发现少了个zlib,根据之前的经验,我们可以尝试安装zlib-devel 这个包

[root@nginx nginx-1.24.0]# yum install zlib-devel -y

然后继续执行上一条命令

Configuration summary
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

到这,所有的依赖都安装完成,检测完成。

[root@nginx nginx-1.24.0]# ll
总用量 820
drwxr-xr-x. 6 1001 1001   4096  8月 15 07:22 auto
-rw-r--r--. 1 1001 1001 323312  4月 10  2023 CHANGES
-rw-r--r--. 1 1001 1001 494234  4月 10  2023 CHANGES.ru
drwxr-xr-x. 2 1001 1001    168  8月 15 07:22 conf
-rwxr-xr-x. 1 1001 1001   2611  4月 10  2023 configure
drwxr-xr-x. 4 1001 1001     72  8月 15 07:22 contrib
drwxr-xr-x. 2 1001 1001     40  8月 15 07:22 html
-rw-r--r--. 1 1001 1001   1397  4月 10  2023 LICENSE
-rw-r--r--. 1 root root    438  8月 15 07:54 Makefile
drwxr-xr-x. 2 1001 1001     21  8月 15 07:22 man
drwxr-xr-x. 3 root root    125  8月 15 07:54 objs
-rw-r--r--. 1 1001 1001     49  4月 10  2023 README
drwxr-xr-x. 9 1001 1001     91  8月 15 07:22 src

# 检测编译完成后objs里面生成的文件才是我们这个软件运行时所需要的 
[root@nginx nginx-1.24.0]# make clean

通过make clean我们可以将我们之前检测的操作换原,换原成最初状态,对应的检测完成后新增的两个包也会消失

然后执行我们下面的命令,进行编译

[root@nginx nginx-1.24.0]# make && make install
  1. make:这部分命令用于编译源代码。make 命令会根据 Makefile 文件中定义的规则来编译源代码,生成可执行文件或者库文件等。在这个过程中,会检查是否有必要重新编译文件(即源文件是否被修改过),然后仅编译那些被修改过的文件,以提高编译效率。如果一切顺利,make 命令执行完毕后,会在当前源代码目录下生成编译好的可执行文件或者库文件,但不会自动安装到系统的指定目录下。

  2. make install:在 make 命令成功执行后,make install 命令才会被执行。这个命令会根据 Makefile 中定义的安装规则,将编译好的文件安装到指定的目录,比如 /usr/local/nginx(这取决于 Makefile 的配置)。这一步通常涉及复制文件到系统目录、设置权限等操作,以便系统可以正常使用这些文件。

[root@nginx nginx-1.24.0]# cd objs/
[root@nginx objs]# ll
总用量 5672
-rw-r--r--. 1 root root   17214  8月 15 07:54 autoconf.err
-rw-r--r--. 1 root root   52929  8月 15 07:54 Makefile
-rwxr-xr-x. 1 root root 5654232  8月 15 08:04 nginx
-rw-r--r--. 1 root root    5537  8月 15 08:04 nginx.8
-rw-r--r--. 1 root root    7990  8月 15 07:54 ngx_auto_config.h
-rw-r--r--. 1 root root     657  8月 15 07:54 ngx_auto_headers.h
-rw-r--r--. 1 root root    8758  8月 15 07:54 ngx_modules.c
-rw-r--r--. 1 root root   42928  8月 15 08:04 ngx_modules.o
drwxr-xr-x. 9 root root      91  8月 15 07:54 src

现在objs里面的文件就是我们的启动程序

此时我们可以通过自带的执行脚本启动nginx

[root@nginx ~]# cd /usr/local/nginx/sbin/
[root@nginx sbin]# ll
总用量 5524
-rwxr-xr-x. 1 root root 5654232  8月 15 08:04 nginx
[root@nginx sbin]# ./nginx

我们可以通过ps查看nginx是否启动

[root@nginx sbin]# ps aux | grep nginx
root       14829  0.0  0.0   9832   932 ?        Ss   08:10   0:00 nginx: master process ./nginx
nginx      14830  0.0  0.2  13720  5388 ?        S    08:10   0:00 nginx: worker process
root       14833  0.0  0.1 221680  2376 pts/1    S+   08:11   0:00 grep --color=auto nginx

nginx默认两个进程,一个master管理进程和worker工作进程

查看端口

[root@nginx sbin]# netstat -antlupe | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          47399      14829/nginx: master
[root@nginx sbin]# ss -ltn | grep :80
LISTEN 0      511          0.0.0.0:80        0.0.0.0:*
[root@nginx sbin]# lsof -i :80
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
nginx   14829  root    6u  IPv4  47399      0t0  TCP *:http (LISTEN)
nginx   14830 nginx    6u  IPv4  47399      0t0  TCP *:http (LISTEN)

以上三种方式都可以使用

因为此时开启了debug模式,使用编译完成后的文件比较大

[root@nginx sbin]# du -sh nginx
5.4M    nginx

我们可以关掉debug模式,重新编译

[root@nginx sbin]# ./nginx -s stop
# 先关闭nginx
[root@nginx sbin]# rm -rf /usr/local/nginx/
# 删除nginx文件
[root@nginx nginx-1.24.0]# make clean
rm -rf Makefile objs

# 回到检测之前的状态
[root@nginx nginx-1.24.0]# ll
总用量 816
drwxr-xr-x. 6 nginx nginx   4096  8月 15 07:22 auto
-rw-r--r--. 1 nginx nginx 323312  4月 10  2023 CHANGES
-rw-r--r--. 1 nginx nginx 494234  4月 10  2023 CHANGES.ru
drwxr-xr-x. 2 nginx nginx    168  8月 15 07:22 conf
-rwxr-xr-x. 1 nginx nginx   2611  4月 10  2023 configure
drwxr-xr-x. 4 nginx nginx     72  8月 15 07:22 contrib
drwxr-xr-x. 2 nginx nginx     40  8月 15 07:22 html
-rw-r--r--. 1 nginx nginx   1397  4月 10  2023 LICENSE
drwxr-xr-x. 2 nginx nginx     21  8月 15 07:22 man
-rw-r--r--. 1 nginx nginx     49  4月 10  2023 README
drwxr-xr-x. 9 nginx nginx     91  8月 15 07:22 src

关闭nginx的debug模式

[root@nginx nginx-1.24.0]# vim auto/cc/gcc


# debug
# CFLAGS="$CFLAGS -g"
#通过vim文本编辑器锁定debug,将这个参数禁止掉

然后再执行之前的检测操作,最后我们再查看编译后的大小

[root@nginx sbin]# du -sh nginx
1.2M    nginx
[root@nginx sbin]# pwd
/usr/local/nginx/sbin

#关闭了debug模式后,明显变小

为了启动nginx的时候不写那么一长串,我们可以通过增加参数达到效果

[root@nginx ~]# vim ~/.bash_profile

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs
export  PATH=$PATH:/usr/local/nginx/sbin
#在最后一行增加
[root@nginx ~]# source ~/.bash_profile

#重新加载并执行当前用户主目录下的.bash_profile文件中的命令和设置。

现在只需要一个nginx就可以启动

[root@nginx ~]# nginx
[root@nginx ~]# netstat -antlupe | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          54991      18045/nginx: master

nginx的配置目录

[root@nginx conf]# pwd
/usr/local/nginx/conf

配置文件

[root@nginx conf]# vim nginx.conf

查看版本

[root@nginx ~]# nginx -v
nginx version: nginx/1.24.0

nginx命令参数

[root@Nginx ~]# nginx -v
nginx version: nginx/1.26.1
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
Options:
-?,-h : this help
-v : show version and exit
-V : show version and configure options then exit #显示版本和编译参数
-t : test configuration and exit #测试配置文件是否异
-T : test configuration, dump it and exit #测试并打印
-q : suppress non-error messages during configuration testing #静默
模式
-s signal : send signal to a master process: stop, quit, reopen, reload #
发送信号,reload信号 会生成新的worker,但master不会重新生成
-p prefix : set prefix path (default: /etc/nginx/) #指定Nginx 目录
-c filename : set configuration file (default: /etc/nginx/nginx.conf) #
配置文件路径
-g directives : set global directives out of configuration file #设置全局指令,注意和
配置文件不要同时配置,否则冲突

nginx的平滑升级及版本回滚

有时候我们需要对Nginx版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时Nginx又在跑着业务无法停掉,这时我们就可能选择平滑升级
平滑升级流程

  • 将旧Nginx二进制文件换成新Nginx程序文件(注意先备份)
  • master进程发送USR2信号
  • master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin
  • master进程用新Nginx文件启动新master进程成为旧master的子进程,系统中将有新旧两个Nginx进程共同提供Web服务,当前新的请求仍然由旧Nginxworker进程进行处理,将新生成的master程的PID存放至新生成的pid文件nginx.pid
  • 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止
  • 向旧master进程发送QUIT信号,关闭老master,并删除Nginx.pid.oldbin文件
  • 如果发现升级有问题,可以回滚∶向老master发送HUP,向新master发送QUIT
 实战
升级

我们先上传一个高版本的nginx软件包,我就要1.26.1版本

[root@nginx ~]# ll
总用量 2312
drwxr-xr-x. 2 root  root        6  8月  9 05:33 公共
drwxr-xr-x. 2 root  root        6  8月  9 05:33 模板
drwxr-xr-x. 2 root  root        6  8月  9 05:33 视频
drwxr-xr-x. 2 root  root        6  8月  9 05:33 图片
drwxr-xr-x. 2 root  root        6  8月  9 05:33 文档
drwxr-xr-x. 2 root  root        6  8月  9 05:33 下载
drwxr-xr-x. 2 root  root        6  8月  9 05:33 音乐
drwxr-xr-x. 2 root  root        6  8月  9 05:33 桌面
-rw-------. 1 root  root     1235  8月  9 05:26 anaconda-ks.cfg
drwxr-xr-x. 9 nginx nginx     186  8月 15 08:27 nginx-1.24.0
-rw-r--r--. 1 root  root  1112471  8月 15 07:21 nginx-1.24.0.tar.gz
-rw-r--r--. 1 root  root  1244738  8月 15 08:47 nginx-1.26.1.tar.gz

进行解压缩,之后就是进行检测编译,但这次只需执行make,无需执行make install,因为老版本的nginx依然在工作

[root@nginx ~]# tar -zxvf nginx-1.26.1.tar.gz
[root@nginx ~]# cd nginx-1.26.1/
[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre --with-stream --with-stream_ssl_module
[root@Nginx nginx-1.26.1]# make

此时我们就有了两个版本的nginx

[root@nginx nginx-1.26.1]# ll objs/nginx  /usr/local/nginx/sbin/nginx
-rwxr-xr-x. 1 root root 5727344  8月 15 08:51 objs/nginx
-rwxr-xr-x. 1 root root 1237312  8月 15 08:27 /usr/local/nginx/sbin/nginx

#一个是当前正在使用的,一个是编译好的
把之前的旧版的 nginx 命令备份
[root@nginx sbin]# ll
总用量 1212
-rwxr-xr-x. 1 root root 1237312  8月 15 08:27 nginx
[root@nginx sbin]# cp nginx nginx.24
[root@nginx sbin]# ll
总用量 2424
-rwxr-xr-x. 1 root root 1237312  8月 15 08:27 nginx
-rwxr-xr-x. 1 root root 1237312  8月 15 08:53 nginx.24

把新版本的复制过去,把之前的版本就覆盖了,然后使用nginx -t 进行检查

[root@nginx sbin]# \cp -f /root/nginx-1.26.1/objs/nginx  /usr/local/nginx/sbin/

[root@nginx sbin]# ll
总用量 6808
-rwxr-xr-x. 1 root root 5727344  8月 15 08:55 nginx
-rwxr-xr-x. 1 root root 1237312  8月 15 08:53 nginx.24
[root@nginx sbin]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

 此时注意,在没有升级前我们的版本为1.24.0

[root@nginx sbin]# ps -aux | grep nginx
root       21245  0.0  0.1   9836  3620 ?        Ss   09:10   0:00 nginx: master process nginx
nginx      21272  0.0  0.2  13724  5340 ?        S    09:12   0:00 nginx: worker process
root       21385  0.0  0.1 221680  2312 pts/1    S+   09:20   0:00 grep --color=auto nginx
[root@nginx sbin]# kill -USR2 21245
[root@nginx sbin]# ps -aux | grep nginx
root       21245  0.0  0.1   9836  3620 ?        Ss   09:10   0:00 nginx: master process nginx
nginx      21272  0.0  0.2  13724  5340 ?        S    09:12   0:00 nginx: worker process
root       21386  0.0  0.2   9836  5916 ?        S    09:21   0:00 nginx: master process nginx
nginx      21387  0.0  0.2  13724  4756 ?        S    09:21   0:00 nginx: worker process
root       21395  0.0  0.1 221680  2300 pts/1    S+   09:21   0:00 grep --color=auto nginx

 USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx

此时两个 master 的进程都在运行 , 只是旧的 master 不在监听 , 由新的 master 监听 80
此时 Nginx 开启一个新的 master 进程,这个 master 进程会生成新的 worker 进程,这就是升级后的 Nginx 进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

 我们通过-WINCH 参数回收旧版本,新版本生效

[root@nginx sbin]# kill -WINCH 21245
# 将老版本的worker进程回收掉
[root@nginx sbin]# ps -aux | grep nginx
root       21245  0.0  0.1   9836  3620 ?        Ss   09:10   0:00 nginx: master process nginx
root       21386  0.0  0.2   9836  5916 ?        S    09:21   0:00 nginx: master process nginx
nginx      21387  0.0  0.2  13724  4756 ?        S    09:21   0:00 nginx: worker process
root       21398  0.0  0.1 221680  2384 pts/1    S+   09:22   0:00 grep --color=auto nginx

 回滚
如果升级的版本发现问题需要回滚 , 可以重新拉起旧版本的 worker
[root@nginx sbin]# cp nginx nginx.26
[root@nginx sbin]# ll
总用量 8020
-rwxr-xr-x. 1 root root 1237312  8月 15 09:20 nginx
-rwxr-xr-x. 1 root root 1237312  8月 15 09:25 nginx.24
-rwxr-xr-x. 1 root root 5727344  8月 15 09:11 nginx.26
[root@nginx sbin]# mv nginx.24 nginx
mv:是否覆盖'nginx'? y
[root@nginx sbin]# kill -HUP 21245   # 把老版本的worker激活
[root@nginx sbin]# ps aux | grep nginx
root       21245  0.0  0.1   9836  3620 ?        Ss   09:10   0:00 nginx: master process nginx
root       21386  0.0  0.2   9836  5916 ?        S    09:21   0:00 nginx: master process nginx
nginx      21387  0.0  0.2  13724  5184 ?        S    09:21   0:00 nginx: worker process
nginx      21413  0.0  0.2  13724  4800 ?        S    09:27   0:00 nginx: worker process
root       21417  0.0  0.1 221680  2292 pts/1    S+   09:27   0:00 grep --color=auto nginx
[root@nginx sbin]# kill -WINCH 21386  # 回收新版本的worker
[root@nginx sbin]# ps aux | grep nginx
root       21245  0.0  0.1   9836  3620 ?        Ss   09:10   0:00 nginx: master process nginx
root       21386  0.0  0.2   9836  5916 ?        S    09:21   0:00 nginx: master process nginx
nginx      21413  0.0  0.2  13724  4800 ?        S    09:27   0:00 nginx: worker process
root       21419  0.0  0.1 221680  2372 pts/1    S+   09:27   0:00 grep --color=auto nginx

如果不行让别人访问时看到你的版本,我们可以通过在 这个目录里面修改配置文件

[root@nginx core]# pwd
/root/nginx-1.26.1/src/core

[root@nginx core]# ls
nginx.c           ngx_crc32.h  ngx_md5.c              ngx_proxy_protocol.h  ngx_shmtx.h
nginx.h           ngx_crc.h    ngx_md5.h              ngx_queue.c           ngx_slab.c
ngx_array.c       ngx_crypt.c  ngx_module.c           ngx_queue.h           ngx_slab.h
ngx_array.h       ngx_crypt.h  ngx_module.h           ngx_radix_tree.c      ngx_spinlock.c
ngx_bpf.c         ngx_cycle.c  ngx_murmurhash.c       ngx_radix_tree.h      ngx_string.c
ngx_bpf.h         ngx_cycle.h  ngx_murmurhash.h       ngx_rbtree.c          ngx_string.h
ngx_buf.c         ngx_file.c   ngx_open_file_cache.c  ngx_rbtree.h          ngx_syslog.c
ngx_buf.h         ngx_file.h   ngx_open_file_cache.h  ngx_regex.c           ngx_syslog.h
ngx_conf_file.c   ngx_hash.c   ngx_output_chain.c     ngx_regex.h           ngx_thread_pool.c
ngx_conf_file.h   ngx_hash.h   ngx_palloc.c           ngx_resolver.c        ngx_thread_pool.h
ngx_config.h      ngx_inet.c   ngx_palloc.h           ngx_resolver.h        ngx_times.c
ngx_connection.c  ngx_inet.h   ngx_parse.c            ngx_rwlock.c          ngx_times.h
ngx_connection.h  ngx_list.c   ngx_parse.h            ngx_rwlock.h
ngx_core.h        ngx_list.h   ngx_parse_time.c       ngx_sha1.c
ngx_cpuinfo.c     ngx_log.c    ngx_parse_time.h       ngx_sha1.h
ngx_crc32.c       ngx_log.h    ngx_proxy_protocol.c   ngx_shmtx.c
[root@nginx core]# vim nginx.h

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


#ifndef _NGINX_H_INCLUDED_
#define _NGINX_H_INCLUDED_


#define nginx_version      1026001
#define NGINX_VERSION      "1.0"
#define NGINX_VER          "lf/" NGINX_VERSION

#ifdef NGX_BUILD
#define NGINX_VER_BUILD    NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD    NGINX_VER
#endif

#define NGINX_VAR          "NGINX"
#define NGX_OLDPID_EXT     ".oldbin"


#endif /* _NGINX_H_INCLUDED_ */
~

nginx启动文件编写

nginx默认情况下没有启动文件,所以我们需要手动编写

[root@nginx ~]# vim /lib/systemd/system/nginx.service
# 我们在这个文件中编写,system/后的文件可以随意起,为了规范一些我就起nginx.service

[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
# 这一部分是我们的环境

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid    #pid位置
ExecStartPre=/usr/local/nginx/sbin/nginx -t   # 执行nginx前看看配置文件有没有问题
ExecStart=/usr/local/nginx/sbin/nginx         # 启动命令
ExecReload=/usr/local/nginx/sbin/nginx -s reload   
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
# 这一部分是启动服务的主体

[Install]
WantedBy=multi-user.target
# 这个表示开启启动下在那个模式做

然后执行

[root@nginx ~]# systemctl daemon-reload
# 重新加载 systemd 管理器的配置
# 通常位于 /etc/systemd/system/ 或 /usr/lib/systemd/system/ 目录下),或者更新了 systemd 的软件包后,需要通知 systemd 重新加载这些配置文件,以确保新的配置生效
[root@nginx ~]# systemctl start nginx.service

我们先关闭之前开启的nginx服务,然后用我们的启动文件进行启动 

[root@nginx ~]# nginx -s stop
[root@nginx ~]# ps aux | grep nginx
root       24148  0.0  0.1 221680  2472 pts/2    S+   05:19   0:00 grep --color=auto nginx
[root@nginx ~]# systemctl start nginx.service
[root@nginx ~]# ps aux | grep nginx
root       24153  0.0  0.0   9848   972 ?        Ss   05:20   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      24154  0.0  0.2  13656  4816 ?        S    05:20   0:00 nginx: worker process
root       24156  0.0  0.1 221680  2408 pts/2    S+   05:20   0:00 grep --color=auto nginx

nginx核心参数

配置文件说明
Nginx的配置文件的组成部分:
  • 主配置文件:nginx.conf
  • 子配置文件: include conf.d/*.conf
  • fastcgi uwsgiscgi 等协议相关的配置文件
  • mime.types:支持的mime类型,MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,MIME消息能包含文本、图像、音频、视频以及其他应用程序专用的数据,是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

nginx 配置文件格式说明  

 配置文件由指令与指令块构成

每条指令以 ; 分号结尾,指令与值之间以空格符号分隔
可以将多条指令放在同一行 , 用分号分隔即可 , 但可读性差 , 不推荐
指令块以 { } 大括号将多条指令组织在一起 , 且可以嵌套指令块
include 语句允许组合多个配置文件以提升可维护性
使用 # 符号添加注释,提高可读性
使用 $ 符号使用变量
部分指令的参数支持正则表达式

Nginx 主配置文件的配置指令方式:  

directive value [value2 ...];
注意
(1) 指令必须以分号结尾
(2) 支持使用配置变量
内建变量:由Nginx模块引入,可直接引用
自定义变量:由用户使用set命令定义,格式: set variable_name value;
引用变量:$variable_name
主配置文件结构:四部分
main block:主配置段,即全局配置段,对http,mail都有效
#事件驱动相关的配置
event {
...
}
#http/https 协议相关配置段
http {
...
}
#默认配置文件不包括下面两个块
#mail 协议相关配置段
mail {
...
}
#stream 服务器相关配置段
stream {
...
}
默认的nginx.conf 配置文件格式说明  
#全局配置端,对全局生效,主要设置nginx的启动用户/组,启动的工作进程数量,工作模式,Nginx的PID路
径,日志路径等。
user nginx nginx;
worker_processes 1;    #启动工作进程数数量
events { #events       #设置快,主要影响nginx服务器与用户的网络连接,比如是否允许同时接受多
                       个网络连接,使用哪种事件驱动模型 #处理请求,每个工作进程可以同时支持的
                        最大连接数,是否开启对多工作进程下的网络连接进行序列化等。
worker_connections 1024;         #设置单个nginx工作进程可以接受的最大并发,作为web服务器
         的时候最大并发数为 #worker_connections *worker_processes,作为反向代理的时候为 
         (worker_connections * worker_processes)/2
}
http {                         #http块是Nginx服务器配置中的重要部分,缓存、代理和日志格                                                                    
                               式定义等绝大多数功能和第三方模块都 #可以在这设置,http块可
                              以包含多个server块,而一个server块中又可以包含多个location块,
                                #server块可以配置文件引入、MIME-Type定义、日志自定义、是
                                否启用sendfile、连接超时时间和 #单个链接的请求上限等。
include mime.types;
default_type application/octet-stream;
sendfile on;             #作为web服务器的时候打开sendfile加快静态文件传输,指定是否使用
                         #sendfile系统调用来传输文件
                         #sendfile系统调用在两个文件描述符之间直接传递数据(完全在内核中操作)
                         #从而避免了数据在内核缓冲区和用户缓冲区之间的拷贝,操作效率很高,被称                    
                         之为零拷贝,
                         #硬盘 >> kernel buffer (快速拷贝到kernelsocket
buffer) >>协议栈。
keepalive_timeout 65;     #长连接超时时间,单位是秒
server {             #设置一个虚拟机主机,可以包含自己的全局快,同时也可以包含多个location模块
                      #比如本虚拟机监听的端口、本虚拟机的名称和IP配置,多个server 可以使用一个            
                      端口比如都使用 #80端口提供web服务
listen 80;             #配置server监听的端口

server_name localhost; #本server的名称,当访问此名称的时候nginx会调用当前serevr内部的配置进程匹配。
location / {         #location其实是server的一个指令,为nginx服务器提供比较多而且灵活的指令
                       #都是在location中体现的,主要是基于nginx接受到的请求字符串
                        #对用户请求的UIL进行匹配,并对特定的指令进行处理
                        #包括地址重定向、数据缓存和应答控制等功能都是在这部分实现
                        #另外很多第三方模块的配置也是在location模块中配置。
root html;             #相当于默认页面的目录名称,默认是安装目录的相对路径,可以使用绝对路径配置。
index index.html index.htm; #默认的页面文件名称
}
error_page 500 502 503 504 /50x.html;     #错误页面的文件名称
location = /50x.html {         #location处理对应的不同错误码的页面定义到/50x.html
                            #这个跟对应其server中定义的目录下。
root html;                 #定义默认页面所在的目录
}
}
#和邮件相关的配置
#mail {
# ...
# }         mail 协议相关配置段
#tcp代理配置,1.9版本以上支持
#stream {
# ...
# }                     stream 服务器相关配置段
#导入其他路径的配置文件
#include /apps/nginx/conf.d/*.conf
}
全局配置
Main 全局配置段常见的配置指令分类
  • 正常运行必备的配置
  • 优化性能相关的配置
  • 用于调试及定位问题相关的配置
  • 事件驱动相关的配置

全局配置说明: 

user nginx nginx;                 #启动Nginx工作进程的用户和组
worker_processes [number | auto]; #启动Nginx工作进程的数量,一般设为和CPU核心数相同
worker_cpu_affinity 00000001 00000010 00000100 00001000 | auto ;
#将Nginx工作进程绑定到指定的CPU核心,默认Nginx是不进行进程绑定的,绑定并不是意味着当前nginx进
程独占以一核心CPU,但是可以保证此进程不运行在其他核心上,这就极大减少了nginx的工作进程在不同的
cpu核心上的来回跳转,减少了CPU对进程的资源分配与回收以及内存管理等,因此可以有效的提升nginx服务
器的性能。
CPU MASK: 00000001:0号CPU
00000010:1号CPU
10000000:7号CPU
#示例
worker_cpu_affinity 0001 0010 0100 1000;第0号---第3号CPU
worker_cpu_affinity 0101 1010;
#示例
worker_processes 4;
worker_cpu_affinity 00000010 00001000 00100000 10000000;
[root@centos8 ~]# ps axo pid,cmd,psr | grep nginx
31093 nginx: master process /apps 1
34474 nginx: worker process 1
34475 nginx: worker process 3
34476 nginx: worker process 5
34477 nginx: worker process 7
     #错误日志记录配置,语法:error_log file [debug | info | notice | warn | error | crit
| alert | emerg]
#error_log logs/error.log;
#error_log logs/error.log notice;
error_log /usr/local/nginx/logs/error.log error;
#pid文件保存路径
pid /usr/local/nginx/logs/nginx.pid;
worker_priority 0; #工作进程优先级,-20~20(19)
worker_rlimit_nofile 65536; #所有worker进程能打开的文件数量上限,
#包括:Nginx的所有连接(例如与代理服务器的连接等)
#而不仅仅是与客户端的连接
#另一个考虑因素是实际的并发连接数不能超过系统级别的最大打开文件
数的限制
#最好与ulimit -n 或者limits.conf的值保持一致,
#修改pam限制
[root@Nginx ~]# sudo -u nginx ulimit -n
1024
[root@Nginx ~]# vim /etc/security/limits.conf
* - nofile 100000
[root@Nginx ~]# sudo -u nginx ulimit -n
100000
daemon off;                 #前台运行Nginx服务用于测试、docker等环境。
master_process off|on;      #是否开启Nginx的master-worker工作模式,仅用于开发调试场景,默认为
on
events {
worker_connections 65535;         #设置单个工作进程的最大并发连接数
use epoll;                         #使用epoll事件驱动,
                                #Nginx支持众多的事件驱动,
                                #比如:select、poll、epoll,只能设置在events模块中设置
accept_mutex on;                 #on为同一时刻一个请求轮流由work进程处理,
                                #而防止被同时唤醒所有worker
                                #避免多个睡眠进程被唤醒的设置,默认为off
                                #新请求会唤醒所有worker进程,此过程也称为"惊群"
                        #因此nginx刚安装完以后要进行适当的优化。建议设置为onmulti_accept on; 
                        #on时Nginx服务器的每个工作进程可以同时接受多个新的网络连接
                                #此指令默认为off,
                                #即默认为一个工作进程只能一次接受一个新的网络连接
                                #打开后几个同接受多个。建议设置为on
}
nginx全局参数优化

打开我们/usr/local/nginx/conf/nginx.conf下的文件,进行参数优化

user  nginx;   # 根据我们编译nginx时的用户进行修改,默认是nobady,且是不启用的
worker_processes  auto;   #启动Nginx工作进程的数量,一般设为和CPU核心数相同,auto为自动,也可以指定
worker_cpu_affinity 00000001 00000010;  #将Nginx工作进程绑定到指定的CPU核心

修改完成后,这是没有进行配置文件更新的状态,此时我们只要一个worker进程 

[root@nginx ~]# ps ax | grep nginx
  24153 ?        Ss     0:00 nginx: master process /usr/local/nginx/sbin/nginx
  24154 ?        S      0:00 nginx: worker process
  24256 pts/2    S+     0:00 grep --color=auto nginx

当我们继续更新配置文件后,我们再看

[root@nginx ~]# nginx -s reload
[root@nginx ~]# ps ax | grep nginx
  24153 ?        Ss     0:00 nginx: master process /usr/local/nginx/sbin/nginx
  24263 ?        S      0:00 nginx: worker process
  24264 ?        S      0:00 nginx: worker process
  24266 pts/2    S+     0:00 grep --color=auto nginx

由于我的电脑是双核,所以他就出了两个进程。

实现 nginx 的高并发配置

我们此时能支持的单个工作进程的最大并发连接数为1024,默认配置不支持高并发

[root@nginx ~]# ulimit -a
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 7490
max locked memory           (kbytes, -l) 64
max memory size             (kbytes, -m) unlimited
open files                          (-n) 1024 
# 我们本机支持的最大打开数量也是1024
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 7490
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

 此时我们可以通过编辑/etc/security/limits.conf文件来修改打开的文件数量上限

 此时我们通过sudo命令,超级用户可以使用任何身份进行访问,来查看我们nginx用户的最大文件打开数量

[root@nginx ~]# sudo -u nginx ulimit -n
10000
[root@nginx ~]# sudo -u nginx ulimit -a
real-time non-blocking time  (microseconds, -R) unlimited
core file size              (blocks, -c) 0
data seg size               (kbytes, -d) unlimited
scheduling priority                 (-e) 0
file size                   (blocks, -f) unlimited
pending signals                     (-i) 7490
max locked memory           (kbytes, -l) 64
max memory size             (kbytes, -m) unlimited
open files                          (-n) 10000
pipe size                (512 bytes, -p) 8
POSIX message queues         (bytes, -q) 819200
real-time priority                  (-r) 0
stack size                  (kbytes, -s) 8192
cpu time                   (seconds, -t) unlimited
max user processes                  (-u) 7490
virtual memory              (kbytes, -v) unlimited
file locks                          (-x) unlimited

此时我们就可以修改/usr/local/nginx/conf/nginx.conf文件下的参数,并且使用epoll模型

核心配置示例

基于不同的IP、不同的端口以及不用得域名实现不同的虚拟主机,依赖于核心模块 ngx_http_core_module实现。

新建一个 PC web 站点

如果我们在原配置文件中进行增加,文件会变得非常长,不利于我们继续修改,查看,使用我们可以新增一个web 站点,将我们要写的内容全部放到新文件中,但是需要在源配置文件中指定新web站点的位置

指定子配置文件的位置,并且写在后面,否则不生效

没有的话我们可以新建这个子配置文件,在这个目录下创建文件,进行编写

[root@nginx ~]# mkdir -p /usr/local/nginx/conf.d/
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录
    index  index.html;                  # 指定了默认索引文件
}
~

创建目录

[root@nginx ~]# mkdir -p /data/web/html
[root@nginx ~]# echo www.haha.org > /data/web/html/index.html

配置完成后进行校验,刷新

[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

在测试之前可以把你的域名加到你的本地解析里面,就是你windows下system32里面drives里面etc下hosts文件

把域名和ip加进去,保存,要是不能保存就修改一下文件的属性,

测试:

root alias 
root:指定web的家目录,在定义location的时候,文件的绝对路径等于 root+location
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

  # 当server 和 location同时写了root,loaction会覆盖掉上面的路径
    location /test1 {
        root /data/web;           # 当你访问test1时,你实际访问的是/data/web/te
                                  # st1
    }
}


# location中没有写索引文件时,默认使用server中的
[root@nginx ~]# mkdir /data/web/test1 -p
[root@nginx ~]# echo hello world > /data/web/test1/
[root@nginx ~]# echo hello world > /data/web/test1/index.html
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

测试:

如果访问不到,也可以通过错误日志排查,

[root@nginx ~]# more /usr/local/nginx/logs/error.log
alias:定义路径别名,会把访问的路径重新定义到其指定的路径,文档映射的另一种机制;仅能用于
location上下文,此指令使用较少
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

  # 当server 和 location同时写了root,loaction会覆盖掉上面的路径
    location /test1 {
        root /data/web;           # 当你访问test1时,你实际访问的是/data/web/te                              
                                  # st1
    }


    location /test2 {
        alias /data/web/test1;       #写是真实的文件存在路径,不加location
    }

}

测试·:相当于做了个软连接

location中使用root指令和alias指令的意义不同
root # 给定的路径对应于 location 中的 /uri 左侧的 /
alias # 给定的路径对应于 location 中的 /uri 的完整路径
location 的详细使用  
在一个 server location 配置段可存在多个,用于实现从 uri 到文件系统的路径映射;
ngnix 会根据用户请求的 URI 来检查定义的所有 location ,按一定的优先级找出一个最佳匹配,
而后应用其配置在没有使用正则表达式的时候, nginx 会先在 server 中的多个 location 选取匹配度最高的一个uri
uri 是用户请求的字符串,即域名后面的 web 文件路径
然后使用该 location 模块中的正则 url 和字符串,如果匹配成功就结束搜索,并使用此 location 处理此请求
#语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
=          #用于标准uri前,需要请求字串与uri精确匹配,大小敏感,如果匹配成功就停止向下匹配并立
           #即处理请求
^~         #用于标准uri前,表示包含正则表达式,并且匹配以指定的正则表达式开头
           #对uri的最左边部分做匹配检查,不区分字符大小写
~          #用于标准uri前,表示包含正则表达式,并且区分大小写
~*         #用于标准uri前,表示包含正则表达式,并且不区分大写
不带符号    #匹配起始于此uri的所有的uri
\          #用于标准uri前,表示包含正则表达式并且转义字符。可以将 . * ?等转义为普通符号

示例

不带符号

[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件


    location /test {
        root /data/web/test;
    }

}
[root@nginx ~]# mkdir  /data/web/test1/
[root@nginx ~]# mkdir  /data/web/test/
[root@nginx ~]# echo hello > /data/web/test/index.html

l

使用^~ 

我们多建几个以t开头的目录,写入不同的内容

[root@nginx ~]# mkdir /data/web/t1
[root@nginx ~]# mkdir /data/web/t2
[root@nginx ~]# echo zei > /data/web/t1/index.html
[root@nginx ~]# echo ni  > /data/web/t2/index.html
[root@nginx ~]# ll /data/web
总用量 0
drwxr-xr-x. 2 root root 24  8月 16 06:48 html
drwxr-xr-x. 2 root root 24  8月 16 10:01 t1
drwxr-xr-x. 2 root root 24  8月 16 10:01 t2
drwxr-xr-x. 2 root root 24  8月 16 09:21 test
drwxr-xr-x. 2 root root 24  8月 16 07:04 test1
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

    location ^~ /t {
        root /data/web;
    }

 }

 

使用 ~和 ~*

[root@nginx /]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

    location ~ /t {
        root /data/web;
    }

 }

[root@nginx /]# vim /usr/local/nginx/conf.d/vhosts.conf
[root@nginx /]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

    location ~* /t {
        root /data/web;
    }

 }

 

~ 和 *~唯一的区别就是一个区分大小写一个不区分大小写 

  1. = 精确匹配:当Nginx找到带有=location块时,它会停止搜索其他location块,并直接使用这个location块来处理请求。=表示请求的URI必须完全匹配location后面的URI才能被这个location块处理。因此,=具有最高的优先级。

  2. ^~ 前缀匹配:如果Nginx没有找到=精确匹配的location块,它会继续搜索是否有以^~开头的location块。如果有,并且请求的URI以该location块中指定的URI作为前缀,Nginx将停止搜索其他location块,并使用这个location块来处理请求。^~的优先级低于=但高于正则表达式匹配和普通前缀匹配。

  3. 正则表达式匹配(~ 和 ~*

    • ~ 表示区分大小写的正则表达式匹配。
    • ~* 表示不区分大小写的正则表达式匹配。

    如果Nginx既没有找到=也没有找到^~匹配的location块,它会搜索正则表达式匹配的location块。这些location块会按照它们在配置文件中出现的顺序进行检查,一旦找到匹配的正则表达式,Nginx就会停止搜索并使用这个location块来处理请求。如果配置文件中有多个正则表达式location块可以匹配请求,Nginx将使用它们出现的顺序中的第一个。

  4. 普通前缀匹配:如果Nginx既没有找到=^~匹配的location块,也没有找到正则表达式匹配的location块,它会尝试找到最长的普通前缀匹配的location块。然后,它会根据这个location块或更具体的配置(如try_files指令)来处理请求。

  5. / 通用匹配:如果没有找到任何其他匹配的location块,Nginx会使用在server块中定义的、通常没有任何前缀或正则表达式的location / {...}块作为最后的选择。这通常被称为“捕获所有”的location块。

= 精确匹配的优先级最高,其次是^~前缀匹配,然后是正则表达式匹配(~ 和 ~*),最后是普通前缀匹配和“捕获所有”的location / {...}块 

 Nginx 账户认证功能

ngx_http_auth_basic_module 模块提供此功能

创建认证文件

[root@nginx ~]# htpasswd -cm /usr/local/nginx/.htpasswd admin
New password:
Re-type new password:
Adding password for user admin

[root@nginx ~]# cat /usr/local/nginx/.htpasswd
admin:$apr1$JOOq07xd$kz.bQNVu/3drKKvx3/Eqr1


# -cm   c表示创建 
#  -m 选项表示使用MD5算法对密码进行加密
# usr/local/nginx/.htpasswd 是你想要创建的密码文件的路径
# .htpasswd 表示将文件隐藏
# 也可以加 -b 后面加密码,表示非交互式

注:二次创建的时候需要把-c参数去掉,否则之前创建的用户会被覆盖

[root@nginx ~]# mkdir /data/web/admin
[root@nginx ~]# echo admin > /data/web/admin/
[root@nginx ~]# echo admin > /data/web/admin/index.html

修改子配置文件

[root@nginx ~]# cat  /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件

    location  /admin {
        root /data/web;
        auth_basic "login password !!"
        auth_basic_user_file "/usr/local/nginx/./htpasswd" 
         # 指定我们的认证文件路径
    }

 }

检测·:

Nginx自定义错误页面
自定义错误页,同时也可以用指定的响应状态码进行响应, 可用位置:http, server, location, if in
location
error_page code ... [=[response]] uri;
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件
    error_page 404 /40x.html;            # 当你报404时,查看/40x.html文件

    location /admin {
        root /data/web;
        auth_basic "login password";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
        }

    location = /40x.html {
        root /data/web/errorpage;           #有指定到errorpage 这个目录
    }
}
[root@nginx ~]# mkdir -p /data/web/errorpage
[root@nginx ~]# echo error page  >/data/web/errorpage/40x.html

# 创建目录,将自定义内容写到文件中

 Nginx自定义错误日志
可以自定义错误日志
Syntax: error_log file [level];
Default:
error_log logs/error.log error;
Context: main, http, mail, stream, server, location
level: debug, info, notice, warn, error, crit, alert, emerg

我们新建一个目录用于存放自定义日志

[root@nginx ~]# mkdir /var/log/nginx
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhosts.conf

server  {
    listen 80;                          # 监听80端口
    server_name www.haha.org;           # 访问 www.haha.org 可以看到发布的东西
    root /data/web/html;                # 设置了请求的根目录 root+目录
    index  index.html;                  # 指定了默认索引文件
    error_page 404 /40x.html;            # 当你报404时,查看/40x.html文件
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
# 将原本的默认的access_log 自定义到我们新路径下的access.log(可以起任何名字)

# 将原本的默认的error_log 自定义到我们新路径下的error.log(可以起任何名字)

    location /admin {
        root /data/web;
        auth_basic "login password";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
        }

    location = /40x.html {
        root /data/web/errorpage;           #有指定到errorpage 这个目录
    }
}

 在未重启前,我们的目录下什么都没有

[root@nginx ~]# cd /var/log/nginx/
[root@nginx nginx]# ll
总用量 0

重启并访问之后

[root@nginx nginx]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx nginx]# nginx -s reload
[root@nginx nginx]# curl www.haha.org/test
error page
[root@nginx nginx]# curl www.haha.org/admin
<html>
<head><title>401 Authorization Required</title></head>
<body>
<center><h1>401 Authorization Required</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>
[root@nginx nginx]# cd /var/log/nginx/
[root@nginx nginx]# ll
总用量 8
-rw-r--r--. 1 root root 190  8月 16 11:19 access.log
-rw-r--r--. 1 root root 208  8月 16 11:19 error.log
[root@nginx nginx]#
Nginx检测文件是否存在

try_files 会按顺序检查文件是否存在,返回第一个找到的文件或文件夹(结尾加斜线表示为文件夹),如果所有文件或文件夹都找不到,会进行一个内部重定向到最后一个参数。只有最后一个参数可以引起一个内部重定向,之前的参数只设置内部URI 的指向。最后一个参数是回退 URI 且必须存在,否则会出现内部500 错误。

 语法格式

Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location

uri:就是我访问的路径。路径.html, 路径/idnex.html 如果都不存在,就访问/error下的内容,如果/error下也不存在就报500的错误

 创建这个目录,并自定义内容

[root@nginx nginx]# mkdir /data/web/html/error/ -p
[root@nginx nginx]# echo " index.html is not exist " > /data/web/html/error/default.html

测试:正常情况下,路径都存在

[root@nginx nginx]# curl www.haha.org
www.haha.org

找不到路径并且/error/default.html也不存在的情况下

[root@nginx nginx]# curl www.haha.org
<html>
<head><title>500 Internal Server Error</title></head>
<body>
<center><h1>500 Internal Server Error</h1></center>
<hr><center>nginx/1.26.1</center>
</body>
</html>

找不到路径,但/error/default.html存在的情况下

[root@nginx nginx]# curl www.haha.org
 index.html is not exist
Nginx长连接配置
keepalive_timeout timeout [header_timeout]; #设定保持连接超时时长,0表示禁止长连接,
                                            默认为75s
                                            #通常配置在http字段作为站点全局配置
keepalive_requests 数字;                    #在一次长连接上所允许请求的资源的最大数量
                                            #默认为100次,建议适当调大,比如:500

在主配置文件中进行修改

 连接时长我们先关闭,长连接允许请求的最大资源数我们先设置为2

测试:我们按照默认的配置使用telnet命令来进行测试

telnet 检测端口是否正常

GET / HTTP/1.1         输入动作
HOST: www.haha.org   输入访问 HOST
按两次回车

根据之前的配置,我们访问2次之后他就自动中止了,

由此可知:

keepalive_requests 数字  ; 数字是几他就只能访问几次

keepalive_timeout   数字 ;  设定保持连接超时时长,0表示禁止长连接

keepalive_timeout 65 60;
开启长连接后,返回客户端的会话保持时间为 60s ,单次长连接累计请求达到指定次数请求或 65 秒就会被断开,第二个数字60 为发送给客户端应答报文头部中显示的超时时间设置为 60s :如不设置客户端将不显示超时时间
 Nginx作为下载服务器配置
ngx_http_autoindex_module 模块处理以斜杠字符 "/" 结尾的请求,并生成目录列表,可以做为下载服务
配置使用
相关指令:
autoindex on | off;             #自动文件索引功能,默为off
autoindex_exact_size on | off;   #计算文件确切大小(单位bytes),off 显示大概大小(单位K、
                                 # M),默认on
autoindex_localtime on | off ;   #显示本机时间而非GMT(格林威治)时间,默认off
autoindex_format html | xml | json | jsonp; #显示索引的页面文件风格,默认html
limit_rate rate;                 #限制响应客户端传输速率(除GET和HEAD以外的所有方法),单位
B/s,bytes/second,               #默认值0,表示无限制,此指令由ngx_http_core_module提供
set $limit_rate 4k;             #也可以通变量限速,单位B/s,同时设置,此项优级高.

建立一个下载目录

[root@nginx ~]# mkdir /data/web/download

创建一个大文件

[root@nginx ~]# dd if=/dev/zero of=/data/web/download/file bs=1M count=100

记录了100+0 的读入
记录了100+0 的写出
104857600字节(105 MB,100 MiB)已复制,0.324275 s,323 MB/s

注:做一个大小为100M的文件,文件的路径为/data/web/download/file,数据的来源为/dev/zero下

修改子配置文件

autoindex on;        自动索引功能
autoindex_exact_size on;   
计算文件确切大小(单位 bytes ),此为默认值 ,off 只显示 大概大小(单位kb mb gb
autoindex_localtime on;
on 表示显示本机时间而非 GMT( 格林威治 ) 时间 , 默为为 off
GMT 时间
limit_rate 1024k;      限速 , 默认不限速

 检测

Nginx 高级配置

Nginx 状态页

基于 nginx 模块 ngx_http_stub_status_module 实现,
在编译安装 nginx 的时候需要添加编译参数 --with-http_stub_status_module
否则配置完成之后监测会是提示法错误
注意: 状态页显示的是整个服务器的状态,而非虚拟主机的状态
#配置示例:
location /nginx_status {
stub_status;
auth_basic "auth login";
auth_basic_user_file /apps/nginx/conf/.htpasswd;
allow 192.168.0.0/16;
allow 127.0.0.1;
deny all;
}
#状态页用于输出nginx的基本状态信息:
#输出信息示例:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三个数字分别对应accepts,handled,requests三个值
Reading: 6 Writing: 179 Waiting: 106
Active connections:                         #当前处于活动状态的客户端连接数
                                            #包括连接等待空闲连接数=reading+writing+waiting
accepts:                              #统计总值,Nginx自启动后已经接受的客户端请求连接的总数。
handled:                             #统计总值,Nginx自启动后已经处理完成的客户端请求连接总数
                              #通常等于accepts,除非有因worker_connections限制等被拒绝的连接
requests:                                     #统计总值,Nginx自启动后客户端发来的总的请求数
Reading:                                    #当前状态,正在读取客户端请求报文首部的连接的连接数
                                            #数值越大,说明排队现象严重,性能不足
Writing:                #当前状态,正在向客户端发送响应报文过程中的连接数,数值越大,说明访问量很大
Waiting:                 #当前状态,正在等待客户端发出请求的空闲连接数
开启 keep-alive的情况下,这个值等于active –(reading+writing)

实战:

配置我们的子配置文件,内容较多,我们新增一个子配置文件

[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload
[root@nginx ~]# vim /usr/local/nginx/conf.d/status.conf
[root@nginx ~]# cat  /usr/local/nginx/conf.d/status.conf
server {
    listen 80;
    server_name status.haha.org;
    root   /data/web/html;
    index   index.html;


    location  /status {
        stub_status;
        auth_basic "login";                                          # 认证参数可加可不加
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
    }
}

在我们windows进行域名解析

访问测试:

 Nginx 压缩功能

Nginx 支持对指定类型的文件进行压缩然后再传输给客户端,而且压缩还可以设置压缩比例,压缩后的文件大小将比源文件显著变小,样有助于降低出口带宽的利用率,降低企业的IT 支出,不过会占用相应的CPU 资源。

 Nginx对文件的压缩功能是依赖于模块 ngx_http_gzip_module,默认是内置模块

配置指令如下:
#启用或禁用gzip压缩,默认关闭
gzip on | off;
#压缩比由低到高从1到9,默认为1,值越高压缩后文件越小,但是消耗cpu比较高。基本设定未4或者5
gzip_comp_level 4;
#禁用IE6 gzip功能,早期的IE6之前的版本不支持压缩
gzip_disable "MSIE [1-6]\.";
#gzip压缩的最小文件,小于设置值的文件将不会压缩
gzip_min_length 1k;
#启用压缩功能时,协议的最小版本,默认HTTP/1.1
gzip_http_version 1.0 | 1.1;
#指定Nginx服务需要向服务器申请的缓存空间的个数和大小,平台不同,默认:32 4k或者16 8k;
gzip_buffers number size;
#指明仅对哪些类型的资源执行压缩操作;默认为gzip_types text/html,不用显示指定,否则出错
gzip_types mime-type ...;
#如果启用压缩,是否在响应报文首部插入“Vary: Accept-Encoding”,一般建议打开
gzip_vary on | off;
#预压缩,即直接从磁盘找到对应文件的gz后缀的式的压缩文件返回给用户,无需消耗服务器CPU
#注意: 来自于ngx_http_gzip_static_module模块
gzip_static on | off;

实战:

修改我们的主配置文件,将压缩功能打开

具体的参数可以根据上面的配置指令一一对照。

[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@nginx ~]# nginx -s reload

 测试:

做一个大文件,一个小文件用以测试

[root@nginx ~]# echo hello world > /data/web/html/small.html

[root@nginx ~]# du -sh /usr/local/nginx/logs/access.log
60K     /usr/local/nginx/logs/access.log
[root@nginx ~]# cat /usr/local/nginx/logs/access.log  > /data/web/html/big.html


通过测试,发现小于1k的文件没有被压缩,大于1k的文件被压缩了 

Nginx 变量使用

  • nginx的变量可以在配置文件中引用,作为功能判断或者日志等场景使用
  • 变量可以分为内置变量和自定义变量
  • 内置变量是由nginx模块自带,通过变量可以获取到众多的与客户端访问相关的值。
 内置变量
官方文档
http://nginx.org/en/docs/varindex.html
常用内置变量
$remote_addr;
#存放了客户端的地址,注意是客户端的公网IP
$args;
#变量中存放了URL中的所有参数
#例如:https://search.jd.com/Search?keyword=手机&enc=utf-8
#返回结果为: keyword=手机&enc=utf-8
$is_args
#如果有参数为? 否则为空
$document_root;
#保存了针对当前资源的请求的系统根目录,例如:/webdata/nginx/timinglee.org/lee。
$document_uri;
#保存了当前请求中不包含参数的URI,注意是不包含请求的指令
#比如:http://lee.timinglee.org/var?\id=11111会被定义为/var
#返回结果为:/var
$host;
#存放了请求的host名称
limit_rate 10240;
echo $limit_rate;
#如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0
$remote_port;
#客户端请求Nginx服务器时随机打开的端口,这是每个客户端自己的端口
$remote_user;
#已经经过Auth Basic Module验证的用户名
$request_body_file;
#做反向代理时发给后端服务器的本地资源的名称
$request_method;
#请求资源的方式,GET/PUT/DELETE等
$request_filename;
#当前请求的资源文件的磁盘路径,由root或alias指令与URI请求生成的文件绝对路径,
#如:webdata/nginx/timinglee.org/lee/var/index.html
$request_uri;
#包含请求参数的原始URI,不包含主机名,相当于:$document_uri?$args,
#例如:/main/index.do?id=20190221&partner=search
$scheme;
#请求的协议,例如:http,https,ftp等
$server_protocol;
#保存了客户端请求资源使用的协议的版本,例如:HTTP/1.0,HTTP/1.1,HTTP/2.0等
$server_addr;
#保存了服务器的IP地址
$server_name;
#虚拟主机的主机名
$server_port;
#虚拟主机的端口号
$http_user_agent;
#客户端浏览器的详细信息
$http_cookie;
#客户端的所有cookie信息
$cookie_<name>
#name为任意请求报文首部字部cookie的key名
$http_<name>
#name为任意请求报文首部字段,表示记录请求报文的首部字段,ame的对应的首部字段名需要为小写,如果有
横线需要替换为下划线
#示例:
echo $http_user_agent;
echo $http_host;
$sent_http_<name>
#name为响应报文的首部字段,name的对应的首部字段名需要为小写,如果有横线需要替换为下划线,此变量有
问题
echo $sent_http_server;
$arg_<name>
#此变量存放了URL中的指定参数,name为请求url中指定的参数
echo $arg_id;

我们通过修改我们的子配置文件来更加清晰的看到内置变量的用法

[root@nginx conf.d]# cat vars.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /var {
       default_type text/html;  #设置文件类型为text
       echo "haha.org";
   }
}

注:默认情况下我们的nginx中是不支持使用echo的,使用我们需要加一个可以使用echo的模块

并且做在本机上做一下映射

[root@nginx conf.d]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.150  www.haha.org   var.haha.org

测试:

[root@nginx conf.d]# curl var.haha.org/var
haha.org

现在我们将echo的内容换成内置变量

[root@nginx conf.d]# cat vars.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /var {
       default_type text/html;  #设置文件类型为text
       echo $remote_addr;  # 客户端的ip
       echo $args;         # url中所有的参数,返回?后面的内容
       echo $is_args;      #根据上一条内容,有参数返回?,没有就为空
       echo $document_root; # 当前资源来源的根目录
       echo $document_uri;  #返回不含参数的uri  location 后的目录
       echo $host;          # 请求的host名称
       echo $remote_port;   # 客户端访问nginx服务器的端口,就是客户端的nginx的进程号
       echo $remote_user;    # 访问这个地址所认证的用户名
       echo $request_method;  # 请求资源的方式 /GET/PUT/DELETE
       echo $http_user_agent;  # 使用的具体是啥浏览器
       echo $request_filename; #访问网站对应的后端文件
       echo $request_uri       # 请求参数的原始uri,不含主机名
       echo $scheme;           # 请求的协议
       echo $server_protocol;  # 客户端请求资源使用的协议版本
       echo $server_addr;      # 服务器的ip
       echo $server_name;      # 虚拟主机名
       echo $server_port;      # 虚拟主机的端口号
       echo $http_cookie;
       echo $cookie_key2;      # 客户端cookie key2的值
   }
}

测试:

[root@nginx conf.d]# curl -b "key1=aa;key2=bb" -u admin:admin var.haha.org/var/?name=admin
192.168.10.150
name=admin
?
/data/web/html
/var/
var.haha.org
59948
admin
GET
curl/7.76.1
/data/web/html/var/
/var/?name=admin
http
HTTP/1.1
192.168.10.150
var.haha.org
80
key1=aa;key2=bb
bb

注:-b 是指定客户端cookie的值,-u 是网站认证的账号和密码,/var/后面的是uri的参数

自定义变量

以上都是nginx中的内置变量,当然我们也可以自定义变量,假如需要自定义变量名称和值,使用指令set $variable value;

 我们可以使用set命令进行设定,然后echo,

[root@nginx conf.d]# cat var1.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /var {
       default_type text/html;
       set $haha  hello;   #变量可以随便起名字
       echo $haha;
   }
}
[root@nginx conf.d]# curl var.haha.org/var/
hello

Nginx Rewrite 相关功能

  • Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求
  • 此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE
  • rewritenginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能
  • 比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问
  • 另外还可以在一定程度上提高网站的安全性。

 ngx_http_rewrite_module 模块指令

if 指令
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在serverlocation块中进行配置,Nginxif语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
if (条件匹配) {
action
}

 使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false,变量与表达式之间使用以下符号链接:

= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
#注意:
#如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
#nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false
[root@nginx conf.d]# vim vars.conf

server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /test {
   if ( !-e $request_filename ){
        echo "$request_filename is exist";
    }
   }
}

注: 当我访问这个网站时,网站内容来源于/data/web/html/test/index.html这个文件中, 如果这个文件不存在,就返回 is exist;

测试;没有这个文件时

[root@nginx conf.d]# curl var.haha.org/test/index.html
/data/web/html/test is exist

 有这个文件时

[root@nginx conf.d]# mkdir /data/web/html/test/
[root@nginx conf.d]# echo ni hao > /data/web
web/  web1/
[root@nginx conf.d]# echo ni hao > /data/web/html/test/index.html
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl var.haha.org/test/index.html
ni hao
set指令
指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
另外set定义格式为set $key valuevalue可以是text, variables和两者的组合。
[root@nginx conf.d]# cat var1.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /var {
       default_type text/html;
       set $haha  hello;   #变量可以随便起名字
       echo $haha;
   }
}
[root@nginx conf.d]# curl var.haha.org/var/
hello
break 指令
  • 用于中断当前相同作用域(location)中的其他Nginx配置
  • 与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效
  • 位于后面的 ngx_http_rewrite_module 模块中指令就不再执行
  • Nginx服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置
  • 该指令可以在server块和locationif块中使用
注意: 如果break指令在location块中后续指令还会继续执行,只是不执ngx_http_rewrite_module
模块的指令,其它指令还会执行。
正常情况下:
 listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /break {
        default_type text/html;
        set $name haha;
        echo $name;
        set $id 666;
        echo $id;
   }
}
[root@nginx conf.d]# curl var.haha.org/break
haha
666

当我们加入break指令后

server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /break {
        default_type text/html;
        set $name haha;
        echo $name;
        break;
        set $id 666;
        echo $id;
   }
[root@nginx conf.d]# curl var.haha.org/break
haha

读到break后,echo $port执行了,但是set没有执行,因为set是ngx_http_rewrite_module 模块的指令所以输出的内容有一个空行

return 指令
return 用于完成对请求的处理,并直接向客户端返回响应状态码,比如 : 可以指定重定向 URL( 对于特殊重定向状态码,301/302 ) 或者是指定提示文本内容 ( 对于特殊状态码 403/500 ) ,处于此指令后的所有配置都将不被执行,return 可以在 server if location 块进行配置

语法格式:

return code;                  #返回给客户端指定的HTTP状态码
return code [text];           #返回给客户端的状态码及响应报文的实体内容
                              #可以调用变量,其中text如果有空格,需要用单或双引号
return code URL;              #返回给客户端的URL地址
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;

   location /return {
       default_type text/html;
       if ( !-e $request_filename){
          return 301 http://www.baidu.com;
        }
        echo "$request_filename is exist";
   }

 注:当我们访问/return时,如果文件不存在,就返回一个301并且重定向到百度去。如果存在就输出存在。

测试;

文件不存在的情况下

[root@nginx conf.d]# curl  -I var.haha.org/return
HTTP/1.1 301 Moved Permanently
Server: lf/1.0
Date: Sun, 18 Aug 2024 11:48:13 GMT
Content-Type: text/html
Content-Length: 163
Connection: keep-alive
Location: http://www.baidu.com

文件存在的情况下

[root@nginx conf.d]# mkdir /data/web/html/return
[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# curl  -I var.haha.org/return
HTTP/1.1 200 OK
Server: lf/1.0
Date: Sun, 18 Aug 2024 11:50:00 GMT
Content-Type: text/html
Connection: keep-alive
Vary: Accept-Encoding
rewrite 指令
通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
语法格式 :
rewrite regex replacement [flag];
  • rewrite将用户请求的URI基于regex所描述的模式进行检查,匹配到时将其替换为表达式指定的新的URI
  • 注意:如果在同一级配置块中存在多个rewrite规则,那么会自下而下逐个检查;被某条件规则替换完成后,会重新一轮的替换检查,隐含有循环机制,但不超过10;如果超过,提示500响应码,[flag]所表示的标志位用于控制此循环机制
  • 如果替换后的URL是以http://https://开头,则替换结果会直接以重定向返回给客户端, 即永久重定向301

 正则表达式格式

.         #匹配除换行符以外的任意字符
\w        #匹配字母或数字或下划线或汉字
\s        #匹配任意的空白符
\d        #匹配数字
\b        #匹配单词的开始或结束
^         #匹配字付串的开始
$         #匹配字符串的结束
*         #匹配重复零次或更多次
+         #匹配重复一次或更多次
?         #匹配重复零次或一次
(n)       #匹配重复n次
{n,}      #匹配重复n次或更多次
{n,m}     #匹配重复n到m次
*?        #匹配重复任意次,但尽可能少重复
+?        #匹配重复1次或更多次,但尽可能少重复
??        #匹配重复0次或1次,但尽可能少重复
{n,m}?    #匹配重复n到m次,但尽可能少重复
{n,}?     #匹配重复n次以上,但尽可能少重复
\W        #匹配任意不是字母,数字,下划线,汉字的字符
\S        #匹配任意不是空白符的字符
\D        #匹配任意非数字的字符
\B        #匹配不是单词开头或结束的位置
[^x]      #匹配除了x以外的任意字符
[^lee]    #匹配除了magedu 这几个字母以外的任意字符
rewrite flag 使用介绍
利用 nginx rewrite 的指令,可以实现 url 的重新跳转, rewrite 有四种不同的 flag ,分别是 redirect( 临时重定向302) permanent( 永久重定向 301) break last 。其中前两种是跳转型的 flag ,后两种是代理型
  • 跳转型指由客户端浏览器重新对新地址进行请求
  • 代理型是在WEB服务器内部实现跳转

 rewrite 格式

Syntax: rewrite regex replacement [flag]; #通过正则表达式处理用户请求并返回替换后的数据
包。
Default: —
Context: server, location, if

flag 说明

redirect;
#临时重定向,重写完成后以临时重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求;使用相对路径,或者http://或https://开头,状态码:302
permanent;
#重写完成后以永久重定向方式直接返回重写后生成的新URL给客户端
#由客户端重新发起请求,状态码:301
break;
#重写完成后,停止对当前URL在当前location中后续的其它重写操作
#而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用
#适用于一个URL一次重写
last;
#重写完成后,停止对当前URI在当前location中后续的其它重写操作,
#而后对新的URL启动新一轮重写检查,不建议在location中使用
#适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户
域名永久与临时重定向
域名的临时的调整,后期可能会变,之前的域名或者URL可能还用、或者跳转的目的域名和URL还会跳转,这种情况浏览器不会缓存跳转,临时重定向不会缓存域名解析记录(A记录),但是永久重定向会缓存。
将访问源域名 var .haha.org 的请求永久重定向到 www.haha.com
永久重定向301
域名永久型调整,即域名永远跳转至另外一个新的域名,之前的域名再也不使用,跳转记录可以缓存到客户端浏览器
永久重定向会缓存 DNS 解析记录 , 浏览器中有 from disk cache 信息 , 即使 nginx 服务器无法访问 , 浏览器也会利用缓存进行重定向
比如 : 京东早期的域名 www.360buy.com 由于与 360 公司类似,于是后期永久重定向到了 www.jd.com

正常情况下:

[root@nginx conf.d]# mkdir /data/web/var
[root@nginx conf.d]# vim vars.conf
[root@nginx conf.d]# mkdir /data/web/html/var
[root@nginx conf.d]# echo hello world > /data/web/html/var/
[root@nginx conf.d]# echo hello world > /data/web/html/var/index.html
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;


   location / {
        root /data/web/var;
        idnex index.html;

   }
}
[root@nginx conf.d]# curl var.haha.org
hello world

永久重定向

[root@nginx conf.d]# cat  vars.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;


   location / {
        root /data/web/var;
        index index.html;
        rewrite / http://www.haha.com  permanent;
#       rewrite / http://www.haha.com  redirect;

   }
}

 如同可知,var.haha.org,被永久重定向到www.haha.org

临时重定向302
域名临时重定向,告诉浏览器域名不是固定重定向到当前目标域名,后期可能随时会更改,因此浏览器不会缓存当前域名的解析记录,而浏览器会缓存永久重定向的DNS 解析记录,这也是临时重定向与永久重定向最大的本质区别。
即当 nginx 服务器无法访问时 , 浏览器不能利用缓存 , 而导致重定向失败
[root@nginx conf.d]# cat  vars.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;


   location / {
        root /data/web/var;
        index index.html;
#       rewrite / http://www.haha.com  permanent;
        rewrite / http://www.haha.com  redirect;

   }
}

测试:

[root@nginx conf.d]# curl -I var.haha.org
HTTP/1.1 302 Moved Temporarily
Server: lf/1.0
Date: Sun, 18 Aug 2024 12:38:26 GMT
Content-Type: text/html
Content-Length: 139
Connection: keep-alive
Location: http://www.haha.com

 break last

break;
重写完成后,停止对当前URL在当前location中后续的其它重写操作而后直接跳转至重写规则配置块之后的其它配置,结束循环,建议在location中使用,适用于一个URL一次重写
last;
重写完成后,停止对当前URI在当前location中后续的其它重写操作,而后对新的URL启动新一轮重写检查,不建议在location中使用,适用于一个URL多次重写,要注意避免出现超过十次以及URL重写后返回错误的给用户

[root@nginx conf.d]# mkdir /data/web/html/{a1,a2,break,last}
[root@nginx conf.d]# echo 11111 > /data/web/html/a1/index.html
[root@nginx conf.d]# echo 22222 > /data/web/html/a2/index.html
[root@nginx conf.d]# echo break > /data/web/html/break/index.html
[root@nginx conf.d]# echo last > /data/web/html/last/index.html

[root@nginx conf.d]# cat vars.conf
server {
   listen 80;
   server_name var.haha.org;
   root  /data/web/html;
   index  index.html;


   location /break {
        rewrite ^/break/(.*) /a1/$1;
        rewrite ^/a1/(.*) /a2/$1;

   }
    location /last {
        rewrite ^/last/(.*) /a1/$1;
        rewrite ^/a1/(.*) /a2/$1;

   }
     location /a1 {
        default_type text/html;
        echo "hahahahahahahahahahahaha";

   }
     location /a2 {
        root  /data/web/html;

   }

}

注:根据上面的描述,此时访问/break,实际访问的就是a2,访问last,实际访问的也是a2

[root@nginx conf.d]# curl var.haha.org/break/
22222
[root@nginx conf.d]# curl var.haha.org/last/
22222

此时我们使用break,

此时我们在访问/break,返回的结果应该是/data/web/html/a1文件中的的内容

[root@nginx conf.d]# curl var.haha.org/break/index.html
11111

 我们使用last

 此时我们访问last,他访问的应该是我们在模块中写的echo输出的a1的内容

[root@nginx conf.d]# curl var.haha.org/last/index.html
hahahahahahahahahahahaha

总结:当我们遇到break,break以下的将停止进行,而他访问的则是当前break 中止的部分加我们location的部分的文件,当遇到last,我们当前的location也会中止,但是他仍会跳出我们location,继续去寻找

自动跳转 https
基于通信安全考虑公司网站要求全站 https,因此要求将在不影响用户请求的情况下将http请求全
部自动跳转至 https,另外也可以实现部分 location 跳转
我们在nginx下建立一个认证目录,做一个认证文件
[root@nginx nginx]# mkdir  certs
[root@nginx nginx]# cd certs/
[root@nginx certs]# openssl req -newkey rsa:2048 -nodes -sha256 -keyout /usr/local/nginx/certs/haha.org.key -x509 -days 365 -out /usr/local/nginx/certs/haha.org.key.crt
....+......+.........+...........+...+...+..........+........+.......+.....+....+........+...+..........+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*.....+...+.....+...+..........+.....+.........+.+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+......+.+..+.......+......+.....+..........+..+...............+.+.....+.+...........+.............+......+.........+.....+.........+...+...+....+..+......+...+.......+..+.......+...+............+...+...+..+...+..................+.+.....+.+..+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+......+...+..+....+.....+............+...+......+.....................+....+........+......+....+..+.+........+......+.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----

[root@nginx certs]# ls
haha.org.key  haha.org.key.crt
server {
   listen 80;
   listen 443 ssl;
   server_name  var.haha.org;
   root  /data/web/html;
   index  index.html;
   ssl_certificate_key /usr/local/nginx/certs/haha.org.key;
   ssl_certificate /usr/local/nginx/certs/haha.org.crt;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;

}

修改子配置文件

测试:http

[root@nginx conf.d]# cat /data/web/html/index.html
haha
[root@nginx conf.d]# vim vars.conf
[root@nginx conf.d]# curl var.haha.org
haha

https

[root@nginx conf.d]# curl -k var.haha.org
haha

 使用rewrite指令临时重定向,跳转https

 listen 80;
   listen 443 ssl;
   server_name  var.haha.org;
   root  /data/web/html;
   index  index.html;
   ssl_certificate_key /usr/local/nginx/certs/haha.org.key;
   ssl_certificate /usr/local/nginx/certs/haha.org.crt;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;

   location / {
      if ( $scheme = http ){
       rewrite /(.*) https://$HOST/$1 redirect;
       }
   }

   location /login {
      if ( $scheme = http ){
       rewrite /login https://$HOST/login redirect;
       }
   }

 

Nginx 防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名正常的referer信息有以下几种
none:             #请求报文首部没有referer首部,
                   #比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:          #请求报文有referer首部,但无有效值,比如为空。
server_names:     #referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string: #自定义指定字符串,但可使用*作通配符。示例: *.timinglee.org
www.timinglee.*
regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头,例如:
~.*\.timinglee\.com
实现盗链
新建一个目录,随便找两张图片,把他们放在不通的目录中 ,防止死循环
[root@nginx ~]# cd /data/web/html/
[root@nginx html]# ll  /data/web/html/tp1.jpg
-rw-r--r--. 1 root root 45190  8月 18 23:22 /data/web/html/tp1.jpg
[root@nginx html]# ll /data/web/html/images/tp.jpg
-rw-r--r--. 1 root root 18887  8月 18 23:19 /data/web/html/images/tp.jpg
server {
   listen 80;
   listen 443 ssl;
   server_name  var.haha.org;
   root  /data/web/html;
   index  index.html;
   ssl_certificate_key /usr/local/nginx/certs/haha.org.key;
   ssl_certificate /usr/local/nginx/certs/haha.org.crt;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;

   location /images {


   }
}

访问:

现在我们在另一台上面使用apache部署web服务

[root@node1 ~]# cat /var/www/html/index.html
<html>

  <head>
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <title>盗链</title>
</head>

  <body>
    <img src="http://var.haha.org/images/tp.jpg" >
    <h1 style="color:red">欢迎大家</h1>
    <p><a href=http://var.haha.org>狂点老李</a>出门见喜</p>
  </body>

</html>

在访问node1的时候可以跳转到我们的nginx部署的web网页上

 点机跳转到我们nginxwe网页上,使所有的nginx web流量全部到了我们node1网站

实现防盗链
基于访问安全考虑,nginx支持通过ngx_http_referer_module模块,检查访问请求的referer信息是否有效实现防盗链功能
定义防盗链:
server {
   listen 80;
   listen 443 ssl;
   server_name  var.haha.org;
   root  /data/web/html;
   index  index.html;
   ssl_certificate_key /usr/local/nginx/certs/haha.org.key;
   ssl_certificate /usr/local/nginx/certs/haha.org.crt;
   ssl_session_cache    shared:SSL:1m;
   ssl_session_timeout  5m;

   location /images {
      valid_referers none blocked server_name *.haha.org ~\.baidu/.;
      if ( $invalid_referer ){
              return 404;

       }
   
    }      
}

测试:

此时图片已经没了,但是点击仍能进入访问,因为我们没有禁止全站,我们只指定了访问/imags

修改为全站,再次访问

 此时便无法跳转

Nginx 反向代理功能

反向代理:reverse proxy,指的是代理外网用户的请求到内部的指定的服务器,并将数据返回给用户的一种方式,这是用的比较多的一种方式。
Nginx 除了可以在企业提供高性能的 web 服务之外,另外还可以将 nginx 本身不具备的请求通过某种预定义的协议转发至其它服务器处理,不同的协议就是Nginx 服务器与其他服务器进行通信的一种规范,主要在不同的场景使用以下模块实现不同的功能
ngx_http_proxy_module:     #将客户端的请求以http协议转发至指定服务器进行处理
ngx_http_upstream_module   #用于定义为proxy_pass,fastcgi_pass,uwsgi_pass
                           #等指令引用的后端服务器分组
ngx_stream_proxy_module:   #将客户端的请求以tcp协议转发至指定服务器处理
ngx_http_fastcgi_module:   #将客户端对php的请求以fastcgi协议转发至指定服务器助理
ngx_http_uwsgi_module:     #将客户端对Python的请求以uwsgi协议转发至指定服务器处理
逻辑调用关系:

访问逻辑图

同构代理:用户不需要其他程序的参与,直接通过 http 协议或者 tcp 协议访问后端服务器
异构代理:用户访问的资源时需要经过处理后才能返回的,比如 php python ,等等,这种访问资源需要经过处理才能被访问

 实现 http 反向代理
官方文档: https://nginx.org/en/docs/http/ngx_http_proxy_module.html
http 协议反向代理
反向代理配置参数
proxy_pass;         #用来设置将客户端请求转发给的后端服务器的主机
                    #可以是主机名(将转发至后端服务做为主机头首部)、IP地址:端口的方式
                    #也可以代理到预先设置的主机群组,需要模块ngx_http_upstream_module支持
#示例:
location /web {
index index.html;
proxy_pass http://172.25.254.30:8080;                 #8080后面无uri,即无 / 符号,
                                     #需要将location后面url 附加到proxy_pass指定的url后面
                                                      #此行为类似于root
                                                #proxy_pass指定的uri不带斜线将访问的/web
                                                #等于访问后端服务器
proxy_pass http://172.25.254.40:8080/;     #8080后面有uri,即有 / 符号
                                     #相当于置换,即访问/web时实际返回proxy_pass后面uri内容
                                            #此行为类似于alias
                                            #proxy_pass指定的uri带斜线
                                            #等于访问后端服务器的
                                            #http://172.25.254.40:8080/index.html
                                            #内容返回给客户端
}                                           # http://nginx/web/index.html ==>
http://1:8080
#重启Nginx测试访问效果:
#curl -L http://www.timinglee.org/web



#如果location定义其uri时使用了正则表达式模式(包括~,~*,但不包括^~),则proxy_pass之后必须不能
使用uri
#即不能有/ ,用户请求时传递的uri将直接附加至后端服务器之后
server {
...
server_name HOSTNAME;
location ~|~* /uri/ {
proxy_pass http://host:port;                 #proxy_pass后面的url 不能加/
}
...
}
http://HOSTNAME/uri/ --> http://host/uri/
proxy_hide_header field;                     #用于nginx作为反向代理的时候
                                             #在返回给客户端http响应时
                                             #隐藏后端服务器相应头部的信息
                                             #可以设置在http,server或location块
#示例: 隐藏后端服务器ETag首部字段
location /web {
index index.html;
proxy_pass http://10.0.0.18:8080/;
proxy_hide_header ETag;
}
proxy_pass_header field;                     #透传
#默认nginx在响应报文中不传递后端服务器的首部字段Date, Server, X-Pad, X-Accel等参数
#如果要传递的话则要使用 proxy_pass_header field声明将后端服务器返回的值传递给客户端
#field 首部字段大小不敏感

#示例:透传后端服务器的Server和Date首部给客户端,同时不再响应报中显示前端服务器的Server字段
proxy_pass_header Server;
proxy_pass_header Date;
proxy_pass_request_body on | off;
#是否向后端服务器发送HTTP实体部分,可以设置在http,server或location块,默认即为开启
proxy_pass_request_headers on | off;
#是否将客户端的请求头部转发给后端服务器,可以设置在http,server或location块,默认即为开启
proxy_set_header;
#可更改或添加客户端的请求头部信息内容并转发至后端服务器,比如在后端服务器想要获取客户端的真实IP的时候,就要更改每一个报文的头部

#示例:
location ~ /web {
proxy_pass http://172.25.254.20:80;
proxy_hide_header ETag;
proxy_pass_header Server;
proxy_pass_request_body on;
proxy_pass_request_headers on;
proxy_set_header X-Forwarded-For $remote_addr;
}
[root@apache20 ~]# vim /etc/httpd/conf/httpd.conf
LogFormat "\"%{X-Forwarded-For}i\" %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%
{User-Agent}i\"" combined
访问后看后端服务器日志

proxy_connect_timeout time;
#配置nginx服务器与后端服务器尝试建立连接的超时时间,默认为60秒
用法如下:proxy_connect_timeout 6s;
#60s为自定义nginx与后端服务器建立连接的超时时间,超时会返回客户端504响应码

proxy_read_timeout time;
#配置nginx服务器向后端服务器或服务器组发起read请求后,等待的超时时间,默认60s


proxy_send_timeout time;
#配置nginx项后端服务器或服务器组发起write请求后,等待的超时 时间,默认60s

proxy_http_version 1.0;
#用于设置nginx提供代理服务的HTTP协议的版本,默认http 1.0


proxy_ignore_client_abort off;
#当客户端网络中断请求时,nginx服务器中断其对后端服务器的请求。即如果此项设置为on开启,则服务器、会忽略客户端中断并一直等着代理服务执行返回,如果设置为off,则客户端中断后Nginx也会中断客户端请求并立即记录499日志,默认为off。


反向代理单台web 服务器
 设备角色IP
nginxnginx反向代理192.168.10.150
node1real server1192.168.10.200
node2real server2192.168.10.210
两台real server 安装apache,实现web服务
[root@node1 ~]# echo node1 - 192.168.10.200 > /var/www/html/index.html
[root@node1 ~]# systemctl restart httpd.service
[root@node1 ~]# curl 192.168.10.200
node1 - 192.168.10.200
[root@node2 ~]# echo node2 - 192.168.10.210 > /var/www/html/index.html
[root@node2 ~]# systemctl restart httpd.service
[root@node2 ~]# curl 192.168.10.210
node2 - 192.168.10.210

在nginx服务器上构建反向代理


[root@nginx ~]# vim /usr/local/nginx/conf.d/vars.conf

server {
   listen 80;
   server_name  var.haha.org;

   location /  {
        proxy_pass http://192.168.10.200:80;

   }
}

测试:客户端访问nginx代理服务器

指定 location 实现反向代理

在node2上新建一个目录

[root@node2 ~]# mkdir /var//www/html/static
[root@node2 ~]# echo node2 - 192.168.10.210 > /var//www/html/static/index.html
vim /usr/local/nginx/conf.d/vars.conf
server {
   listen 80;
   server_name  var.haha.org;

   location /  {
        proxy_pass http://192.168.10.200:80;

   }

   location /static {
        proxy_pass http://192.168.10.210:80;

   }

测试:

指定 location 实现动静分离反向代理

在node上安装php,实现动态资源,node1依然使用html,实现静态资源

[root@node1 ~]# cat /var/www/html/index.php
<?php
  phpinfo();
?>
[root@node1 ~]# systemctl restart httpd.service
[root@nginx ~]# vim /usr/local/nginx/conf.d/vars.conf

server {
   listen 80;
   server_name  var.haha.org;

   location ~ \.php$  {
        proxy_pass http://192.168.10.200:80;

   }

   location /static{
        proxy_pass http://192.168.10.210:80;

   }

访问nginx服务器测试

 反向代理:缓存功能
缓存功能默认关闭状态,需要先动配置才能启用
proxy_cache zone_name | off; 默认off
#指明调用的缓存,或关闭缓存机制;Context:http, server, location
#zone_name 表示缓存的名称.需要由proxy_cache_path事先定义
proxy_cache_key string;
#缓存中用于“键”的内容,默认值:proxy_cache_key $scheme$proxy_host$request_uri;
proxy_cache_valid [code ...] time;
#定义对特定响应码的响应内容的缓存时长,定义在http{...}中
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_path;
#定义可用于proxy功能的缓存;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=zone_name:size [inactive=time] [max_size=size] [manager_files=number]
[manager_sleep=time] [manager_threshold=time] [loader_files=number]
[loader_sleep=time] [loader_threshold=time] [purger=on|off]
[purger_files=number] [purger_sleep=time] [purger_threshold=time];
#示例:在http配置定义缓存信息
proxy_cache_path /var/cache/nginx/proxy_cache #定义缓存保存路径,proxy_cache会自动创建
levels=1:2:2 #定义缓存目录结构层次
#1:2:2可以生成
2^4x2^8x2^8=2^20=1048576个目录
keys_zone=proxycache:20m #指内存中缓存的大小,主要用于存放key和metadata
(如:使用次数)
#一般1M可存放8000个左右的key
inactive=120s #缓存有效时间
max_size=10g; #最大磁盘占用空间,磁盘存入文件内容的缓存空间最大值
#调用缓存功能,需要定义在相应的配置段,如server{...};或者location等
proxy_cache proxycache;
proxy_cache_key $request_uri; #对指定的数据进行MD5的运算做为缓存的key
proxy_cache_valid 200 302 301 10m; #指定的状态码返回的数据缓存多长时间
proxy_cache_valid any 1m; #除指定的状态码返回的数据以外的缓存多长时间,必须设置,
否则不会缓存
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 |
http_502 | http_503 | http_504 | http_403 | http_404 | off ; #默认是off
#在被代理的后端服务器出现哪种情况下,可直接使用过期的缓存响应客户端
#示例
proxy_cache_use_stale error http_502 http_503;
proxy_cache_methods GET | HEAD | POST ...;
#对哪些客户端请求方法对应的响应进行缓存,GET和HEAD方法总是被缓存
非缓存场景压测
[root@nginx ~]# ab -n1000 -c100 http://var.haha.org/static/index.html

 准备缓存配置

在主配置文件内添加参数

 在子配置文件loaction中添加

[root@nginx ~]# vim /usr/local/nginx/conf.d/vars.conf

server {
   listen 80;
   server_name  var.haha.org;

   location  ~ \.php$  {
        proxy_pass http://192.168.10.200:80;

   }

   location /static{
        proxy_pass http://192.168.10.210:80;  
        proxy_cache proxycache;       # 缓存的名称 和主配置文件名称相同,自己设定
        proxy_cache_key  $request_uri;  
        proxy_cache_valid 200 302 301 10m;  #什么样的返回值才缓存,缓存多久
        proxy_cache_valid any 1m;    #缓存其他的响应时间

   }

配置完成后,刷新配置,缓存目录会自动生成

[root@nginx ~]# ll -d /usr/local/nginx/proxy_cache/ -d
drwx------. 2 nginx root 6  8月 20 11:46 /usr/local/nginx/proxy_cache/
[root@nginx ~]# cd /usr/local/nginx/proxy_cache/
[root@nginx proxy_cache]# ll
总用量 0
访问并验证缓存文件
[root@nginx proxy_cache]# ab -n1000 -c100 http://var.haha.org/static/index.html

[root@nginx proxy_cache]# tree
.
└── e
    └── 50
        └── 99

3 directories, 0 files

访问var.haha.org/static 后 nginx服务器将缓存保存在你添加的目录下面,

 http 反向代理负载均衡
在上一个节中Nginx可以将客户端的请求转发至单台后端服务器但是无法转发至特定的一组的服务器,而且不能对后端服务器提供相应的服务器状态监测,Nginx 可以ngx_http_upstream_module模块提供服务器分组转发、权重分配、状态监测、调度算法等高级功能
官方文档: https://nginx.org/en/docs/http/ngx_http_upstream_module.html
http upstream配置参数
#自定义一组服务器,配置在http块内
upstream name {
server .....
......
}
#示例
upstream backend {
server backend1.example.com weight=5;
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
server backup1.example.com backup;
}
server address [parameters];
#配置一个后端web服务器,配置在upstream内,至少要有一个server服务器配置。
#server支持的parameters如下:
weight=number #设置权重,默认为1,实现类似于LVS中的WRR,WLC等
max_conns=number #给当前后端server设置最大活动链接数,默认为0表示没有限制
max_fails=number #后端服务器的下线条件,当客户端访问时,对本次调度选中的后端服务器连续进行检
测多少次,如果都失败就标记为不可用,默认为1次,当客户端访问时,才会利用TCP触发对探测后端服务器健康性
检查,而非周期性的探测
fail_timeout=time #后端服务器的上线条件,对已经检测到处于不可用的后端服务器,每隔此时间间隔再
次进行检测是否恢复可用,如果发现可用,则将后端服务器参与调度,默认为10秒
backup #设置为备份服务器,当所有后端服务器不可用时,才会启用此备用服务器
down #标记为down状态,可以平滑下线后端服务器
resolve #当server定义的是主机名的时候,当A记录发生变化会自动应用新IP而不用重启
Nginx
hash KEY [consistent];
#基于指定请求报文中首部字段或者URI等key做hash计算,使用consistent参数,将使用ketama一致性
hash算法,适用于后端是Cache服务器(如varnish)时使用,consistent定义使用一致性hash运算,一致
性hash基于取模运算
hash $request_uri consistent; #基于用户请求的uri做hash
hash $cookie_sessionid #基于cookie中的sessionid这个key进行hash调度,实现会话绑
定
ip_hash;
#源地址hash调度方法,基于的客户端的remote_addr(源地址IPv4的前24位或整个IPv6地址)做hash计
算,以实现会话保持
least_conn;
#最少连接调度算法,优先将客户端请求调度到当前连接最少的后端服务器,相当于LVS中的WLC
反向代理后端多台 web服务器

编写nginx子配置文件

upstream webcluster {      # 名字可以随意起
    server 192.168.10.200:80 fail_timeout=15s max_fails=3;
    server 192.168.10.210:80 fail_timeout=15s max_fails=3;
    server 192.168.10.150:80 backup;
}
server {
   listen 80;
   server_name  var.haha.org;

   location / {
        proxy_pass http://webcluster;
   }


}

访问测试

不加算法的话,默认是轮询

 基于uri进行hash

hash $request_uri consistent;
upstream webcluster {
    hash $request_uri consistent;
    server 192.168.10.200:8080 fail_timeout=15s max_fails=3;
    server 192.168.10.210:80 fail_timeout=15s max_fails=3;
#   server 192.168.10.150:80 backup;
}
server {
   listen 80;
   server_name  var.haha.org;

   location / {
        proxy_pass http://webcluster;
   }


}
[root@node1 ~]# mkdir /var/www/html/static
[root@node1 ~]# echo static > /var/www/html/static/index.html

访问测试:

实现 Nginx 四层负载均衡  
Nginx1.9.0版本开始支持tcp模式的负载均衡,在1.9.13版本开始支持udp协议的负载,udp主要用于DNS的域名解析,其配置方式和指令和http 代理类似,其基于ngx_stream_proxy_module模块实现tcp负载,另外基于模块ngx_stream_upstream_module实现后端服务器分组转发、权重分配、状态监测、调度算法等高级功能。
如果编译安装,需要指定 --with-stream 选项才能支持ngx_stream_proxy_module模块
官方文档:
https://nginx.org/en/docs/stream/ngx_stream_proxy_module.html
tcp负载均衡配置参数
stream { #定义stream相关的服务;
Context:main
upstream backend { #定义后端服务器
hash $remote_addr consistent; #定义调度算法
server backend1.example.com:12345 weight=5; #定义具体server
server 127.0.0.1:12345 max_fails=3 fail_timeout=30s;
server unix:/tmp/backend3;
}
upstream dns { #定义后端服务器
server 10.0.0.1:53; #定义具体server
server dns.example.com:53;
}
server { #定义server
listen 12345; #监听IP:PORT
proxy_connect_timeout 1s; #连接超时时间
proxy_timeout 3s; #转发超时时间
proxy_pass backend; #转发到具体服务器组
}
server {
listen 127.0.0.1:53 udp reuseport;
proxy_timeout 20s;
proxy_pass dns;
}
server {
listen [::1]:12345;
proxy_pass unix:/tmp/stream.socket;
}
}
负载均衡实例: MySQL

两台real server安装mysql

[root@node1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf

[root@node1 ~]# mysql -e "grant all on *.* to haha@'%' identified by 'haha';"
[root@node1 ~]# mysql -uhaha -p123 -h192.168.10.200 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|          20 |
+-------------+
[root@node2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf

 

[root@node2 ~]# systemctl start mariadb.service
[root@node2 ~]# mysql -e "grant all on *.* to haha@'%' identified by 'haha';"
# 启动服务
# 设置mysql可远程登陆的账户和密码
[root@node2 ~]# mysql -uhaha -p123 -h192.168.10.210 -e "select @@server_id"
+-------------+
| @@server_id |
+-------------+
|          10 |
+-------------+
#查看server_id

 配置nginx服务器

[root@nginx ~]# vim /usr/local/nginx/conf.d/vars.conf

stream  {
  upstream mysql_server {
    server 192.168.10.200:3306 fail_timeout=15s max_fails=3;
    server 192.168.10.210:3306 fail_timeout=15s max_fails=3;
   }

   server {
     listen 192.168.10.150:3306;
     proxy_pass mysql_server;
     proxy_connect_timeout 30s;
     proxy_timeout 300s;
   }


}
s

注意,我们需要新建一个子配置文件独立在http模块之外,因为此时我们用到的是tcp,是四层,使所以独立在http之外

[root@nginx ~]# mkdir  /usr/local/nginx/tcpconf.d
[root@nginx ~]# mv /usr/local/nginx/conf.d/vars.conf /usr/local/nginx/tcpconf.d/

创建这个目录,并把之前写好的文件移动到当前目录下

测试:不添加算法,默认是轮询

实现 FastCGI

CGI的由来:
最早的 Web 服务器只能简单地响应浏览器发来的 HTTP 请求,并将存储在服务器上的 HTML 文件返回给浏览器,也就是静态html 文件,但是后期随着网站功能增多网站开发也越来越复杂,以至于出现动态技术,比如像php(1995 ) java(1995) python(1991) 语言开发的网站,但是 nginx/apache 服务器并不能直接运行 php java 这样的文件, apache 实现的方式是打补丁,但是 nginx 缺通过与第三方基于协议实现,即通过某种特定协议将客户端请求转发给第三方服务处理,第三方服务器会新建新的进程处理用户的请求,处理完成后返回数据给Nginx 并回收进程,最后 nginx 在返回给客户端,那这个约定就是通用网关接口(common gateway interface ,简称 CGI) CGI (协议) 是 web 服务器和外部应用程序之间的接口标准,是cgi 程序和 web 服务器之间传递信息的标准化接口。

 

为什么会有FastCGI
CGI 协议虽然解决了语言解析器和 Web Server 之间通讯的问题,但是它的效率很低,因为 Web Server每收到一个请求都会创建一个CGI 进程, PHP 解析器都会解析 php.ini 文件,初始化环境,请求结束的时候再关闭进程,对于每一个创建的CGI 进程都会执行这些操作,所以效率很低,而 FastCGI 是用来提高 CGI 性能的,FastCGI 每次处理完请求之后不会关闭掉进程,而是保留这个进程,使这个进程可以处理多个请求。这样的话每个请求都不用再重新创建一个进程了,大大提升了处理效率。
什么是PHP-FPM
PHP-FPM(FastCGI Process Manager
  • FastCGI进程管理器)是一个实现了Fastcgi的程序,并且提供进程管理的功能。

进程包括master进程和worker进程。master进程只有一个,负责监听端口,接受来自web server 的请求

  • worker进程一般会有多个,每个进程中会嵌入一个PHP解析器,进行PHP代码的处理。
 FastCGI配置指令
Nginx基于模块ngx_http_fastcgi_module实现通过fastcgi协议将指定的客户端请求转发至php-fpm处理,其配置指令如下
fastcgi_pass address:port;
#转发请求到后端服务器,address为后端的fastcgi server的地址,可用位置:location, if in
location
fastcgi_index name;
#fastcgi默认的主页资源,示例:fastcgi_index index.php;
fastcgi_param parameter value [if_not_empty];
#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义
key
fastcgi_param REMOTE_ADDR $remote_addr; #客户端源IP
fastcgi_param REMOTE_PORT $remote_port; #客户端源端口
fastcgi_param SERVER_ADDR $server_addr; #请求的服务器IP地址
fastcgi_param SERVER_PORT $server_port; #请求的服务器端口
fastcgi_param SERVER_NAME $server_name; #请求的server name
Nginx默认配置示例:
location ~ \.php$ {
root /scripts;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; #默认脚本路径
#fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params; #此文件默认系统已提供,存放的相对路径为
prefix/conf
}
FastCGI实战案例
Nginxphp-fpm在同一服务器
编译安装更方便自定义参数或选项,所以推荐大家使用源码编译
官方网站: www.php.net
源码编译 php
#利用yum解决php依赖
[root@Nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel
libpng-devel libcurl-devel oniguruma-devel
#解压源码并安装
[root@Nginx ~]# ./configure \
--prefix=/usr/local/php \ #安装路径
--with-config-file-path=/usr/local/php/etc \ #指定配置路径
--enable-fpm \ #用cgi方式启动程序
--with-fpm-user=nginx \ #指定运行用户身份
--with-fpm-group=nginx \
--with-curl \ #打开curl浏览器支持
--with-iconv \ #启用iconv函数,转换字符编码
--with-mhash \ #mhash加密方式扩展库
--with-zlib \ #支持zlib库,用于压缩http压缩传输
--with-openssl \ #支持ssl加密
--enable-mysqlnd \ #mysql数据库
--with-mysqli \
--with-pdo-mysql \
--disable-debug \ #关闭debug功能
--enable-sockets \ #支持套接字访问
--enable-soap \ #支持soap扩展协议
--enable-xml \ #支持xml
--enable-ftp \ #支持ftp
--enable-gd \ #支持gd库
--enable-exif \ #支持图片元数据
--enable-mbstring \ #支持多字节字符串
--enable-bcmath \ #打开图片大小调整,用到zabbix监控的时候用到了这个模块
--with-fpm-systemd #支持systemctl 管理cg
解压缩php的安装包
[root@nginx ~]# tar xvf php-8.3.9.tar.gz
解压源码并安装
[root@nginx php-8.3.9]# ./configure \
> --prefix=/usr/local/php \
> --with-config-file-path=/usr/local/php/etc \
> --enable-fpm \
> --with-fpm-user=nginx \
> --with-fpm-group=nginx \
> --with-curl \
> --with-iconv \
> --with-mhash \
> --with-zlib \
> --with-openssl \
> --enable-mysqlnd \
> --with-mysqli \
> --with-pdo-mysql \
> --disable-debug \
> --enable-sockets \
> --enable-soap \
> --enable-xml \
> --enable-ftp \
> --enable-gd \
> --enable-exif \
> --enable-mbstring \
> --enable-bcmath \
> --with-fpm-systemd
configure: error: Package requirements (libsystemd >= 209) were not met:

Package 'libsystemd', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables SYSTEMD_CFLAGS
and SYSTEMD_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

发现缺少依赖,使用dnf whatprovides查找

进行执行

configure: error: Package requirements (libxml-2.0 >= 2.9.0) were not met:

Package 'libxml-2.0', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables LIBXML_CFLAGS
and LIBXML_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

进行执行

configure: error: Package requirements (sqlite3 >= 3.7.7) were not met:

Package 'sqlite3', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables SQLITE_CFLAGS
and SQLITE_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

进行检测

configure: error: Package requirements (libcurl >= 7.29.0) were not met:

Package 'libcurl', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables CURL_CFLAGS
and CURL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

 进行检测

configure: error: Package requirements (libpng) were not met:

Package 'libpng', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables PNG_CFLAGS
and PNG_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

根据上面的经验,应该是-devel的包

configure: error: Package requirements (oniguruma) were not met:

Package 'oniguruma', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables ONIG_CFLAGS
and ONIG_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

该依赖无法使用yum安装,所以我们在网上搜索这个软件,进行安装

[root@nginx php-8.3.9]# wget https://mirrors.aliyun.com/rockylinux/9.4/devel/x86_64/kickstart/Packages/o/oniguruma-devel-6.9.6-1.el9.5.x86_64.rpm


检测完成

开始编译 

 php相关配置优化
[root@Nginx ~]# cd /usr/local/php/etc
[root@Nginx etc]# cp php-fpm.conf.default php-fpm.conf
[root@Nginx etc]# vim php-fpm.conf
去掉注释
pid = run/php-fpm.pid #指定pid文件存放位置
[root@Nginx etc]# cd php-fpm.d/
[root@Nginx php-fpm.d]# cp www.conf.default www.conf
#生成主配置文件
[root@Nginx php-fpm.d]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai #修改时区

 去掉pid注释

[root@nginx php-fpm.d]# vim www.conf

监听所有端口

生成主配置文件
[root@Nginx php-fpm.d]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp php.ini-production /usr/local/php/etc/php.ini
[root@Nginx ~]# vim /usr/local/php/etc/php.ini
[Date]
; Defines the default timezone used by the date functions
; https://php.net/date.timezone
date.timezone = Asia/Shanghai #修改时区

生成启动文件 

[root@Nginx ~]# cd /root/php-8.3.9/
[root@Nginx php-8.3.9]# cp sapi/fpm/php-fpm.service /lib/systemd/system/
# Mounts the /usr, /boot, and /etc directories read-only for processes invoked by
this unit.
#ProtectSystem=full #注释该内容

注释此行 

启动成功

[root@nginx php-8.3.9]# systemctl daemon-reload
[root@nginx php-8.3.9]# systemctl start php-fpm.service

[root@nginx php-8.3.9]# netstat -antlupe | grep php-fpm
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      0          177244     134978/php-fpm: mas
准备 php 测试页面
[root@nginx ~]# mkdir  /data/php -p
[root@nginx ~]# vim /data/php/index.html
[root@nginx ~]# cat /data/php/index.html
<?php
phpinfo();
?>
Nginx 配置转发
Nginx 安装完成之后默认生成了与 fastcgi 的相关配置文件,一般保存在 nginx 的安装路径的 conf 目录当中,比如/apps/nginx/conf/fastcgi.conf /apps/nginx/conf/fastcgi_params
配置nginx子配置文件,将子配置文件添加至主配置文件
[root@nginx ~]# cat /usr/local/nginx/conf.d/vhosts.conf
server {
  listen 80;
  server_name var.haha.org;
  root /data/php;
  location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    include fastcgi.conf; 
  } 
}

php的动态扩展模块(php的缓存模块)

安装memcache模块

[root@Nginx ~]# tar zxf memcache-8.2.tgz
[root@Nginx ~]# cd memcache-8.2/
[root@Nginx memcache-8.2]# yum install autoconf
[root@Nginx memcache-8.2]# phpize
[root@Nginx memcache-8.2]# ./configure && make && make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-nonzts-20230831/
[root@Nginx memcache-8.2]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-
20230831/
memcache.so opcache.so

 复制测试文件到nginx发布目录中

[root@Nginx ~]# cd memcache-8.2/

[root@Nginx memcache-8.2]# cp example.php memcache.php /data/php/
[root@Nginx ~]# vim /data/php/memcache.php

 

更改账户密码 

配置 php 加载 memcache 模块
[root@Nginx ~]# vim /usr/local/php/etc/php.ini

 部署memcached

[root@Nginx ~]# yum install memcached -y
[root@Nginx ~]# systemctl enable --now memcached.service


[root@nginx memcache-8.2]# netstat -antlupe | grep memcache
tcp        0      0 127.0.0.1:11211         0.0.0.0:*               LISTEN      977        352981     274542/memcached
tcp6       0      0 ::1:11211               :::*                    LISTEN      977        352982     274542/memcached

[root@Nginx ~]# cat /etc/sysconfig/memcached
PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1,::1"

测试:

 php高速缓存

部署方法
在我们安装的nginx中默认不支持memcsrcache功能,需要借助第三方模块来让nginx支持此功能,所以nginx需要重新编译
[root@nginx nginx-1.26.1]# make clean
rm -rf Makefile objs
[root@nginx nginx-1.26.1]# rm -rf /usr/local/nginx/

 

压测:

  • 14
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值