LAMP 架构html
对任何系统进行调优的第一步都是了解它的工做原理。按照最简单的形式,基于 LAMP 的应用程序是用 PHP 这样的脚本语言编写的,它们做为 Linux 主机上运行的 Apache Web 服务器的一部分运行。jquery
PHP 应用程序经过请求的 URL、全部表单数据和已捕获的任意会话信息从客户机得到信息,从而肯定应该执行什么操做。若有必要,服务器会从 MySQL 数据库(也在 Linux 上运行)得到信息,将这些信息与一些 Hypertext Markup Language(HTML)模板组合在一块儿,并将结果返回给客户机。当用户在应用程序中导航时,这个过程重复进行;当多个用户访问系统时,这个过程会并发进行。可是,数据流不是单向的,由于能够用来自用户的信息更新数据库,包括会话数据、统计数据(包括投票)和用户提交的内容(好比评论或站点更新)。除了动态元素以外,还有静态元素,好比图像、JavaScript 代码和层叠样式表(CSS)。linux
在研究 LAMP 系统中的请求流以后,就来看看可能出现性能瓶颈的地方。数据库提供许多动态信息,因此数据库对查询的响应延迟都会反映在客户机中。Web 服务器必须可以快速地执行脚本,还要可以处理多个并发请求。最后,底层操做系统必须处于良好的状态才能支持应用程序。经过网络在不一样服务器之间共享文件的其余设置也可能成为瓶颈。浏览器
度量性能安全
持续地对性能进行度量在两个方面有帮助。首先,度量能够帮助了解性能趋势,包括好坏两方面的趋势。做为一个简单的方法,查看一下 Web 服务器上的中央处理单元(CPU)使用率,就能够了解 CPU 是否负载太重。一样,查看过去使用的总带宽并推断将来的变化,能够帮助判断何时须要进行网络升级。这些度量最好与其余度量和观测结合考虑。例如,当用户抱怨应用程序太慢时,能够检查磁盘操做是否达到了最大容量。服务器
性能度量的第二个用途是,判断调优是对系统性能有帮助,仍是使它更糟糕了。方法是比较修改以前和以后的度量结果。可是,为了进行有效的比较,每次应该只修改一个设置,而后对适当的指标进行比较以判断修改的效果。每次只修改一个设置的缘由应该是很明显的:同时作出的两个修改极可能会相互影响。选择用来进行比较的指标比较微妙。cookie
选择的指标必须可以反映应用程序用户感受到的响应。若是一项修改的目标是减小数据库的内存占用量,那么取消各类缓冲区确定会有帮助,可是这会牺牲查询速度和应用程序性能。因此,应该选择应用程序响应时间这样的指标,这会使调优向着正确的方向发展,而不只仅是针对数据库内存使用量。网络
能够以许多方式度量应用程序响应时间。最简单的方法多是使用 curl
命令,见清单 1。
$ curl -o /dev/null -s -w %{time_connect}:%{time_starttransfer}:%{time_total}\ http://www.canada.com 0.081:0.272:0.779 |
清单 1 给出对一个流行的新闻站点执行 curl
命令的状况。输出一般是 HTML 代码,经过 -o
参数发送到 /dev/null
。-s
参数去掉全部状态信息。-w
参数让 curl
写出表 1 列出的计时器的状态信息:
计时器 | 描述 |
---|---|
time_connect | 创建到服务器的 TCP 链接所用的时间 |
time_starttransfer | 在发出请求以后,Web 服务器返回数据的第一个字节所用的时间 |
time_total | 完成请求所用的时间 |
这些计时器都相对于事务的起始时间,甚至要先于 Domain Name Service(DNS)查询。所以,在发出请求以后,Web 服务器处理请求并开始发回数据所用的时间是 0.272 - 0.081 = 0.191 秒。客户机从服务器下载数据所用的时间是 0.779 - 0.272 = 0.507 秒。
经过观察 curl
数据及其随时间变化的趋势,能够很好地了解站点对用户的响应性。
固然,Web 站点不只仅由页面组成。它还有图像、JavaScript 代码、CSS 和 cookie 要处理。curl
很适合了解单一元素的响应时间,可是有时候须要了解整个页面的装载速度。
用于 Firefox 浏览器的 Tamper Data 扩展(参见 参考资料 一节中的连接)能够在日志中记录 Web 浏览器发出的每一个请求,并显示每一个请求所用的下载时间。使用这个扩展的方法是,选择 Tools > Tamper Data 来打开 Ongoing requests 窗口。装载要考察的页面,而后就会看到浏览器发出的每一个请求的状态和装载每一个元素所用的时间。图 1 给出装载 developerWorks 主页的结果。
图 1. 用于装载 developerWorks 主页的请求细目
每一行描述一个元素的装载状况。显示的数据包括发出请求的时间、装载所用的时间、大小和结果。Duration 栏列出装载元素自己所用的时间,Total Duration 栏列出全部子元素所用的时间。在图 1 中,装载主要页面所用的时间是 516 毫秒(ms),可是装载全部东西并显示整个页面所用的时间是 5101 ms。
Tamper Data 扩展有一种有用的模式,将页面装载数据的输出绘制成图形。右击 Ongoing requests 窗口上半部分的任何地方,并选择 Graph all。图 2 显示图 1 中数据的图形化视图。
图 2. 用于装载 developerWorks 主页的请求的图形化视图
在图 2 中,每一个请求的持续时间显示为深蓝色,并相对于页面装载的启始时间显示。因此,能够看出哪些请求使整个页面的装载变慢了。
尽管关注的重点是页面装载时间和用户体验,可是也不要忽视核心系统指标,好比磁盘、内存和网络。有许多实用程序能够捕获这些信息;其中最有帮助的多是 sar
、vmstat
和 iostat
。关于这些工具的更多信息,请参见 参考资料 一节。
在对系统的 Apache、PHP 和 MySQL 组件进行调优以前,应该花一些时间确保底层 Linux 组件的运行正常。还应该对正在运行的服务进行缩减,只运行须要的那些服务。这不可是一种良好的安全实践,并且能够节省内存和 CPU 时间。
大多数 Linux 发布版都定义了适当的缓冲区和其余 Transmission Control Protocol(TCP)参数。能够修改这些参数来分配更多的内存,从而改进网络性能。设置内核参数的方法是经过 proc
接口,也就是经过读写 /proc
中的值。幸运的是,sysctl
能够读取 /etc/sysctl.conf
中的值并根据须要填充 /proc
,这样就可以更轻松地管理这些参数。清单 2 展现在互联网服务器上应用于 Internet 服务器的一些比较激进的网络设置。
清单 2. 包含较为激进的网络设置的 /etc/sysctl.conf
# Use TCP syncookies when needed net.ipv4.tcp_syncookies = 1 # Enable TCP window scaling net.ipv4.tcp_window_scaling: = 1 # Increase TCP max buffer size net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 # Increase Linux autotuning TCP buffer limits net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 # Increase number of ports available net.ipv4.ip_local_port_range = 1024 65000 |
将这些设置添加到 /etc/sysctl.conf
的现有内容中。第一个设置启用 TCP SYN cookie。当从客户机发来新的 TCP 链接时,数据包设置了 SYN 位,服务器就为这个半开的链接建立一个条目,并用一个 SYN-ACK 数据包进行响应。在正常操做中,远程客户机用一个 ACK 数据包进行响应,这会使半开的链接转换为全开的。有一种称为 SYN 泛滥(SYN flood) 的网络***,它使 ACK 数据包没法返回,致使服务器用光内存空间,没法处理到来的链接。SYN cookie 特性能够识别出这种状况,并使用一种优雅的方法保留队列中的空间(细节参见 参考资料 一节)。大多数系统都默认启用这个特性,可是确保配置这个特性更可靠。
启用 TCP 窗口伸缩使客户机可以以更高的速度下载数据。TCP 容许在未从远程端收到确认的状况下发送多个数据包,默认设置是最多 64 KB,在与延迟比较大的远程客户机进行通讯时这个设置可能不够。窗口伸缩会在头中启用更多的位,从而增长窗口大小。
后面四个配置项增长 TCP 发送和接收缓冲区。这使应用程序能够更快地丢掉它的数据,从而为另外一个请求服务。还能够强化远程客户机在服务器繁忙时发送数据的能力。
最后一个配置项增长可用的本地端口数量,这样就增长了能够同时服务的最大链接数量。
在下一次引导系统时,或者下一次运行 sysctl -p /etc/sysctl.conf
时,这些设置就会生效。
磁盘在 LAMP 架构中扮演着重要的角色。静态文件、模板和代码都来自磁盘,组成数据库的数据表和索引也来自磁盘。对磁盘的许多调优(尤为是对于数据库)集中于避免磁盘访问,由于磁盘访问的延迟至关高。所以,花一些时间对磁盘硬件进行优化是有意义的。
首先要作的是,确保在文件系统上禁用 atime
日志记录特性。atime
是最近访问文件的时间,每当访问文件时,底层文件系统必须记录这个时间戳。由于系统管理员不多使用 atime
,禁用它能够减小磁盘访问时间。禁用这个特性的方法是,在 /etc/fstab
的第四列中添加 noatime
选项。清单 3 给出了一个配置示例。
清单 3. 演示如何启用 noatime
的 fstab 示例
/dev/VolGroup00/LogVol00 / ext3 defaults,noatime 1 1 LABEL=/boot /boot ext3 defaults,noatime 1 2 devpts /dev/pts devpts gid=5,mode=620 0 0 tmpfs /dev/shm tmpfs defaults 0 0 proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 LABEL=SWAP-hdb2 swap swap defaults 0 0 LABEL=SWAP-hda3 swap swap defaults 0 0 |
在清单 3 中只修改了 ext3 文件系统,由于 noatime
只对驻留在磁盘上的文件系统有帮助。为让这一修改生效,不须要从新引导;只需从新挂装每一个文件系统。例如,为了从新挂装根文件系统,运行 mount / -o remount
。
有多种磁盘硬件组合,并且 Linux 不必定可以探测出访问磁盘的最佳方式。可使用 hdparm
命令查明和设置用来访问 IDE 磁盘的方法。hdparm -t /path/to/device
执行速度测试,能够将这个测试结果做为性能基准。为了使结果尽量准确,在运行这个命令时系统应该是空闲的。清单 4 给出在 hda
上执行速度测试的结果。
# hdparm -t /dev/hda /dev/hda: Timing buffered disk reads: 182 MB in 3.02 seconds = 60.31 MB/sec |
这一测试说明,在这个磁盘上读取数据的速度是大约每秒 60 MB。
在尝试一些磁盘调优选项以前,必须注意一个问题。错误的设置可能损害文件系统。有时候会出现一个警告,指出这个选项与硬件不兼容;可是,有时候没有警告消息。所以,在将系统投入生产以前,必须对设置进行完全的测试。在全部服务器上都采用标准的硬件也会有所帮助。
表 2 列出比较经常使用的一些选项。
选项 | 描述 |
---|---|
-vi | 向磁盘查询它支持的设置以及它正在使用的设置。 |
-c | 查询/启用 (E)IDE 32 位 I/O 支持。hdparm -c 1 /dev/hda 启用这个设置。 |
-m | 查询/设置每中断多扇区模式。若是设置大于零,设置值就是每一个中断能够传输的最大扇区数量。 |
-d 1 -X | 启用直接内存访问(DMA)传输并设置 IDE 传输模式。hdparm 手册页详细说明了在 -X 后面能够设置的数字。只有在 -vi 说明目前并未使用最快速的模式的状况下,才须要进行这个设置。 |
不幸的是,对于 Fiber Channel and Small Computer Systems Interface(SCSI)系统,调优依赖于具体的驱动器。
必须将有帮助的设置添加到启动脚本中,好比 rc.local
。
网络文件系统(NFS)是一种经过网络共享磁盘的方法。NFS 能够帮助确保每一个主机具备相同数据的拷贝,并确保修改反映在全部节点上。可是,在默认状况下,NFS 的配置不适合大容量磁盘。
每一个客户机应该用 rsize=32768,wsize=32768,intr,noatime
挂装远程文件系统,从而确保:
atime
。
能够将这些设置放在 /etc/fstab
中,见 清单 3。若是使用自动挂装器,那么应该将这些设置放在适当的 /etc/auto.*
文件中。
在服务器端,必定要确保有足够的 NFS 内核线程来处理全部客户机。在默认状况下,只启动一个线程,可是 Red Hat 和 Fedora 系统会启动 8 个线程。对于繁忙的 NFS 服务器,应该提升这个数字,好比 32 或 64。能够用 nfsstat -rc
命令评估客户机,了解是否有阻塞的现象,这个命令显示客户机远程过程调用(RPC)统计数据。清单 5 显示一个 Web 服务器的客户机统计数据。
# nfsstat -rc Client rpc stats: calls retrans authrefrsh 1465903813 0 0 |
第二列 retrans
是零,这表示从上一次从新引导以来没有出现须要从新传输的状况。若是这个数字比较大,就应该考虑增长 NFS 内核线程。设置方法是将所需的线程数量传递给 rpc.nfsd
,好比 rpc.nfsd 128
会启动 128 个线程。任什么时候候均可以进行这种设置。线程会根据须要启动或销毁。一样,这个设置应该放在启动脚本中,尤为是在系统上启用 NFS 的脚本。
关于 NFS,最后要注意一点:若是可能的话,应该避免使用 NFSv2,由于 NFSv2 的性能比 v3 和 v4 差得多。在现代的 Linux 发行版中这应该不是问题,可是能够在服务器上检查 nfsstat
的输出,了解是否有任何 NFSv2 调用。