企业高性能web服务器

一、Apache 经典的 Web 服务端

1.1 Apache prefork 模型

预派生模式,有一个主控制进程,然后生成多个子进程,使用select模型,最大并发1024

每个子进程有一个独立的线程响应用户请求

相对比较占用内存,但是比较稳定,可以设置最大和最小进程数

是最古老的一种模式,也是最稳定的模式,适用于访问量不是很大的场景

优点:稳定

缺点:每个用户请求需要对应开启一个进程,占用资源较多,并发性差,不适用于高并发场景

1.2 Apache worker 模型

一种多进程和多线程混合的模型

有一个控制进程,启动多个子进程

每个子进程里面包含固定的线程

使用线程程来处理请求

当线程不够使用的时候会再启动一个新的子进程,然后在进程里面再启动线程处理请求

由于其使用了线程处理请求,因此可以承受更高的并发

优点:相比prefork 占用的内存较少,可以同时处理更多的请求
缺点:使用keepalive的长连接方式,某个线程会一直被占据,即使没有传输数据,也需要一直等待到超 时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用(该问题在 prefork模式下,同样会发生)

1.3 Apache event模型

Apache中最新的模式,2012年发布的apache 2.4.X系列正式支持event 模型,属于事件驱动模型(epoll)

每个进程响应多个请求,在现在版本里的已经是稳定可用的模式
它和worker模式很像,最大的区别在于,它解决了keepalive场景下长期被占用的线程的资源浪费问题 (某些线程因为被keepalive,空挂在哪里等待,中间几乎没有请求过来,甚至等到超时)
event MPM中,会有一个专门的线程来管理这些keepalive类型的线程
当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样增强了高并发场 景下的请求处理能力

优点:单线程响应多请求,占据更少的内存,高并发下表现更优秀,会有一个专门的线程来管理keep-alive类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放
缺点:没有线程安全控制

二、Nginx 架构和安装

2.1 Nginx 功能介绍


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


2.2 Web 服务相关的功能


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


2.3 Nginx 基础特性


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


2.4 Nginx 模块介绍


nginx 有多种模块

核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件 驱动机制 、进程管理等核心功能
标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置等等
可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持 Stream服务模块: 实现反向代理功能,包括TCP协议代理
第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支 持等

2.5Nginx 安装

官方源码包

nginx: download

[root@nginx ~]# tar zxf nginx-1.24.0.tar.gz 

安装模块

[root@nginx nginx-1.24.0]#  dnf install gcc pcre-devel zlib-devel openssl-devel -y

加载相应模块

[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

[root@nginx nginx-1.24.0]# make && make install

查看

root@nginx nginx-1.24.0]# cd /usr/local/nginx/
[root@nginx nginx]# ls
conf  html  logs  sbin
[root@nginx sbin]# useradd -s /sbin/nologin -M nginx
[root@nginx sbin]# id nginx
uid=1001(nginx) gid=1001(nginx) groups=1001(nginx)
[root@nginx sbin]# ./nginx
[root@nginx sbin]# ps aux | grep nginx
root       42047  0.0  0.0   9868   940 ?        Ss   00:38   0:00 nginx: master process ./nginx
nginx      42048  0.0  0.2  13740  4852 ?        S    00:38   0:00 nginx: worker process
root       42054  0.0  0.1 221668  2216 pts/1    S+   00:39   0:00 grep --color=auto nginx
 
[root@nginx sbin]# netstat -antlupe | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      0          79628      42047/nginx: master 

三、平滑升级和回滚 

3.1平滑升级

解压缩

[root@nginx ~]# tar zxf echo-nginx-module-0.63.tar.gz 
[root@nginx ~]# tar zxf nginx-1.26.1.tar.gz

编译目录

[root@nginx nginx-1.26.1]# ./configure --prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--add-module=/root/echo-nginx-module-0.63 \
--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 \
--with-stream_realip_module  \
--add-module=/root/srcache-nginx-module-0.33  \
--add-module=/root/memc-nginx-module-0.20 

用新版本覆盖旧版本

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

回收旧版本

[root@nginx sbin]# kill -USR2 9155
[root@nginx sbin]# kill -WINCH 9155

3.2  平滑回滚

[root@nginx sbin]# ps aux | grep nginx
avahi        882  0.0  0.1  15528  6224 ?        Ss   11:36   0:00 avahi-daemon: running [nginx.local]
root        9155  0.0  0.0   9860  2568 ?        Ss   12:22   0:00 nginx: master process nginx
root        9195  0.0  0.1   9896  5924 ?        S    12:10   0:00 nginx: master process nginx
nginx       9196  0.0  0.1  13792  5300 ?        S    12:14   0:00 nginx: worker process
root        9219  0.0  0.0 221796  2372 pts/1    S+   12:34   0:00 grep --color=auto nginx

[root@nginx sbin]# kill -HUP 9155
[root@nginx sbin]# ps aux | grep nginx
avahi        882  0.0  0.1  15528  6224 ?        Ss   11:30   0:00 avahi
root        9155  0.0  0.0   9860  2568 ?        Ss   12:16   0:00 nginx
root        9195  0.0  0.1   9896  5924 ?        S    12:25   0:00 nginx
nginx       9196  0.0  0.1  13792  5300 ?        S    12:25   0:00 nginx
nginx       9225  0.0  0.1  13756  4868 ?        S    12:50   0:00 nginx
root        9227  0.0  0.0 221796  2376 pts/1    S+   12:58   0:00 grep 
[root@nginx sbin]# kill -WINCH 9195

四、 I/O 模型

4.1 I/O 模型相关概念

同步/异步:关注的是消息通信机制,即调用者在等待一件事情的处理结果时,被调用者是否提供完成状 态的通知。

 同步:synchronous,被调用者并不提供事件的处理结果相关的通知消息,需要调用者主动询问事 情是否处理完成

 异步:asynchronous,被调用者通过状态、通知或回调机制主动通知调用者被调用者的运行状态

阻塞/非阻塞:关注调用者在等待结果返回之前所处的状态

阻塞:blocking,指IO操作需要彻底完成后才返回到用户空间,调用结果返回之前,调用者被挂 起,干不了别的事情。

非阻塞:nonblocking,指IO操作被调用后立即返回给用户一个状态值,而无需等到IO操作彻底完 成,在最终的调用结果返回之前,调用者不会被挂起,可以去做别的事情。

4.2 网络 I/O 模型

阻塞型、非阻塞型、复用型、信号驱动型、异步

4.2.1阻塞型 I/O 模型(blocking IO)

 阻塞IO模型是最简单的I/O模型,用户线程在内核进行IO操作时被阻塞

       用户线程通过系统调用read发起I/O读操作,由用户空间转到内核空间。内核等到数据包到达后,然 后将接收的数据拷贝到用户空间,完成read操作

        用户需要等待read将数据读取到buffer后,才继续处理接收的数据。整个I/O请求的过程中,用户线程是被阻塞的,这导致用户在发起IO请求时,不能做任何事情,对CPU的资源利用率不够。

        优点:程序简单,在阻塞等待数据期间进程/线程挂起,基本不会占用 CPU 资源

        缺点:每个连接需要独立的进程/线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销 较apache 的preforck使用的是这种模式。

        同步阻塞:程序向内核发送I/O请求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回,则进 程将一直等待并不再接受新的请求,并由进程轮询查看I/O是否完成,完成后进程将I/O结果返回给 Client,在IO没有返回期间进程不能接受其他客户的请求,而且是有进程自己去查看I/O是否完成,这种 方式简单,但是比较慢,用的比较少

4.2.2 非阻塞型 I/O 模型 (nonblocking IO)

       用户线程发起IO请求时立即返回。但并未读取到任何数据,用户线程需要不断地发起IO请求,直到数据 到达后,才真正读取到数据,继续执行。即 “轮询”机制存在两个问题:如果有大量文件描述符都要等, 那么就得一个一个的read。这会带来大量的Context Switch(read是系统调用,每调用一次就得在用户 态和核心态切换一次)。轮询的时间不好把握。这里是要猜多久之后数据才能到。等待时间设的太长, 程序响应延迟就过大;设的太短,就会造成过于频繁的重试,干耗CPU而已,是比较浪费CPU的方式,一 般很少直接使用这种模型,而是在其他IO模型中使用非阻塞IO这一特性。 

        非阻塞:程序向内核发送请I/O求后一直等待内核响应,如果内核处理请求的IO操作不能立即返回IO结果,进程将不再等待,而且继续处理其他请求,但是仍然需要进程隔一段时间就要查看内核I/O是否完成。

         查看上图可知,在设置连接为非阻塞时,当应用进程系统调用 recvfrom 没有数据返回时,内核会立即返 回一个EWOULDBLOCK错误,而不会一直阻塞到数据准备好。如上图在第四次调用时有一个数据报准 备好了,所以这时数据会被复制到 应用进程缓冲区 ,于是 recvfrom 成功返回数据。

        当一个应用进程这样循环调用 recvfrom 时,称之为轮询 polling 。这么做往往会耗费大量CPU时间,实 际使用很少。


4.2.3 多路复用 I/O 型(I/O multiplexing)

         I/O multiplexing 主要包括:select,poll,epoll三种系统调用,select/poll/epoll的好处就在于单个 process就可以同时处理多个网络连接的IO。

        它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数 据到达了,就通知用户进程。

        它的基本原理就是select/poll/epoll这个function会不断的轮询所负责的所有socket,当某个socket有数 据到达了,就通知用户进程。

        Apache prefork是此模式的select,worker是poll模式。

        IO多路复用(IO Multiplexing) :是一种机制,程序注册一组socket文件描述符给操作系统,表示“我要 监视这些fd是否有IO事件发生,有了就告诉程序处理”IO多路复用一般和NIO一起使用的。NIO和IO多路 复用是相对独立的。NIO仅仅是指IO API总是能立刻返回,不会被Blocking;而IO多路复用仅仅是操作系统 提供的一种便利的通知机制。操作系统并不会强制这俩必须得一起用,可以只用IO多路复用 + BIO,这时 还是当前线程被卡住。IO多路复用和NIO是要配合一起使用才有

实际意义

        IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,就通知该进程多个连接共用一 个等待机制,本模型会阻塞进程,但是进程是阻塞在select或者poll这两个系统调用上,而不是阻塞在真 正的IO操作上用户首先将需要进行IO操作添加到select中,同时等待select系统调用返回。当数据到达 时,IO被激活,select函数返回。用户线程正式发起read请求,读取数据并继续执行从流程上来看,使用 select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视IO,以及调用select函数的 额外操作,效率更差。并且阻塞了两次,但是第一次阻塞在select上时,select可以监控多个IO上是否已 有IO操作准备就绪,即可达到在同一个线程内同时处理多个IO请求的目的。而不像阻塞IO那种,一次只 能监控一个IO虽然上述方式允许单线程内处理多个IO请求,但是每个IO请求的过程还是阻塞的(在select 函数上阻塞),平均时间甚至比同步阻塞IO模型还要长。如果用户线程只是注册自己需要的IO请求,然 后去做自己的事情,等到数据到来时再进行处理,则可以提高CPU的利用率IO多路复用是最常使用的IO 模型,但是其异步程度还不够“彻底”,因它使用了会阻塞线程的select系统调用。因此IO多路复用只能称 为异步阻塞IO模型,而非真正的异步IO

优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述 符一个线程),这样可以大大节省系统资源

缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理 需要 2 次系统调用,占用时间会有增加

4.2.4 信号驱动式 I/O 模型 (signal-driven IO)

        信号驱动I/O的意思就是进程现在不用傻等着,也不用去轮询。而是让内核在数据就绪时,发送信号通知 进程。

        调用的步骤是,通过系统调用 sigaction ,并注册一个信号处理的回调函数,该调用会立即返回,然后主 程序可以继续向下执行,当有I/O操作准备就绪,即内核数据就绪时,内核会为该进程产生一个 SIGIO信 号,并回调注册的信号回调函数,这样就可以在信号回调函数中系统调用 recvfrom 获取数据,将用户进 程所需要的数据从内核空间拷贝到用户空间

        此模型的优势在于等待数据报到达期间进程不被阻塞。用户主程序可以继续执行,只要等待来自信号处 理函数的通知。

        在信号驱动式 I/O 模型中,应用程序使用套接口进行信号驱动 I/O,并安装一个信号处理函数,进程继续运行并不阻塞

        当数据准备好时,进程会收到一个 SIGIO 信号,可以在信号处理函数中调用 I/O 操作函数处理数据。优点:线程并没有在等待数据时被阻塞,内核直接返回调用接收信号,不影响进程继续处理其他请求因此 可以提高资源的利用率

缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知

异步阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核收到进程请求后

进行的IO如果不能立即返回,就由内核等待结果,直到IO完成后内核再通知进程。

4.2.5  异步 I/O 模型 (asynchronous IO)

  异步I/O 与 信号驱动I/O最大区别在于,信号驱动是内核通知用户进程何时开始一个I/O操作,而异步I/O 是由内核通知用户进程I/O操作何时完成,两者有本质区别,相当于不用去饭店场吃饭,直接点个外卖,把 等待上菜的时间也给省了

        相对于同步I/O,异步I/O不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备 好,都会直接返回给用户进程,然后用户态进程可以去做别的事情。等到socket数据准备好了,内核直 接复制数据给进程,然后从内核向进程发送通知。IO两个阶段,进程都是非阻塞的。

         信号驱动IO当内核通知触发信号处理程序时,信号处理程序还需要阻塞在从内核空间缓冲区拷贝数据到 用户空间缓冲区这个阶段,而异步IO直接是在第二个阶段完成后,内核直接通知用户线程可以进行后续 操作了

        优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠

        缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。目前 Windows 下通过 IOCP 实现了真正的 异步 I/O,在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编 程时以 IO 复用模型模式+多线程任务的架构基本可以满足需求

        Linux提供了AIO库函数实现异步,但是用的很少。目前有很多开源的异步IO库,例如libevent、libev、 libuv。
        异步非阻塞:程序进程向内核发送IO调用后,不用等待内核响应,可以继续接受其他请求,内核调用的 IO如果不能立即返回,内核会继续处理其他事物,直到IO完成后将结果通知给内核,内核在将IO完成的 结果返回给进程,期间进程可以接受新的请求,内核也可以处理新的事物,因此相互不影响,可以实现 较大的同时并实现较高的IO复用,因此异步非阻塞使用最多的一种通信方式。 

五、Nginx核心配置 

全局配置

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
user  nginx;
worker_processes  auto;
worker_cpu_affinity 0001 0010;  

重启服务

[root@nginx ~]# nginx -s reload

查看

[root@nginx ~]# ps aux | grep nginx
root       55887  0.0  0.0  10024  3476 ?        Ss   23:07   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      55943  0.0  0.1  14364  5008 ?        S    23:27   0:00 nginx: worker process
nginx      55944  0.0  0.1  14364  5008 ?        S    23:27   0:00 nginx: worker process
root       55946  0.0  0.0 221664  2304 pts/0    S+   23:27   0:00 grep --color=auto nginx

在末尾添加以下内容

[root@nginx ~]# vim /etc/security/limits.conf
nginx            -      nofile          100000

修改连接数

[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf
events {
    worker_connections  100000; 
}

root和alias 

新建一个网页

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

编写配置文件 

[root@nginx nginx]# vim /usr/local/nginx/conf.d/vhost.conf
server{
    listen 80;
    server_name www.example.org;
    root /data/web/html;
    index index.html;
}

创建文件夹,并打印

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

重新载入

[root@nginx nginx]# nginx -s reload

alias

编写配置文件

server{
    listen 80;
    server_name www.example.org;
    root /data/web/html;
    index index.html;
    location /test1/ {
        root /data/web;
    }
    location /test2 {
        alias /data/web/test1;
    }
}    

测试

Nginx账户认证

创建认证文件

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

创建并编写配置文件

[root@nginx ~]# mkdir -p /data/web
[root@nginx ~]# mkdir /data/web/lee
[root@nginx ~]# echo lee > /data/web/lee/index.html
[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf
server{
    listen 80;
    server_name www.example.org;
    root /data/web/html;
    index index.html;
 
    location /lee {
        root /data/web;
        auth_basic "login password";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
    }
}

重启服务并查看网页

[root@nginx ~]# nginx -s reload

 Nginx自定义错误页面

创建文件夹

[root@nginx ~]# mkdir -p /data/web/errorpage
[root@nginx ~]# echo errorpage > /data/web/errorpage/404.html

编写配置文件


[root@nginx ~]# vim /usr/local/nginx/conf.d/vhost.conf 
server{
    listen 80;
    server_name www.example.org;
    root /data/web/html;
    index index.html;
    
    error_page 404 /40x.html;
 
    location /lee {
        root /data/web;
        auth_basic "login password";
        auth_basic_user_file "/usr/local/nginx/.htpasswd";
    }
    location = /40x.html {
        root /data/web/errorpage;
    }
}

六、Nginx 高级配置 

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 ~]# cd /usr/local/nginx/conf.d/
[root@nginx conf.d]# vim status.conf
server {
   listen 80;
    server_name status.example.org;
    root /data/web/html;
    index index.html;
     location /status {
        stub_status;
   }
}

Nginx 压缩功能

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

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

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

   gzip  on;  
   gzip_comp_level 5;
   gzip_min_length 1k;
   gzip_http_version 1.1;
   gzip_vary on;
   gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/gif image/png;
[root@nginx conf.d]# nginx -t

重启服务

[root@nginx conf.d]# nginx -s reload
[root@nginx conf.d]# echo hello example xixi > /data/web/html/small.html
[root@nginx conf.d]# cat /var/log/example.org/access.log > /data/web/html/big.html

测试

[root@nginx conf.d]# curl --head --compressed 172.25.254.100/small.html 
[root@nginx conf.d]# curl --head --compressed 172.25.254.100/big.html

Rewrite相关功能

Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求

此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库

rewrite是nginx服务器的重要功能之一,用于实现URL的重写,URL的重写是非常有用的功能

比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问

另外还可以在一定程度上提高网站的安全性。

配置文件

[root@nginx conf.d]# vim vhost.conf 
server {
    listen 80;
    server_name var.example.org;
    root /data/web/html;
    index index.html;
 
    location / {
        root /data/web/var;
        index index.html;
        rewrite / http://www.example.com permanent;     
       
    }
}

创建文件夹

[root@nginx conf.d]# mkdir /data/web/var -p

测试

[root@nginx nginx]# curl var.example.org

全站加密 

创建目录

[root@nginx ~]# cd /usr/local/nginx/
[root@nginx nginx]# mkdir certs

加密


[root@nginx ~]# openssl req  -newkey  rsa:2048 -nodes -sha256 -keyout/usr/local/nginx/certs/example.org.key  -x509  -days 365 -out /usr/local/nginx/certs/example.org.crt

编写配置文件

[root@nginx certs]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
    listen 443 ssl;
    server_name www.example.org;
    root /data/web/html;
    index index.html;

    ssl_certificate /usr/local/nginx/certs/example.org.crt;
    ssl_certificate_key /usr/local/nginx/certs/example.org.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;
 
    location / {
    
        if ( $scheme = http ){
            rewrite / https://$host redirect;
        }
      
        if ( !-e $request_filename ){
            rewrite /(.*) https://$host/index.html redirect;
        }
    }
}

防盗链

防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:

none: #请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。

blocked: #请求报文有referer首部,但无有效值,比如为空。

server_names: #referer首部中包含本主机名及即nginx 监听的server_name。

arbitrary_string: #自定义指定字符串,但可使用*作通配符。

regular expression: #被指定的正则表达式模式匹配到的字符串,要使用~开头

[root@nginx ~]# cd /data/web/html/images

配置文件

[root@webserver1 html]# vim index.html
<html>
  <head>
    <meta http-equiv=Content-Type content="text/html;charset=utf-8">
    <title>盗链</title>
</head>
  <body>
    <img src="http://www.example.org/images/logo.png" >
    <h1 style="color:red">欢迎大家</h1>
    <p><a href=http://www.example.org>狂点老李</a>出门见喜</p>
  </body>
</html>

然后重启httpd服务


[root@webserver1 html]# systemctl restart httpd

Nginx反向代理

编辑配置文件,添加以下内容

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

proxy_cache_path /usr/local/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120 max_size=1g;
[root@nginx conf.d]# vim /usr/local/nginx/conf.d/vhost.conf
server {
    listen 80;
   server_name www.example.org;

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

    location /static {
        proxy_pass http://172.25.254.20:8080;
        proxy_cache proxycache;  
        proxy_cache_key $request_uri;  
        $scheme$proxy_host$request_uri
        proxy_cache_valid 200 302 301 10m;  
        proxy_cache_valid any 1m;   
    }
}

然后重启服务

[root@nginx conf.d]# nginx -s reload

七、实现FastCGI

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默认的主页资源,示例:fastcgi_index index.php;
fastcgi_index name;

#设置传递给FastCGI服务器的参数值,可以是文本,变量或组合,可用于将Nginx的内置变量赋值给自定义key
fastcgi_param parameter value [if_not_empty];

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
}

源码编译php

解决依赖问题

[root@nginx ~]# yum install -y bzip2 systemd-devel libxml2-devel sqlite-devel libpng-devel libcurl-devel oniguruma-devel

解压源码并安装

[root@nginx nginx-1.26.2]#  ./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 管理cgi

php相关配置

[root@nginx ~]# cd /usr/local/php/etc
[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 
[root@nginx etc]# cd php-fpm.d/
[root@nginxphp-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 

生成启动文件,注释以下内容

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 

准备php测试页面

[root@nginx ~]# mkdir -p /data/web/php
[root@nginx ~]# cat /data/web/php/index.php 
phpinfo();
?>

Nginx配置转发


[root@nginx ~]# vim /apps/nginx/conf.d/php.conf
server {
listen 80;
server_name php.timinglee.org;
root /data/php;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi.conf;
}
}

访问验证php测试页面

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值