第38卷第6期 计算机应用与软件
Vol 38No.62021年6月
ComputerApplicationsandSoftware
Jun.2021
LNMP生产服务器技术改进
曾棕根
(宁波职业技术学院电子信息工程学院 浙江宁波315800)
收稿日期:2019-09-24。曾棕根,副教授,主研领域:软件工程。
摘 要 LNMP服务器由于构造复杂、优化难度高,经常出现处理PHP网页时卡死、数据库崩溃和服务器被入侵的情况。针对上述问题,使用源代码现场编译、tmpfs内存文件系统、网络压缩传输、多进程和线程池等多种技术手段,对LNMP生产服务器进行了深度技术改进。测试结果表明,LNMP服务器处理PHP MariaDB请求的速度提高了1.8倍,还具有安全可靠和抗拥塞特征,取得了很好的应用效果。关键词 LNMP PHP 安全 高性能 抗拥塞 服务器
中图分类号 TP393.09 文献标志码 A DOI:10.3969/j.issn.1000 386x.2021.06.005
TECHNICALIMPROVEMENTOFLNMPPRODUCTIONSERVER
ZengZonggen
(SchoolofElectronicInformationEngineering,NingboPolytechnic,Ningbo315800,Zhejiang,China)
Abstract DuetothecomplexityofLNMPserverstructureandthedifficultyofoptimization,itoftenoccursthattheserverisstuckwhenprocessingPHPwebpages,thedatabasecrashesandtheserverisinvaded.Thispaperfindsthekeytotheaboveproblems.TheLNMPproductionserverwasdeeplyimprovedbymeansofon sitesourcecodecompilation,tmpfsmemoryfilesystem,networkcompressiontransmission,multiprocessandthreadpool.Thetestresultsshowthatthespeedo
fprocessingPHP MariaDBrequestsbyLNMPserverisincreasedby1.8times,anditalsohasthecharacteristicsofsecurity,reliabilityandanti congestion,andachievesgoodapplicationeffect.Keywords LNMP PHP Security High performance Anti congestion Server
0 引 言
php文件下载源码LNMP架构免费开源、功能强大,是当前最流行的Web服务器架构,与大数据和人工智能服务器存在密切的关系。由于LNMP架构技术牵涉面广、安装与配置非常复杂且可借鉴的高端经验少,按照默认配置无法发挥该架构稳定、安全和高效的特征。LNMP服务器出现安全漏洞、在访问高峰期网页卡死甚至数据库崩溃成为常态,因此对LNMP生产服务器进行技术改进成为当前亟待解决的问题。
历经七年对LNMP生产服务器的管理与深入研究,解决了LNMP架构安装、运行中遇到的各种问题,对该架构进行了全方位的技术改进,使得该架构安全、快速、抗拥塞。本文系统地论述了该架构在上述三方
面所做的深度技术改进。
1 LNMP架构的组成
LNMP架构是指由Linux内核的操作系统、Nginx服务器、MariaDB数据库服务器和PHP脚本服务器组成的PHP动态网站运行架构,组成该架构的四个软件
都是免费开源的[1]
。生产环境下,推荐使用的Linux
操作系统是CentOS 7(1908),其稳定、快速、安全;Nginx是一款高性能低开销的Web服务器,目前最新
的稳定版本是1.16.2[2];MariaDB是MySQL数据库的
一个分支,由开源社区维护,代码更新速度最为快速,目前最新稳定版本为1
0.3.11;PHP网页服务器则是用来编译和运行PHP脚本,目前最新版本为7.2.24。图1为L
NMP架构数据流动示意图。
24
计算机应用与软件
2021
年
图1 LNMP架构数据流动示意图
用户总是在浏览器中发出PHP网页查看请求,Nginx收到用户的PHP程序调用请求后,将此请求发送给PHP FPM服务器,PHP FPM服务器则调用PHP进程去编译和运行PHP程序,PHP程序则通过SQL指令从MariaDB数据库中去存取所需信息,MariaDB将SQL指令运行后以二维表的形式将结果返回给PHP进程,PHP进程则将记录以HTML语法进行包装,PHP FPM服务器会将此H
TML文本传送给Nginx服务器,Nginx服务器则将此HTML文本返回给客户端浏览器,客户端浏览器则解释此HTML文本中的HTML标签,用户即可从浏览器中看到此P
HP程序的运行结果。由图1可见,数据的流动是以单一、固定的路径传输的,数据总是从客户端浏览器中发出,经过Nginx、PHP FPM、MariaDB三项服务,最后按原路返回,构成一个闭环。因此,要提高LNMP架构的安全性和性能,就必须对LNMP架构每一项服务进行技术改进。
2 安全性改进
确保在互联网环境下的访问安全是服务器建设中最重要的问题。L
NMP架构服务器安全措施包括磁盘规划、以编译方式安装最新源代码、开放有限端口、限定登录账户
、规划文件读取权限和使用HTTPS访问协议等。
2.1 磁盘规划
服务器上应该使用多个物理磁盘,构建某种磁盘阵列,某个磁盘损坏时可以直接用新磁盘替换,从而不影响服务器的运行。例如RAID5,服务器上有3个以上硬盘即可做此模式,一份数据分成3份写,如果一个硬盘坏了,其他数据不会受损失,抽出坏的硬盘再插入
新的硬盘即可[
3]
。在安装CentOS操作系统时,应该将系统所需的不同的目录分别安装在不同的物理磁盘分区上,以避免某一个目录出现错误时殃及其他目录或整个磁盘。表1列出了不同分区和所需的磁盘空间,其中/boot引导分区用来存储Linux内核,/根分区用来存储CentOS操作系统所需的其他文件,而服务器中所安装的其他
软件如Nginx、MariaDB、PHP及其需要保存的数据则放在/opt分区内。还可以进一步细化,将/根分区中的用户目录和临时目录等放于不同的分区中。这样确保了运行中出现的问题限定在某一个分区内,能最大限度地减少损失。
表1 典型的CentOS磁盘分区规划
分区类型文件系统容量swap交换分区1N/A2GBswap交换分区2N/A2GB/boot引导分区Ext4200MB/根分区
xfs40GB/opt软件安装分区
xfs
其余空间
如果LNMP服务器配有专用的大容量磁盘阵列服务器时,可以使用网线将二者的网卡直连,两块直连网卡使用192.168.0.x地址组建成一个局域网,在LNMP服务器中采用mount命令将磁盘阵列服务器挂载到CentOS操作系统的一个目录中,如mount192.168.0.100
:/vol1/mnt/array,最后将CentOS操作系统中LNMP架构的用户数据或者备份数据直接写在/mnt/array即磁盘阵列设备上,这样就确保了LNMP架构在物理层面上的安全性。
2.2 编译安装最新源码
LNMP架构中Nginx、MariaDB和PHP都是开源软件,官方一直在做功能、性能或安全性上的改进,因此不宜采用LNMP一键安装包或RPM安装包,而应去下载最新的适用于L
inux操作系统的源代码包,直接在CentOS操作系统上现场配置、编译和安装。这样可以确保得到最新的稳定版本,而且可以生成最适合服务器CPU运行的二进制代码。同时,管理员也清楚每个软件都安装到哪个文件夹中,便于日后的升级和维护。
CentOS操作系统安装好后,应该立即使用yum yupdate命令对操作系统进行一次全面更新,而且要定期使用这个命令更新系统。系统更新后,采用rpm qkernel查看是否升级了内核,若升级,则需重启操作系统,重启后会自动运行最新内核。这时,使用uname a查看正在运行的内核,并用rpm e将旧版本的内核删除,否则分配给内核的200MB磁盘空间会不够用,下次将无法升级新版内核。
还要立即升级CentOS操作系统中的gcc、cmake和libzip,这三个软件都是编译其他软件(如Nginx、MariaDB和PHP)所必须的。
通过g++--version命令,可以看到CentOS中
第6期 曾棕根:LNMP生产服务器技术改进25
g++的版本为g++(GCC)4.8.520150623(RedHat4.8.5-39),由于该版本太老,因此须到(https://gcc.gnu.org/)上下载gcc-9.2.0.tar.gz源代码编译安装。安装完成后,必须要把/usr/lib64/中的libstdc++.so.6链接到新版本的/usr/local/lib64/libstdc++.so.6.0.27文件,否则g++编译器将无法使用gcc-9.2.0。
从cmake(https://cmake.org/down load/)上下载最新的cmake-3.15.1.tar.gz源代码包,编译安装完成后,调用cmake version时,会出现“段错误(coredumped)”而无法使用,执行hash r命令可以解决此错误。
libzip是编译PHP所必须的支持包,CentOS默认没有安装libzip,要去(https://libzip.org/)下载最新版本的libzip-1.5.2.tar.gz源代码包,编译安装后,运行libzip时会出现不到zipconf.h的错误,还需复制/usr/local/lib/libzip/include/zipconf.h到/usr/local/include/zipconf.h位置。
Nginx、MariaDB和PHP都需要从上下载最新源代码,然后在本机上现场编译安装,Nginx安装在/opt中,而MariaDB和PHP安装在/usr/local/文件夹中。
要定期关注这三个软件的更新情况,并要随官方的修订及时更新它们,以确保最近发现的漏洞能被及时修复。
特别地,以前PHP使用Oracle官方发布的MySQL驱动libmysql与MariaDB服务进行通信,为了避免版权问题和程序的非可控性,PHP已自行开发了mysqlnd本地驱动替代libmysql,所以不再需要先安装MariaDB再安装PHP了,传统的安装PHP的方式中,在编译PHP时,需要指定以下几项:
--with-mysql=/usr/local/mysql
--with-mysqli=/usr/local/mysql/bin/mysql_config
--with-pdo-mysql=/usr/local/mysql
现在使用mysqlnd驱动,编译PHP时,上述本条配置应该改为:
--with-mysql=mysqlnd
--with-mysqli=mysqlnd
--with-pdo-mysql=mysqlnd
安装完成后,如果在phpinfo输出的mysqli项中发现ClientAPIlibraryversion为mysqlnd5.0.12-dev-20150407,说明mysqlnd驱动mysqlnd5.0.12-dev-20150407已经安装成功,PHP脚本可以使用pdo_mysql和mysqli这两种APIExtensions通过mysqlnd驱动与MariaDB数据库服务器通信。
CentOS操作系统中各种软件都采用OpenSSL函数库进行加密,但OpenSSL在2014年4月8日曝光了一个名为heartbleed的漏洞。利用该漏洞,约30%以https开头网址的用户登录账号密码通过网络被窃取[4]。所以必须从OpenSSL(https://www.opens sl.org)下载,将OpenSSL1.0.2k-fips26Jan2017升级为OpenSSL1.1.1d10Sep2019。同时,使用Open SSL加密函数库的Nginx、PHP和OpenSSH都必须采用新安装的OpenSSL加密函数库重新编译安装,以确保网站访问安全和服务器SSH远程访问安全。
2.3 服务器访问限制
LNMP服务器编译安装好后,为确保服务器在互联网上的访问安全,必须在开放有限端口、限定登录
账户、规划文件读取权限等方面作出限制。
通常情况下,服务器只开放80号Web服务端口、22号SSH远程访问端口和443号https访问端口,同时关闭不需要的服务,这样可以减少暴露在互联网中的漏洞。同时,删除firewalld.service防火墙,安装ipt ables services防火墙,这样易于使用。
同时,在CentOS操作系统中,要禁止在ssh中使用root直接登录,要求用户先用普通账号登录CentOS操作系统,再通过su命令输入root账号密码才可以登录root账号,这样可以防止针对root账号的远程暴力破解。因此,首先要在CentOS中创建一个普通账号,再在/etc/ssh/sshd_config中设置PermitRootLoginno即可。
在PHP FPM服务器的配置文件php fpm.conf中,设置user=www和group=www,使得只有www组的www用户才可能访问PHP FPM服务。
MariaDB数据库服务必须指定允许来自某台客户机的某个账号来连接自己。在MySQL数据库的user表中,只留下Host为localhost和127.0.0.1和User为root的这两条记录,以此只允许来自当前服务器的root账号连接MariaDB数据库服务,从而确保了MariaDB数据库服务的安全。
对CentOS操作系统中每个文件和文件夹,都可以通过chgrp命令设置其隶属于哪个组,通过chown命令来设置它隶属于哪个用户,并通过chmod命令来设置所有者、所属组其他用户和其他组对它的操作权限。操作权限用4、2、1数字来代表,4表示读取权限,2表示写入权限,1表示执行权限[5]。如775这三个数字代表拥有者、组用户、其他用户的权限分别为7=4+2+1、7=4+2+1、5=4+1,第一个数字7表示所有者具有读取、写入和执行权限,第二个数字7表示与所有者同组的用户具有读取、写入和执行权限,第三个数字
26
计算机应用与软件2021年
5表示其他用户具有读取和执行权限。对访问用户、访问组和其他组的操作权限限定,使得CentOS操作系统中的文件访问得到有效地保护。
2.4 使用HTTPS访问协议
Nginx默认采用HTTP协议与客户端浏览器通信,该协议采用明文方式传输网页和用户账号密码,容易受到网络中间人的窃密,所以极不安全。Nginx服务器必须采用HTTPS安全传输协议与用户端浏览器通信。用户在首次访问Nginx服务器时,Nginx服务器会将使用私钥加密的包
含对应公钥的数字证书CA发送到客户端浏览器中,以后用户发送访问请求给Nginx服务器时,先用浏览器中的数字证书中的公钥对信息进行加密,再发送给Nginx服务器;Nginx服务器在接收到用户的访问信息后,用服务器上的对应的私钥解开信息;在完成用户提交的请求后,将相应网页用服务器中对应的私钥加密后,再发送给客户端浏览器;客户端浏览器接收到信息后,会用浏览器中该Nginx服务器对应的数字证书中的公钥解密,完成双向加密通信。
将私钥和包含对应公钥的数字证书拷贝到Nginx服务器上后,只需在Nginx的配置文件中编写如下配置即可:
server{
listen443ssl;
server_namelocalhost;
ssl_certificate/etc/pki/tls/certs/server.cer;
ssl_certificate_key/etc/pki/tls/private/server.key;
重启Nginx服务器后,客户端浏览器就可以采用https://方式来访问网站了,这样确保了通信安全。
3 处理速度改进
对软件的运行方式进行优化,才可以充分发挥服务器硬件性能,使得服务器处理Web请求的速度大大加快,从而避免服务器横向扩展,一方面降低了服务器购置成本,另一方面降低了软件管理上的复杂度。可以从如下几个方面进行技术改进来加快LNMP服务器的处理速度:用内存代替磁盘、使用PHP缓存、多进程并行处理、优化InnoDB存储引擎性能和压缩后再传输。3.1 用内存代替磁盘
内存的存取速度远高于磁盘的存取速度,因此把网站的程序文件和数据库直接放在内存中,将会大大提高网站的访问速度。目前最大容量内存是单条128GB,一块CPU可以插8条内存,也就是1TB。如果是双路CPU,最大内存可达8TB。网站代码磁盘占用量一般在1GB以内,MariaDB数据库的数据文件一般在20GB以内,因此一台64GB的服务器就可以将网站和数据库全部放入内存直接存取。
将磁盘文件放入内存的方法,就是使用TMPFS文件系统。TMPFS,即临时文件系统,是最好的基于RAM的文件系统,是由Linux内核的VM子系统管理的。TMPFS初始容量默认是物理内存大小的一半[6]。指定的TMPFS内存空间并不会被锁定独占,只有挂载存储文件后才会占用相
应大小的空间。
使用TMPFS文件系统最大的风险是意外掉电后该文件系统中的文件会全部消失。为了防止服务器意外掉电,确保数据安全,一方面定期自动备份数据库,另一方面,确保服务器上的双电源都有效。使用通信型UPS不间断电源通过联机USB线实时监测市电,一旦发现断电,立即会切换到电源供电,并自动将内存中的文件保存到磁盘中,再自动关闭CentOS服务器,最后自动关闭UPS。整个处理过程只需5分钟,所以UPS只需600W的功率,如LADISH1000600W型UPS。
3.2 使用PHP缓存
使用PHP缓存,可以大大减少同一网页再次被访问时PHP的编译时间开销,从而大大加快网页访问速度。
PHP是解释型语言而非编译型语言,每次调用PHP文件时,翻译器先将PHP文件翻译成易于执行的中间代码(即opcode字节码)后再执行,执行完后所占用的内存马上被释放,基本上所有数据包括opcode字节码在此时都被销毁。opcode字节码并非目标机器代码,不能直接在硬件上运行。该PHP文件第二次被调用时,同样还是会被重新转换为字节码,但很多时候文件内容几乎是一样的,比如静态HTML文件生成字节码后其内容很久都不会改变,这样就非常浪费时间。
为了避免上述问题,PHP开发了Opcache组件。该组件的前身是Optimizer+,它是PHP的官方公司Zend开发的一款闭源但可以免费使用的PHP优化加速组件,2013年3月中旬Optimizer+改名为Opcache,在PHP源代码中已经包含了该组件。启用PHP的Opcache组件后,PHP会缓存PHP字节码,使得再次调用相同的PHP文件时,无须编译,直接从Opcache缓存中获取字节码去运行;同时,Opcache还应用了一些代码优化模式,使得代码执行更快,从而加速PHP的执行,使CPU消耗少了许多,PHP网页的响应时间也大幅缩短。图2是PHP程序使用Opcache缓存后的生命周期示意图。
第6期
曾棕根:LNMP生产服务器技术改进
27
图2 PHP对象生命周期示意图
可以看到,传统的PHP的整个运行过程为:Re quest请求(Nginx等)→Zend引擎读取.php文件→扫描其词典和表达式→解析文件→创建要执行的计算机代码(称为Opcode)→执行Opcode→Response返回。使用了O
pcache组件后,如果PHP网页没有变化,就直接从O
pcache缓存中读取中间代码,再去执行,避免了C
PU的重复计算。3.3 多进程并行处理
为了充分利用CPU多核特征,Nginx和PHP都设计为多进程的工作方式,以提高处理效率。从图3所示的LNMP架构示意图中可以看出,客户端浏览器与Nginx管理进程交互后,Nginx监控进程就会把具体的工作任务分配给一个空闲的Nginx工作进程,对于用户的PHP网页请求,Nginx工作进程会把PHP的编译和运行工作交给PHP FPM管理进程,PHP FPM则把具体的工作任务分配给一个空闲的P
HPFastCGI工作进程,PHPFastCGI会把要访问的PHP网页编译并运行,并存取MariaDB数据库,最后把结果组织成HTML超文本,
回传给用户端浏览器。
图3 LNMP架构示意图
因此,为Nginx和PHP FPM设置合适的工作进程数量和工作方式,可以加快LNMP整体架构的处理速度。Nginx通过worker_processes指令本配置开启多少个工作进程,其数量一般为CPU的逻辑核心数量(即CPU超线程总量)。例如,双CPU共16个物理核心,每个物理核心上有2个超线程,那么worker_processes应该设置为32。
PHP FPM进程池(pm)有static(静态)、dynamic(动态)和ondemand(按需)三种PHPFastCGI工作进程启动方式。
如果将pm设置为static,那么PHPFastCGI工作进程始终保持p
m.max_children个数目。如果将pm设置为dynamic,那么PHP FPM管理进程首先启动pm.start_servers个工作进程,遇到访问高峰时,会自动增加工作进程数量,确保任何时候都有pm.min_spare_servers个空闲进程存在。访问高峰过后,如果空闲进程多于pm.max_spare_servers个时,多余的空闲进程会被杀掉;而同时能存活的最大工作进程总量为p
m.max_children个。如果将pm设置为ondemand,那么刚开始时php fpm
管理进程不会创建任何工作进程,当有请求时才会创建;当进程在pm.process_idle_timeout秒后还处于空闲状态就会被杀掉,默认时长为10秒。因此,在完全空闲时,只有一个PHP FPM管理进程存在。在此模式下,能同时存活的工作进程最大数量为pm.max_children个。
要根据具体情况来选择这三种PHP FPM的进程管理方式。如果内存足够大,可以选用static方式,按一个PHP进程占用30MB内存的标准来确定PHP进程设置数量,由于不用在使用时临时创建PHP进程,因此这种方式效率最高,作为首选方式。如果服务器内存不宽裕,则可以选用dynamic方式,动态应付访问高峰,能兼顾内存与效率。ondemand方式把节约内存放在首位,其缺点是遇到访问高峰或者如果pm.process_idle_timeout的值太短的话,服务器会频繁创建进程,用户会感受到明显的网络延迟。
3.4 优化InnoDB存储引擎性能
MariaDB的存储引擎采用插件式工作方式,而InnoDB存储引擎作为事务型数据库的首选引擎,支持事务安全表(ACID),能与MariaDB数据库系统完美结合。MariaDB系统接收的用户SQL请求和传输的数据最后都要通过InnoDB存储引擎与磁盘设备交互。LNMP架构中用户请求数据链最后都要经过InnoDB
存储引擎,因此InnoDB数据库的存取性能决定了
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论