两分钟带你了解企业高性能web服务器!

web服务基础介绍

正常情况下单次web服务访问流程:

只要看得到源码,就是静态,例如:

看不到源码就是动态。

web服务介绍

Apache经典web服务端

Apache prefork模型

预派生模式,有一个主进程,生成多个子进程,最大并发1024.

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

相对比较占内存,较稳定,进程间不会相互影响。

最古老最稳定,适用于访问量不大的场景。

并发性不高

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

较智能。

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

Nginx-高性能的web服务端

nginx核心模块代码长度198430,一行代码约2.2万人民币。

天猫、淘宝、京东、小米、163、新浪等都在用Nginx或者进行二次开发。

基于Nginx的工作场景:

在企业里源码编译装Nginx:

把四个虚机都删了,用9.4的镜像克隆一个虚机:nginx

自行下载包(没有的私信博主):

配置网络:

下载: 

解压:

下载c语言编译:

再编译:

查看模块:

需要的模块如下:
会发现报错:
此时搜索pcre:
下载pcre:
再编译:
会发现又报错:
再search:
再下载:
再编译:
又报错:
再search:
再下载:
再编译:
然后:
将之前做的操作还原:
安装各模块:
创建用户:
此时:
端口也有了:
关闭防火墙:
此时可访问:
查看大小:
关闭:
重启:
怎么卸载:
关闭debug功能:

效果:

再编译:

完了以后:

编辑环境变量配置文件(把nginx软件命令执行路径添加到目录里):

查看大小:

启动起来:

此时启动不起来:
因为端口被占,先查看端口被什么占住了,再kill掉即可重启:
再启动:
配置目录:
配置文件:
此时安装成功。

平滑升级

下载:
此时:
把包拖进来:
解压:
编译:
再make:
可查看版本:
隐藏版本:
检测环境:
把新版本的nginx命令复制过去,再kill老版本:
备份:

26版本的不能make install

强制复制:

老的:
启动新的:
写一个死循环测试一下:
此时:
没断:
此时已更新:

平滑回滚

平滑回滚就是把老版本激活,把新版本回收:

把老的激活:

把新的回收:
这个也没断:

服务端I/O流程

磁盘

网络

磁盘I/O

计算方式:

机械磁盘的寻道时间、旋转延迟和数据传输时间:
寻道时间:是指磁头移动到正确的磁道上所花费的时间,寻道时间越短则 I/O 处理就越快,目前磁盘的寻道时
间一般在 3-15 毫秒左右。
旋转延迟:是指将磁盘片旋转到数据所在的扇区到磁头下面所花费的时间,旋转延迟取决于磁盘的转速,通常
使用磁盘旋转一周所需要时间的 1/2 之一表示,比如 7200 转的磁盘平均训传延迟大约为
60*1000/7200/2=4.17 毫秒,公式的意思为 (每分钟 60 *1000 毫秒每秒 /7200 转每分 /2 ),如果是
15000 转的则为 60*1000/15000/2=2 毫秒。 1.2.4.2 网络 I/O
网络通信就是网络协议栈到用户空间进程的 IO 就是网络 IO
网络 I/O 处理过程
获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求( 1-3
构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成( 4
返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端( 5-7
不论磁盘和网络 I/O
每次 I/O ,都要经由两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短
数据传输时间:指的是读取到数据后传输数据的时间,主要取决于传输速率,这个值等于数据大小除以传输速
率,目前的磁盘接口每秒的传输速度可以达到 600MB ,因此可以忽略不计。
常见的机械磁盘平均寻道时间值:
7200 / 分的磁盘平均物理寻道时间: 9 毫秒
10000 / 分的磁盘平均物理寻道时间: 6 毫秒
15000 / 分的磁盘平均物理寻道时间: 4 毫秒
常见磁盘的平均延迟时间:
7200 转的机械盘平均延迟: 60*1000/7200/2 = 4.17ms
10000 转的机械盘平均延迟: 60*1000/10000/2 = 3ms
15000 转的机械盘平均延迟: 60*1000/15000/2 = 2ms
每秒最大 IOPS 的计算方法:
7200 转的磁盘 IOPS 计算方式: 1000 毫秒 /(9 毫秒的寻道时间 +4.17 毫秒的平均旋转延迟时
)=1000/13.13=75.9 IOPS
10000 转的磁盘的 IOPS 计算方式: 1000 毫秒 /(6 毫秒的寻道时间 +3 毫秒的平均旋转延迟时
)=1000/9=111IOPS
15000 转的磁盘的 IOPS 计算方式: 15000 毫秒 /(4 毫秒的寻道时间 +2 毫秒的平均旋转延迟时
)=1000/6=166.6 IOPS

网络I/O

处理过程:

获取请求数据,客户端与服务器建立连接发出请求,服务器接受请求( 1-3
构建响应,当服务器接收完请求,并在用户空间处理客户端的请求,直到构建响应完成( 4
返回数据,服务器将已构建好的响应再通过内核空间的网络 I/O 发还给客户端( 5-7
磁盘和网络I/O:
每次 I/O ,都要经由两个阶段:
第一步:将数据从文件先加载至内核内存空间(缓冲区),等待数据准备完成,时间较长
第二步:将数据从内核缓冲区复制到用户空间的进程的内存中,时间较短

I/O模型

I/O模型相关概念

同步&异步:

通知:同步

不通知:异步

阻塞&非阻塞:

拿数据,

等待:阻塞

不等待:非阻塞

apache:同步阻塞型,稳定。

apache prefork:同步阻塞型。

网络I/O模型

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

一个进程只能处理一个。

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

响应其他链接,但是会一直不断询问,性能不好。因为不会告诉你它好了没,所以只能一直问。

信号驱动I/O模型

内核会反馈已接受到请求,那进程就不会再问了,数据就绪时,发送信号通知进程。异步非阻塞。

异步I/O模型

由内核通知用户进程操作何时完成,非阻塞。

以上都一次进程只能接受一个数据响应。

所以:

多路复用I/O型

select会记录在一个表格中,select再通知内核,进行处理。select会对表格进行列变,每次都全部问一遍好没好,select最多承担1024链接数。

poll是没有链接数限制的,只不过链接越多越慢,其他和select一样。

epoll进行哈希计算,只记录已经好了的在表格,没好的不记表格。

五种I/O对比

I/O具体实现方式

I/O常见实现

select

poll

epoll

kqueue

Iocp

rtsig

/dev/poll

eventport

常用I/O模型比较

零拷贝
零拷贝介绍
      传统的 Linux 系统的标准 I/O 接口( read write )是基于数据拷贝的,也就是数据都 copy_to_user 或者 copy_from_user ,这样做的好处是,通过中间缓存的机制,减少磁盘 I/O 的操作,但是坏处也很明显,大量数据的拷贝,用户态和内核态的频繁切换,会消耗大量的 CPU 资源,严重影响数据传输的性能,统计表明,在Linux 协议栈中,数据包在内核态和用户态之间的拷贝所用的时间甚至占到了数据包整个处理流程时间的57.1%。
       零拷贝就是上述问题的一个解决方案,通过尽量避免拷贝操作来缓解 CPU 的压力。零拷贝并没有真正做到“0” 拷贝,它更多是一种思想,很多的零拷贝技术都是基于这个思想去做的优化。

Nginx架构和安装

查看nginx信息:

再起服务:

-v:查看版本

不关闭进程的条件下重新加载配置:

关nginx:

再起:

开启时不能指定值,所以关掉:

# nginx -s stop

再指定:

指定了开不了,文件中注释了可开启。

生成Nginx启动文件

生效启动:

Nginx核心配置详解

配置文件说明

# 全局配置端,对全局生效,主要设置 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 监听的端口 3.2 全局配置
Main 全局配置段常见的配置指令分类
正常运行必备的配置
优化性能相关的配置
用于调试及定位问题相关的配置
事件驱动相关的配置
全局配置说明 :
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
}

主进程root:

子进程nginx:

全局配置

参数优化:

会是两个:(没成功)

4核:

双核:

因为:

会发现没有改成功:

改错啦!

此时:

压力测试:

查看access日志:

发现没报错链接

再调大:

再查看:

最后发现:

###

换epoll模型:

再做本地解析后浏览器访问:

root和alias:

root:

alias:

location

# 语法规则:
location [ = | ~ | ~* | ^~ ] uri { ... }
= # 用于标准 uri 前,需要请求字串与 uri 精确匹配,大小敏感 , 如果匹配成功就停止向下匹配并立
即处理请求
^~ # 用于标准 uri 前,表示包含正则表达式 , 并且匹配以指定的正则表达式开头
# uri 的最左边部分做匹配检查,不区分字符大小写
~ # 用于标准 uri 前,表示包含正则表达式 , 并且区分大小写
~* # 用于标准 uri 前,表示包含正则表达式 , 并且不区分大写
不带符号 # 匹配起始于此 uri 的所有的 uri
\ # 用于标准 uri 前,表示包含正则表达式并且转义字符。可以将 . * ? 等转义为普通符号
# 匹配优先级从高到低:
=, ^~, ~/~*, 不带符号

= :

或者:

那是因为访问的不是指定的位置。

这样也不行。

又或者标准uri前加=:

这个可以。

但:

其实生效了,但失败的根本原因是要精确匹配,一模一样才行。

谁优先级高:

换一下位置?

所以不加=的优先级高。

~:

因为uri前面以t开头的才行,所以lee不行,tee和test行。

~*:以什么结尾

以html结尾。

换成大写?(不行的,因为要区分大小写,但加*可以)

不加*:

\:转译

或者():

或者:

证明优先级:

所以最先匹配~。

再来:

但是换顺序了就是web5,所以web4和web5一样的优先级。

不断测试发现:

第一: 带 = 号的

第二:~ 里,不带号 和 带号 优先级一样。 谁在前,谁的优先级高。

第三:不带符号的优先级高。

第四:带^的

Nginx用户认证

创建默认日志文件:

如何使用:

编辑配置文件:

加用户认证:

自定义错误页面

日志重定向

检测文件是否存在

长连接配置

装长连接测试工具:

telnet是浏览器:

报文的内容要手打:

如果设定了3次测试次数:

重启:


timeout:

五秒后自动断开。

保持连接65s,客户能看到的连接时间是60s:

时区

下载服务器配置:vi

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,同时设置,此项优级高.

字节:

0就是不限速。

Nginx高级应用

Nginx状态页面

重启后:

设定一下用户认证:

或者指定谁看:

没问题。

Nginx压缩包

看效果:

可以看见这是没被压缩的。

这是被压缩的。

--head只看头部

=要跟上文件:因为精确指定。

FastCGI

实验环境:

删掉nginx目录:

重新编译:

解压各个包:

编译:

安装:

什么是FastCGI?

FastCGI是进程管理器。CGI会将webserver的请求转发给会解决请求的人。PHP处于一会儿上班一会儿下班的状态。

PHP-FPM:FastCGI Process Manager。worker进程一般会有多个,每个进程会嵌入一个PHP解析器,进行PHP代码的处理。

FastCGI配置指令

源码编译PHP

启服务:

#nginx

装php:

解压:

编译:

缺一个包:

去阿里云找:

综上:

编译成功。

再make:

php相关配置优化

复制文件:

生成启动脚本:

重载:

写日志:

解决只读:

重载并启动:

🆗啦~

准备php测试页面

创建一个目录存放页面:

写子配置文件:

先在主配置文件里引用:

写子配置文件:

重启:

关防火墙:

502报错:检查端口、子配置文件等。

php的动态扩展模块

让php支持memcache:

编辑配置文件:

安装memcache

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

测试

访问并多访问几次:

然后发现:

性能有没有提升:

okk~到这你就超越99%的同学啦!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值