我使用的服务器操作系统是Ubuntu 12.04 64位 LTS,内存为512M并且没有启用虚拟内存。优化后,服务器内存一般占用在256M-378M之间,并稳定运行。所以呢,我应该来分享一下我的配置过程。
确定空闲的内存和虚拟内存是否开启
要着手配置服务器之前,先来看一下服务器内存的使用情况。你可以通过如下命令来进行查看:
free -m
当然,你也可以通过如下命令来查看内存都用到哪了(根据各进程内存占用大小排序的一个列表)!
ps -eo pmem,pcpu,rss,vsize,args | sort -k 1 -r | less
关闭不用的服务,让LAMP处于低内存占用状态
在关闭不用的服务之前,我们需要知道哪些服务项是不必要的。我找到了一款开机启动服务管理的软件:sysv-rc-conf,图开操作界面,很实用。其安装命令如下:
sudo apt-get install sysv-rc-conf
接着通过如下命令来打开sysv-rc-conf的图形操作界面(如何操作在图片界面中有说的),如下
sudo sysv-rc-conf
其图形界面如下:
Configure Linux Startup Applications with sysv-rc-conf
下图中所示的服务是我关闭的,你可以退据实际情况定夺:
sendmail:这是一个邮件服务,因为我使用的是163邮箱stmp服务,所以就没有必要开启。如果你需要你的服务器,能通过php mail()函数发送邮件,那就不要关闭了。
dns-clean:使用拨号上网时,清除DNS信息。这在服务器上一般用不到。故直接关闭其启动。
关于更多的linux服务介绍,你可以移步到:ubuntu 服务优化
配置APACHE
在内存占用中,apache是最大的内存占用户。安装LAMP环境后,默认的相关配置是很不适合于小内存服务运行的,所以很有必要做一定的修改。我将用如下的技术点来让apache占用更低的内存,保持原有的速度。
处理少量的并发请求
加载必要的模块
记录必要的日志信息
减少APACHE子进程的数量
prefork模式是由多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器。它具有很强的自我调节能力,只要很少的配置就可以了。最重要是将MaxClients设置为一个适合的值以处理潜在的访问高峰其,但其值不能太大,以致超出了物理内存的大小。如下是我的配置内容:
<IfModule mpm_prefork_module>
StartServers 1
MinSpareServers 1
MaxSpareServers 3
MaxClients 15
MaxRequestsPerChild 3000
</IfModule>
当Apache被启动时,Apache会自动创建StartServers个进程,并且尽力将空闲进程数保持在MinSpareServers和MaxSpareServers之间。当空闲进程小于MinsPareServers时,Apache会以大约1s钟的时间来创建进程;当小于MaxSpareServers时,Apache将会删除多余的空闲进程,释放服务器资源。进程数的最大值是由MaxClients决定。MaxRequestsPerChild用来控制每个进程在处理了多少次请求之后自动销毁,若这个参数的值为0表示无限(即不销毁进程)。
worker模式是由多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于采用的是线程处理,所以可以处理大量的请求的同时,系统资源的占用小于基于进程的MPM。我的控制指领配置如下:
<IfModule mpm_worker_module>
StartServers 1
MinSpareThreads 5
MaxSpareThreads 15
ThreadLimit 25
ThreadsPerChild 5
MaxClients 25
MaxRequestsPerChild 200
</IfModule>
StartServers指令设置了服务器启动时建立的子进程数量。MinSpareThreads最小空闲进程数。MaxSpareThreads配置最大空闲线程数。ThreadLimit每个子进程可配置的线程数上限。MaxClients允许同时伺服的最大接入请求数量(最大线程数量)。ThreadsPerChild每个子进程建立的常驻的执行线程数。MaxRequestsPerChild配置每个子进程在其生存期内允许伺服的最大请求数量。
除了更改以上配置外,我还更改了“KeepAliveTimeOut(连接存活时间)”,将其值调整为15,默认值为5。
只加载必要的模块
在Apache中的配置中,加载了很多不必要的模块,我们有必要把不必要的模块清理出去。你可以通过如下的命令查看你的Apache加载了哪些模块:
apache2ctl -M
如下的图片是Apache默认加载的模块;当然,你的也可能有所差异。
Default Apache modules
为了能让wordpress正常的运行,以下模块是必不可少的。
LoadModule dir_module modules/mod_dir.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule mime_module modules/mod_mime.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule alias_module modules/mod_alias.so
LoadModule authz_host_module modules/mod_authz_host.so
LoadModule rewrite_module modules/mod_rewrite.so
你可以把不必要的模块注释掉以节约内存,或者通过如下命令来开启/关闭模块。如:
sudo a2enmod module_name #开启模块
sudo a2dismod module_name #关闭模块
当然,在更改后,你必须重载apache服务以生效。
sudo /etc/init.d/apache2 reload
更少的日志处理
如果你想最大程度的优化性能的话,你可以减少记录日志文件信息。在服务器上,我把错误日志级别设为error。另外,如果你可以不记录一些不必关心的统计数据(如:User-Ageng、http-referer)。
ErrorLog ${APACHE_LOG_DIR}/error.log
#
# LogLevel: Control the number of messages logged to the error_log.
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
#
LogLevel error
我是这么处理的,具体配置就看你了。
优化My Sql服务
调整My Sql内存占用是很容易处理的。我将会告诉你为什么而不是告诉你怎么做。看完如下内容后,你很有希望能在你的服务器上做些优化。我们可以了解一下Mysql设置的以下几个方面:
可以关闭的事件处理
调整MySql的参数配置
使用MySql的第三方配置助手
编辑Mysql的配置文件(/etc/mysql/my.conf),优化MySql性能。
可以关闭的事件处理
MySql允许我们为数据库的表指定不同的存储引擎,最常见的两种类型是InnoDB和MyISAM。这两种存储引擎不同的具体表现如下:
MyISAM支持表级的锁定,这就意味着,当数据将要写入到数据库表时,整个表都处于锁定状态。也就是说要是同时有其他数据要写入到数据库表中的话,它必须等到上次操作完成之后才能执行。
InnoDB提供了行级的锁定,也就意味着,当向表中的某行写入数据时,也就只有那一行被锁定,表中的其他行都是可以进行写入的。
表级的锁定只有在数据库操作量很大时才会表现出来。对于一般的网站来讲,MyISAM通常能够提供更好的性能,更低的服务成本。
如果你决定只使用MyISAM型表,你必须把如下的配置项加入到mysql配置文件中:
default-storage-engine=MyISAM
default-tmp-storage-engine=MyISAM
如果你的数据库中的表都是MyISAM类型的,你可以关闭InnoDB引擎来节约内存。请在mysql配置文件中加入如下:
skip-innodb
如果你的数据库以前是用的InnoDB,你可以通过以下简单的脚本把InnoDb类型的表转化成MyISAM类型。
#!/bin/bash
MYSQLCMD=mysql
for db in `echo show databases | $MYSQLCMD | grep -v Database`; do
for table in `echo show tables | $MYSQLCMD $db | grep -v Tables_in_`; do
TABLE_TYPE=`echo show create table $table | $MYSQLCMD $db | sed -e's/.*ENGINE=\([[:alnum:]\]\+\)[[:space:]].*/\1/'|grep -v 'Create Table'`
if [ $TABLE_TYPE = "InnoDB" ] ; then
mysqldump $db $table > $db.$table.sql
echo "ALTER TABLE $table ENGINE = MyISAM" | $MYSQLCMD $db
fi
done
done
调整MySql的参数配置
这里有几个参数让可以调整MyISAM,让其能更快更稳定的运行。
索引缓冲区的大小
这可能是影响MySql内存占用和性能最关键的一个配置了。MySql总是试图把所有的索引全部放入到索引缓冲区中,所以这就可以获得巨大的性能提升。SQL查阅时就会直接从内存中读取。你应该让你的关键字能够放入到缓冲区,我不能说设置多大最好,因为我并不知道你有多少的空闲内存。
查阅结果的缓存
如果你连续两次作相同的查阅,MySql并无须作第二次查阅。如果你想提高性能,你能满足你的需求,但它非常消耗内存。所以你要把他设置的不高不低。
以下的3个参数用来设置Mysql查询集缓存大小:
query_cache_size
query_cache_limit
query_cache_type
最大的连接数
关于最大的数据库连接与apache的进程数有关。所以如果你对apache作了限制,那就应该没有多大的事了。
表缓存
每当你访问某个表时,MySql总会在缓存表中加载一个参考表作为一个入口。这对于并发有请求,有着很大的性能提升,稍微的增加内存的占用。你可以不断的增加表的缓存,但是操作系统所能同时打开的文件是有限的,请记住这一点。如果把表缓存设置的太低,MY SQL也会罢工,你应该不希望这样的。
以下是我对我对轻云服务器的My sql配置做的处理:
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
skip-locking
key_buffer = 16K
max_allowed_packet = 1M
table_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 64K
# For low memory, InnoDB should not be used so keep skip-innodb uncommented unless required
skip-innodb
# Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = /var/lib/mysql/
#innodb_data_file_path = ibdata1:10M:autoextend
#innodb_log_group_home_dir = /var/lib/mysql/
#innodb_log_arch_dir = /var/lib/mysql/
# You can set .._buffer_pool_size up to 50 - 80 %
# of RAM but beware of setting memory usage too high
#innodb_buffer_pool_size = 16M
#innodb_additional_mem_pool_size = 2M
# Set .._log_file_size to 25 % of buffer pool size
#innodb_log_file_size = 5M
#innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit = 1
#innodb_lock_wait_timeout = 50
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates
[isamchk]
key_buffer = 8M
sort_buffer_size = 8M
[myisamchk]
key_buffer = 8M
sort_buffer_size = 8M
[mysqlhotcopy]
interactive-timeout
My sql的第三方配置向导
我找到了Percona,他提供免费MYSQL配置向导让你的数据库服务器处于最佳的状态。
My sql服务监视
My sql存储统计决定你使用的最佳值。另外,这里有两个实用的工具,可以方便的来读统计数据并把它们以图表的形式展现:tuning-primer.sh和mysqltuner.pl。
这些脚本将会控制你的数据库服务,最后,他会给你一个建议性的报告,你可以参照这在你的服务器上做一定的优化。
优化PHP 及其缓存
PHP程序并不会突然占用很大的内存,所以你不用担心它的内存占用,除非你的应用确实需要。我对此做过调查,找到一些小的调整可以降低PHP对服务器内存的占用。
; Limit the memory to 40M should be fine for barebones WordPress
memory_limit = 48M
realpath_cache_ttl=300
realpath_cache_size=1M
可选的PHP缓存
安装PHP的缓冲器,如Alternative PHP Cache。PHP缓存可以存储PHP执行后的结果,以便在重复的数据请求中不必重复执行PHP脚本。
pecl install apc
在php.ini中加入如下配置:
[APC]
extension=apc.so
apc.enabled=1
apc.shm_segments=1
;32M per WordPress install
apc.shm_size=128M
;Relative to the number of cached files (you may need to watch your stats for a day or two to find out a good number)
apc.num_files_hint=7000
;Relative to the size of WordPress
apc.user_entries_hint=4096
;The number of seconds a cache entry is allowed to idle in a slot before APC dumps the cache
apc.ttl=7200
apc.user_ttl=7200
apc.gc_ttl=3600
;Setting this to 0 will give you the best performance, as APC will
;not have to check the IO for changes. However, you must clear
;the APC cache to recompile already cached files. If you are still
;developing, updating your site daily in WP-ADMIN, and running W3TC
;set this to 1
apc.stat=1
;This MUST be 0, WP can have errors otherwise!
apc.include_once_override=0
;Only set to 1 while debugging
apc.enable_cli=0
;Allow 2 seconds after a file is created before it is cached to prevent users from seeing half-written/weird pages
apc.file_update_protection=2
;Leave at 2M or lower. WordPress does't have any file sizes close to 2M
apc.max_file_size=2M
;Ignore files
apc.filters = "/var/www/apc.php"
apc.cache_by_default=1
apc.use_request_time=1
apc.slam_defense=0
apc.mmap_file_mask=/var/www/temp/apc.XXXXXX
apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600
apc.lazy_classes=0
apc.lazy_functions=0
静态缓存
另外一个非常好的建议是安装一个HTTP加速器,如Varnish。它确实很有效,安装及配置Varnis是一个复杂且漫长的话题,所以不再缀述。
最终结果
我把服务器的相关配置分享以便能获取在最低配置上获取最佳的性能。我用的是Ubuntu 12.04 LTS, LAMP, Varnish, APC Cache,支持了3个Wordpress网站,能保证博客每天1W人的访问量。让我们来看看Blitz.io的测试报告吧:
Blitz-Test-Result
正如你所看到的那样,当网站访问量达到42,735,587时,也仅仅只用0.23%用户连接超时。或许我还可以做些什么,但对于这我已经很开心了。
如果你感觉按照上面来做感觉麻烦,你可以试试 PuPHPet 或Vagrant。