前言
其实本文的作者我是个懒人,总喜欢在网上找一些现成的东西,而且还很屌丝买不起什么收费的产品,在互联网创业过程中,我早期使用Discuz所创建的一个小站,由于高峰期并发有好几百,导致服务器上其它应用程序受到影响,才开始钻研这些东西。那时什么都不懂,就会用远程桌面在Win2003系统中下载一个环境包安装,然后简单的复制与粘贴,直到后来在一些牛人的BLOG中学习,并逐渐认识了一些高人不耻上问,再加上平时与“谷哥”、“度娘”的形影不离,才逐渐成长起来。
在CentOS6下搭建高性能的LTMP环境
先给出这篇文章中的环境与硬件信息:
【这台自用服务器的硬件略屌丝有木有T.T】
操作系统 | CentOS 6.5 (Linux) |
WEB环境 | LTMP (LNMP) Linux + Tengine 1.5.2 (Nginx) + MariaDB 5.5.37 (MySQL) + PHP 5.4.29/5.3.28 |
优化组件 | Memcached + Jemalloc + OPcache + Pthreads |
硬件信息 | Intel(R) Xeon(R) E5405 @ 2.00GHz CPU*2 2G DDR2 内存*4 (8G) 500G SATA 硬盘*2(Raid1) |
或许很多人会对LTMP环境陌生,其实LTMP就是加强版本的LNMP,Tengine是由淘宝开发的Nginx分支,而MariaDB则是由MySQL的创始人新开发出的增强版MySQL,世界互联网巨头公司之一的Google就在使用,所在稳定与性能上,LTMP环境都经得起考验。
下图是我前段时间为了新项目开发,维护服务器时截取的,服务器在无人维护的情况下稳定运行了303天未出现任何问题,我们可以由此看出LTMP环境的稳定性。(当然这和访问压力不大也有关系)
另外,在服务器中遗留了一套LNMP环境,是我以前搞一个创业项目时,让一个参与者架设的,最近有时间看了下,发现架设的很不认真,自然性能上也好不到哪去,也证明了当年放弃和那人一起搞项目的正确性(好像跑题了),不过这套遗留下来的环境正好可以做测试,简单做了下承压对比,均使用PHP5.3版本,一样的程序得出两种不同结果:
根据对比可以看出,前后两者差距明显,在低并发的情况下,前者处理PHP文件的速度很慢,而随着并发数的增加,前者十分不稳定,甚至到了5000并发时就已经出现502错误。随后,我又进行了后者更高并发的测试,结果如下图:
[返回目录]
一、获取相关开源程序
① 利用CentOS-Linux系统自带的yum命令安装、升级所需的程序库:
sudo -s LANG=C yum -y install gcc gcc-c++ autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel krb5 krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel nss_ldap openldap-clients openldap-servers bison libevent-devel cmake wget
② 程序源码包下载:
建立源码包目录
mkdir -p /data0/software cd /data0/software
下载所需源码包
wget http://tengine.taobao.org/download/tengine-1.5.2.tar.gz wget http://cn2.php.net/distributions/php-5.4.36.tar.gz wget http://mirrors.hustunique.com/mariadb/mariadb-5.5.41/source/mariadb-5.5.41.tar.gz wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz wget http://downloads.sourceforge.net/mhash/mhash-0.9.9.9.tar.gz wget http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz wget http://downloads.sourceforge.net/mcrypt/mcrypt-2.6.8.tar.gz wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz wget http://pecl.php.net/get/zendopcache-7.0.2.tgz wget http://pecl.php.net/get/memcached-2.2.0.tgz wget http://pecl.php.net/get/memcache-2.2.7.tgz wget http://pecl.php.net/get/imagick-3.1.2.tgz wget http://pecl.php.net/get/pthreads-2.0.7.tgz wget http://www.memcached.org/files/memcached-1.4.20.tar.gz wget ftp://ftp.imagemagick.org/pub/ImageMagick/ImageMagick.tar.gz wget http://www.canonware.com/download/jemalloc/jemalloc-3.6.0.tar.bz2 wget http://www.openssl.org/source/openssl-1.0.1g.tar.gz
[返回目录]
二、安装MariaDB(MySQL) 5.5
① 编译安装Jemalloc:
tar jxvf jemalloc-3.6.0.tar.bz2 cd jemalloc-3.6.0/ ./configure make make install cd ../ ln -s /usr/local/lib/libjemalloc.so.1 /usr/lib/libjemalloc.so.1
如果是64位系统还需要输入
ln -s /usr/local/lib/libjemalloc.so.1 /usr/lib64/libjemalloc.so.1
② 编译安装MySQL:
创建mysql用户与用户组
/usr/sbin/groupadd mysql /usr/sbin/useradd -g mysql mysql
编译安装MariaDB
tar zxvf mariadb-5.5.41.tar.gz cd mariadb-5.5.41/ cmake -DCMAKE_INSTALL_PREFIX=/usr/local/webserver/mysql -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=complex -DWITH_READLINE=1 -DWITH_SSL=system -DWITH_EMBEDDED_SERVER=1 -DENABLED_LOCAL_INFILE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_PARTITION_STORAGE_ENGINE=1 -DCMAKE_EXE_LINKER_FLAGS="-ljemalloc" -DWITH_SAFEMALLOC=OFF -DMYSQL_DATADIR=/data0/mysql/3306/data -DMYSQL_USER=mysql make make install
如果编译出错将参数 -DWITH_EMBEDDED_SERVER=1 删除并执行 make clean 后重新编译
③ 一些相关设置:
ln -s /usr/local/webserver/mysql/lib/libmysqlclient.so.18 /usr/lib/libmysqlclient.so.18 chmod +w /usr/local/webserver/mysql chown -R mysql:mysql /usr/local/webserver/mysql
创建MySQL数据库存放目录
mkdir -p /data0/mysql/3306/data/ mkdir -p /data0/mysql/3306/binlog/ mkdir -p /data0/mysql/3306/relaylog/ chown -R mysql:mysql /data0/mysql/
以mysql用户帐号的身份建立数据表
/usr/local/webserver/mysql/scripts/mysql_install_db --collation-server=utf8_general_ci --basedir=/usr/local/webserver/mysql --datadir=/data0/mysql/3306/data --user=mysql
创建my.cnf配置文件
vi /usr/local/webserver/mysql/my.cnf
输入以下内容(适合4G内存以上的独立服务器或云服务器)
# Example MySQL config file for very large systems. # # This is for a large system with memory of 1G-2G where the system runs mainly # MySQL. # # MySQL programs look for option files in a set of # locations which depend on the deployment platform. # You can copy this option file to one of those # locations. For information about these locations, see: # http://dev.mysql.com/doc/mysql/en/option-files.html # # In this file, you can use all long options that a program supports. # If you want to know which options a program supports, run the program # with the "--help" option. # The following options will be passed to all MySQL clients [client] character-set-server = utf8 port = 3306 socket = /tmp/mysql.sock # The MySQL server [mysqld] character-set-server = utf8 replicate-ignore-db = mysql replicate-ignore-db = test replicate-ignore-db = information_schema user = mysql port = 3306 socket = /tmp/mysql.sock basedir = /usr/local/webserver/mysql datadir = /data0/mysql/3306/data log-error = /data0/mysql/3306/mysql_error.log pid-file = /data0/mysql/3306/mysql.pid open_files_limit = 10240 back_log = 600 max_connections = 5000 max_connect_errors = 6000 table_cache = 512 external-locking = FALSE key_buffer_size = 256M max_allowed_packet = 32M table_open_cache = 512 sort_buffer_size = 1M join_buffer_size = 1M read_buffer_size = 1M read_rnd_buffer_size = 16M bulk_insert_buffer_size = 64M myisam_sort_buffer_size = 128M myisam_max_sort_file_size = 10G myisam_repair_threads = 1 myisam_recover thread_cache_size = 300 query_cache_size = 512M query_cache_limit = 2M query_cache_min_res_unit = 2k # Try number of CPU's*2 for thread_concurrency thread_concurrency = 8 default-storage-engine = InnoDB thread_stack = 192K transaction_isolation = READ-COMMITTED tmp_table_size = 246M max_heap_table_size = 246M long_query_time = 2 # binary logging is required for replication log-slave-updates log-bin=/data0/mysql/3306/binlog/binlog binlog_cache_size = 4M binlog_format = MIXED max_binlog_cache_size = 8M max_binlog_size = 1G relay-log-index = /data0/mysql/3306/relaylog/relaylog relay-log-info-file = /data0/mysql/3306/relaylog/relaylog relay-log = /data0/mysql/3306/relaylog/relaylog expire_logs_days = 30 interactive_timeout = 120 wait_timeout = 120 # required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set # but will not function as a master if omitted server-id = 1 skip-name-resolve #master-connect-retry = 10 slave-skip-errors = 1032,1062,126,1114,1146,1048,1396 # The replication master for this slave - required #master-host = <hostname> # # The username the slave will use for authentication when connecting # to the master - required #master-user = <username> # # The password the slave will authenticate with when connecting to # the master - required #master-password = <password> # # The port the master is listening on. # optional - defaults to 3306 #master-port = 3306 # Uncomment the following if you are using InnoDB tables innodb_data_home_dir = /data0/mysql/3306/data innodb_data_file_path = ibdata1:256M:autoextend #innodb_log_group_home_dir = /data0/mysql/3306/data # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high innodb_buffer_pool_size = 1G innodb_additional_mem_pool_size = 16M # Set .._log_file_size to 25 % of buffer pool size innodb_log_file_size = 128M innodb_log_buffer_size = 16M innodb_flush_log_at_trx_commit = 2 innodb_lock_wait_timeout = 120 innodb_file_io_threads = 4 innodb_thread_concurrency = 8 innodb_file_per_table = 1 #log-slow-queries = /data0/mysql/3306/slow.log #long_query_time = 10 [mysqldump] quick max_allowed_packet = 32M #[mysql] #no-auto-rehash # Remove the next comment character if you are not familiar with SQL #safe-updates #[myisamchk] #key_buffer_size = 256M #sort_buffer_size = 256M #read_buffer = 2M #write_buffer = 2M #[mysqlhotcopy] #interactive-timeout
→【 MySQL5.5参数优化详解 】
对于1G~2G内存的VPS主机而言,一般使用MySQL自带的配置文件即可 @注意:按上文方法配置的请跳过这一步
cp /usr/local/webserver/mysql/support-files/my-large.cnf /usr/local/webserver/mysql/my.cnf
④ 配置MySQL服务脚本:
安装服务脚本
cd support-files/ cp mysql.server /etc/rc.d/init.d/mysqld chmod +x /etc/init.d/mysqld cd ../ make clean cd ../
编辑服务脚本文件
vi /etc/init.d/mysqld
查找并修改以下变量内容
basedir=/usr/local/webserver/mysql datadir=/data0/mysql/3306/data
加入启动项
chkconfig --add mysqld chkconfig --level 345 mysqld on
启动MySQL服务
service mysqld start
设置数据库root用户密码 @友情提醒:最后的密码就不要跟着复制了 – -!
/usr/local/webserver/mysql/bin/mysqladmin password 12345678
数据库版本的选择: 简单说下看法。这篇文章的案例是将数据库与前端放置在同一台服务器上的,更适合于个人站长与中小型企业,当然这种环境用来做新上线产品的过渡也不错,因为随着网站的发展,并发逐渐增加,除了硬件和带宽外,数据库必定是最先遇到瓶颈问题的。首先在单台服务器或云主机上(VPS和虚拟主机就更不用说了),MySQL各种版本的差距不是很大,企业选择一些加强版本更多是用在集群环境下,另外也为了方便维护。当然在单台服务器上,不同版本的MySQL差距多少还是有一点点的: 在MySQL5.5版本上,如果只使用InnoDB引擎,Percona Server 5.5或许是个不错的选择,很多生产环境都在使用,在性能提升与维护支持上都略优于MariaDB,但MariaDB已经包含了Percona优化过的InnoDB引擎,另外一个主要原因,我正在尝试MariaDB自带的Aria引擎,这是MyISAM引擎的加强版本,个人觉得Aria引擎更适合那些以MyISAM为默认引擎开发的程序,至少在并发压力不是很大的站点上,速度不差于甚至优于InnoDN引擎,很多网站从MyISAM转InnoDB的主要原因就是为了解决表锁的问题,而Aria引擎支持行锁,对数据写入也有优化,所以随着将来引擎版本的进步,在高并发的情况下未必不如InnoDB,但目前Aria引擎的资料并不是很多,拥有那种高并发压力的生产环境都是以稳定为第一位的,大型网站依旧会选择InnoDB引擎。作者本人没有经历过那种高并发的生产环境,个人看法仅供参考,但有一点可以肯定,在5.5版本下无论是MariaDB还是Percona Server性能都要强过MySQL的原始版本。 关于MySQL5.6版本,由于我生产环境的系统是CentOS5,一些组件无法升级到高版本导致没能安装成功,但MariaDB在这个版本上来势很凶,而且创建了自己的10版本,在这个版本上采用了一些大型企业提交的意见,其中就包括国内互联网三巨头之一的淘宝网,而且MariaDB在进入稳定版后采用了5.6内核,性能不在像前几个版本那么不尽人意,相信随着小版本的升级会逐渐稳定;而Percona Server 5.6依旧走着稳定的路线,不过据一些权威测试,评其与MySQL5.6原版的差距越来越小。个人认为,生产环境还不没到升级MySQL5.6的时候,毕竟数据库不像PHP、Nginx一类的程序,不稳定可以很容易的换回,尤其在有数据库集群的环境上升级会很麻烦。另外我在虚拟机做了测试,并发不高的情况下,MySQL5.6性能相对5.5版本的提升几乎没多少,最近看了几篇关于MySQL5.7版本的文章,感觉5.6更像是一个过渡版本,真正的大幅度提升很可能在5.7版本上,当然新站与数据不多的站还是可以升级到5.6版本的,安装方法和MySQL5.5版本大同小异。
[返回目录]
三、安装PHP 5.5/5.4/5.3
由于PHP5.2版本实在过低,对很多新出的PHP扩展也无法很好的支持,就不在教程中讲解了,而PHP5.3.28依旧用在很多生产环境上,国内很多优秀的PHP程序都推荐使用5.3版本,而PHP6在我写这篇教学的几年内并不会在生产环境上普及,相信5.5、5.4、5.3这三个PHP版本依旧是几年内生产环境上的主流。
在写这篇教程的PHP安装部分前,我在本站的服务器上做了一个测试,分别使用了以上3个PHP版本,测试程序分别使用了国内的Discuz与国外的WordPress,这两款都是比较热门的PHP程序,均使用Memcached缓存,结果大致如下:
服务器系统:CentOS 5.10 | Discuz | WordPress |
数据库查询时间 | 5.4 < 5.5 < 5.3 | 5.5 ≤ 5.4 < 5.3 |
PHP页面处理速度 | 5.5 < 5.4 < 5.3 | 5.5 < 5.4 < 5.3 |
PHP页面处理稳定性 | 5.5 < 5.4 = 5.3 | 5.5 < 5.4 = 5.3 |
(以上测试结果或许受系统、硬件等因素的影响,只供参考使用)
意外的是,5.3版本在PHP页面的处理速度上是最快的,但在连接数据库的速度方面,5.4与5.5版本的提升很明显,虽然5.3版本已经支持mysqlnd驱动,但经过测效果并不是很理想,从5.4版本后mysqlnd的性能优势才体现出来,而且很多PHP扩展逐渐不支持5.3版本了,再加上5.4.29应该是最后几个版本甚至就是最后一个版本,在维护方面要容易很多,所以我在自己的生产环境上使用了5.4版本。 其实细心的朋友应该会发现,本文给出的版本,几乎都是截止我写这篇教学时,不更新版本中最新的,因为要考虑生产环境的稳定性。如果是搭建全新的环境,推荐选择5.4或5.5版本;如果你的PHP应用程序不支持5.4以上的版本,那么5.3.28版本是最好的选择;如果生产环境中正在使用5.3版本,而且运行稳定,升级到最新的5.3.28小版本即可,等5.5版本进入最后几个版本时再考虑升级。 在前面的《获取相关开源程序》讲解中,下载的是PHP5.4.30版本,获取5.3或5.5版本只需在地址中更换对应的版本号即可,另外PHP5.5已经集成了Zendopcache功能,如果选择安装5.5版本无需下载该扩展。
[返回目录]
>安装PHP5.4/5.5(推荐)
① 安装所需的支持库
tar zxvf libiconv-1.14.tar.gz cd libiconv-1.14/ ./configure --prefix=/usr/local make make instal make clean cd ../
vi /etc/ld.so.conf
最下方输入
/usr/local/lib
然后执行
ldconfig
编译libiconv时可能遇到 “./stdio.h:1010:1: 错误: ‘gets’未声明(不在函数内)” 的问题
【点击查看解决方法】
tar zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt-2.5.8/ ./configure make make install /sbin/ldconfig cd libltdl/ ./configure --enable-ltdl-install make make install cd ../ make clean cd ../ tar zxvf mhash-0.9.9.9.tar.gz cd mhash-0.9.9.9/ ./configure make make install make clean cd ../ tar zxvf libmemcached-1.0.18.tar.gz cd libmemcached-1.0.18/ ./configure --prefix=/usr/local/libmemcached --with-memcached=/usr/local/webserver/memcached make make install make clean cd ../ ln -s /usr/local/lib/libmcrypt.la /usr/lib/libmcrypt.la ln -s /usr/local/lib/libmcrypt.so /usr/lib/libmcrypt.so ln -s /usr/local/lib/libmcrypt.so.4 /usr/lib/libmcrypt.so.4 ln -s /usr/local/lib/libmcrypt.so.4.4.8 /usr/lib/libmcrypt.so.4.4.8 ln -s /usr/local/lib/libmhash.a /usr/lib/libmhash.a ln -s /usr/local/lib/libmhash.la /usr/lib/libmhash.la ln -s /usr/local/lib/libmhash.so /usr/lib/libmhash.so ln -s /usr/local/lib/libmhash.so.2 /usr/lib/libmhash.so.2 ln -s /usr/local/lib/libmhash.so.2.0.1 /usr/lib/libmhash.so.2.0.1 ln -s /usr/local/bin/libmcrypt-config /usr/bin/libmcrypt-config ln -s /usr/local/libmemcached/lib/libmemcached.so.11 /usr/lib/libmemcached.so.11 tar zxvf mcrypt-2.6.8.tar.gz cd mcrypt-2.6.8/ /sbin/ldconfig ./configure make make install make clean cd ../
如果是64位系统还需要输入
cp -frp /usr/lib64/libldap* /usr/lib/
② 编译安装PHP
tar zxvf php-5.4.36.tar.gz cd php-5.4.36/ ./configure --prefix=/usr/local/webserver/php --with-config-file-path=/usr/local/webserver/php/etc --with-mysql --with-mysqli --with-pdo-mysql --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --disable-mysqlnd-compression-support --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --with-mcrypt=usr/lib --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-mbstring --enable-maintainer-zts make ZEND_EXTRA_LIBS='-liconv' make install cp php.ini-production /usr/local/webserver/php/etc/php.ini mv /usr/local/webserver/php/etc/php-fpm.conf.default /usr/local/webserver/php/etc/php-fpm.conf make clean cd ../
@提醒:成功编译PHP的请跳过下面灰框的步骤继续安装
如果安装的是PHP5.5版本,请在编译参数中加入 --enable-opcache 并跳过下文zendopcache的安装过程。另外在CentOS5系统中由于OpenSSL无法升级到更高版本,导致编译过程中出错(貌似搜不到正确的解决方法),给出两种解决方法: # 一种比较简单,如果你不需要OpenSSL相关的功能,删除编译参数"--with-openssl"即可解决; # 另一种需要编译升级OpenSSL版本,具体方法如下: /*安装最新版本的OpenSSL tar xzvf openssl-1.0.1g.tar.gz cd openssl-1.0.1g/ ./config shared zlib make make install /usr/local/ssl/bin/openssl version -a make clean cd ../ /*替换旧版本的OpenSSL mv /usr/bin/openssl /usr/bin/openssl.old mv /usr/include/openssl /usr/include/openssl.old ln -s /usr/local/ssl/bin/openssl /usr/bin/openssl ln -s /usr/local/ssl/include/openssl/ /usr/include/openssl /*配置库文件搜索路径 echo "/usr/local/ssl/lib" >> /etc/ld.so.conf ldconfig /*查看OpenSSL版本 openssl version -a 如果已经升级到1.0.1g版本 使用参数 --with-openssl=/usr/local/ssl 替换上文的PHP编译参数"--with-openssl"即可通过编译
③ 编译安装PHP扩展模块
tar zxvf ImageMagick.tar.gz cd ImageMagick-6.8.9-5/ ./configure make make install make clean cd ../ tar zxvf imagick-3.1.2.tgz cd imagick-3.1.2/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install make clean cd ../ tar zxvf pthreads-2.0.7.tgz cd pthreads-2.0.7/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config --enable-pthreads make make install make clean cd ../ tar zxvf zendopcache-7.0.2.tgz cd zendopcache-7.0.2/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install make clean cd ../ tar zxvf memcached-2.2.0.tgz cd memcached-2.2.0/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config --with-libmemcached-dir=/usr/local/libmemcached make make install make clean cd ../ tar zxvf memcache-2.2.7.tgz cd memcache-2.2.7/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config make make install make clean cd ../
④ 安装Memcached
编译安装Memcached
tar zxvf memcached-1.4.20.tar.gz cd memcached-1.4.20/ ./configure --prefix=/usr/local/webserver/memcached make make install make clean cd ../
如果是64位系统,可以在编译参数中加入
--enable-64bit
创建服务脚本
vi /etc/rc.d/init.d/memcached
输入以下内容
#!/bin/bash # Init file for memcached # chkconfig: - 80 12 # description: Distributed memory caching daemon # processname: memcached # config: /usr/local/webserver/memcached/memcached.conf # pidfile: /var/run/memcached.pid source /etc/init.d/functions ### Default variables PORT="11211" USER="memcached" MAXCONN="5000" CACHESIZE="1024" OPTIONS="" #BIN="/usr/local/bin" BIN="/usr/local/webserver/memcached/bin" SYSCONFIG="/usr/local/webserver/memcached/memcached.conf" ### Read configuration [ -r "$SYSCONFIG" ] && source "$SYSCONFIG" RETVAL=0 prog="memcached" desc="Distributed memory caching" start() { echo -n $"Starting $desc ($prog) on $PORT: " daemon $BIN/$prog -d -p $PORT -u $USER -c $MAXCONN -m $CACHESIZE $OPTIONS RETVAL=$? echo [ $RETVAL -eq 0 ] && touch /var/lock/subsys/$prog return $RETVAL } stop() { echo -n $"Shutting down $desc ($prog): " kill `ps -aef | grep $PORT | grep -v grep | awk '{print $2}'` > /dev/null 2>&1 RETVAL=$? echo [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$prog return $RETVAL } restart() { stop start } reload() { echo -n $"Reloading $desc ($prog): " killproc $prog -HUP RETVAL=$? echo return $RETVAL } case "$1" in start) start ;; stop) stop ;; restart) restart ;; condrestart) [ -e /var/lock/subsys/$prog ] && restart RETVAL=$? ;; reload) reload ;; status) status $prog RETVAL=$? ;; *) echo $"Usage: $0 {start|stop|restart|condrestart|status}" RETVAL=1 esac exit $RETVAL
其中"MAXCONN"与"CACHESIZE"根据服务器的实际情况进行设置,本文给出的参数建议在4G内存以上的硬件环境中使用
创立memcached用户与用户组
groupadd memcached useradd -g memcached memcached
加入启动项
chkconfig --add memcached chkconfig memcached on chmod +x /etc/init.d/memcached
启动Memcached服务
service memcached start
⑤ 修改PHP配置文件
修改 /usr/local/webserver/php/etc/php.ini 中的以下参数
disable_functions = passthru,system,popen,proc_open,shell_exec,chroot,assert,getcwd,scandir,chgrp,chmod,chown expose_php = Off html_errors = Off upload_max_filesize = 8M date.timezone = Asia/Shanghai mysqlnd.collect_memory_statistics = On session.save_handler = memcached session.save_path = "127.0.0.1:11211" extension_dir = "/usr/local/webserver/php/lib/php/extensions/no-debug-zts-20100525"
并在下方添加
extension = "imagick.so" extension = "pthreads.so" extension = "memcache.so" extension = "memcached.so" zend_extension = "/usr/local/webserver/php/lib/php/extensions/no-debug-zts-20100525/opcache.so" opcache.memory_consumption = 128 opcache.interned_strings_buffer = 8 opcache.max_accelerated_files = 4000 opcache.revalidate_freq = 60 opcache.fast_shutdown = 1 opcache.enable_cli = 1
⑥ 创建www用户和用户组
/usr/sbin/groupadd www /usr/sbin/useradd -g www www
⑦ 设置php-fpm
vi /usr/local/webserver/php/etc/php-fpm.conf
修改以下参数
pid = run/php-fpm.pid emergency_restart_threshold = 20 emergency_restart_interval = 60s process_control_timeout = 5s user = www group = www listen = /dev/shm/php-cgi.sock listen.backlog = -1 listen.owner = www listen.group = www listen.mode = 0660 pm = dynamic pm.max_children = 128 pm.start_servers = 8 pm.min_spare_servers = 8 pm.max_spare_servers = 8 pm.max_requests = 16384 request_terminate_timeout = 300s catch_workers_output = yes
其中"pm.start_servers"、"pm.min_spare_servers"、"pm.max_spare_servers"这三个参数,经过研究发现将这3个参数设置成CPU的线程数有奇效,具体原因未知(按照参数解释这样设置是错误的) 当然选择自己优化更好,"pm.max_children"的值设置为128适合4G内存以上的独立服务器或云服务器,建议根据实际情况自行修改,但不要少于CPU的线程数。
安装服务脚本
cp /data0/software/php-5.4.36/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
加入启动项
chkconfig --add php-fpm chkconfig php-fpm on chmod +x /etc/rc.d/init.d/php-fpm
启动php-fpm服务
service php-fpm start
[返回目录]
>安装PHP5.3.28
① 安装所需的支持库
与PHP5.4/5.5的方法相同,请参考上文
② 编译安装PHP
tar zxvf php-5.3.28.tar.gz cd php-5.3.28/ ./configure --prefix=/usr/local/webserver/php --with-config-file-path=/usr/local/webserver/php/etc --with-mysql --with-mysqli --with-pdo-mysql --with-iconv-dir=/usr/local --with-freetype-dir --with-jpeg-dir --with-png-dir --with-zlib --with-libxml-dir=/usr --disable-mysqlnd-compression-support --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --with-mcrypt=usr/lib --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-mbstring make ZEND_EXTRA_LIBS='-liconv' make install wget http://pear.php.net/go-pear.phar /usr/local/webserver/php/bin/php go-pear.phar cp php.ini-production /usr/local/webserver/php/etc/php.ini mv /usr/local/webserver/php/etc/php-fpm.conf.default /usr/local/webserver/php/etc/php-fpm.conf make clean cd ../
③ 编译安装PHP扩展模块
除Pthreads扩展模块外,均与PHP5.4/5.5的方法相同,请参考上文
因为一个PHP程序如果不支持5.4/5.5版本,基本也用不到Pthreads扩展模块,跳过Pthreads的安装即可,作者推荐这样做。但考虑到特殊需求,且安装过程中会出现很多问题,讲解下PHP5.3.28如何安装Pthreads扩展:
修正PHP5.3.28的源码(否则编译安装时会出错)
vi Zend/zend_language_parser.h
将文件最下方的”int zendparse (void)”修改为
int zendparse (void *compiler_globals)
在上文PHP编译参数中增加
--enable-maintainer-zts
安装Pthreads 0.0.45(这是目前可以在PHP5.3下正常安装的最高版本)
wget http://pecl.php.net/get/pthreads-0.0.45.tgz tar zxvf pthreads-0.0.45.tgz cd pthreads-0.0.45/ /usr/local/webserver/php/bin/phpize ./configure --with-php-config=/usr/local/webserver/php/bin/php-config --enable-pthreads make make install make clean cd ../
在 /usr/local/webserver/php/etc/php.ini 中将下文修改的两处”no-debug-non-zts-20090626″替换为
no-debug-zts-20090626
并在下方加入
extension = "pthreads.so"
④ 安装Memcached
与PHP5.4/5.5的方法相同,请参考上文
⑤ 修改PHP配置文件
修改 /usr/local/webserver/php/etc/php.ini 中的以下参数
disable_functions = passthru,system,popen,proc_open,shell_exec,chroot,assert,getcwd,scandir,chgrp,chmod,chown expose_php = Off upload_max_filesize = 8M date.timezone = Asia/Shanghai session.save_handler = memcached session.save_path = "127.0.0.1:11211" extension_dir = "/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20090626"
并在下方添加
extension = "imagick.so" extension = "memcache.so" extension = "memcached.so" zend_extension = "/usr/local/webserver/php/lib/php/extensions/no-debug-non-zts-20090626/opcache.so" opcache.memory_consumption = 128 opcache.interned_strings_buffer = 8 opcache.max_accelerated_files = 4000 opcache.revalidate_freq = 60 opcache.fast_shutdown = 1 opcache.enable_cli = 1
⑥ 创建www用户和用户组
与PHP5.4/5.5的方法相同,请参考上文
⑦ 设置php-fpm
vi /usr/local/webserver/php/etc/php-fpm.conf
修改以下参数
pid = run/php-fpm.pid emergency_restart_threshold = 20 emergency_restart_interval = 60s process_control_timeout = 5s user = www group = www listen = /dev/shm/php-cgi.sock listen.backlog = -1 pm = dynamic pm.max_children = 128 pm.start_servers = 8 pm.min_spare_servers = 8 pm.max_spare_servers = 8 pm.max_requests = 16384 request_terminate_timeout = 300s catch_workers_output = yes
安装服务脚本
cp /data0/software/php-5.4.29/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
加入启动项
chkconfig --add php-fpm chkconfig php-fpm on chmod +x /etc/rc.d/init.d/php-fpm
启动php-fpm服务
service php-fpm start
[返回目录]
四、安装Tengine(Nginx)
① 安装所需的pcre库:
tar zxvf pcre-8.36.tar.gz cd pcre-8.36/ ./configure --prefix=/usr/local/pcre make make install make clean cd ../
② 编译安装Tengine
tar zxvf openssl-1.0.1g.tar.gz tar zxvf tengine-1.5.2.tar.gz cd tengine-1.5.2/ ./configure --user=www --group=www --prefix=/usr/local/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_gzip_static_module --with-pcre=/data0/software/pcre-8.36 --with-openssl=/data0/software/openssl-1.0.1g --with-http_realip_module --with-http_concat_module --with-jemalloc=/data0/software/jemalloc-3.6.0 --dso-path=/usr/local/webserver/nginx/modules make make install make clean cd ../
③ 创建站点与日志目录
mkdir -p /data0/htdocs/wwwroot chmod +w /data0/htdocs/wwwroot chown -R www:www /data0/htdocs/wwwroot mkdir -p /data0/htdocs/itwulin.com chmod +w /data0/htdocs/itwulin.com chown -R www:www /data0/htdocs/itwulin.com mkdir -p /data1/logs chmod +w /data1/logs chown -R www:www /data1/logs
④ 创建Tengine配置文件
rm -f /usr/local/webserver/nginx/conf/nginx.conf vi /usr/local/webserver/nginx/conf/nginx.conf
输入并保存以下内容:
user www www; worker_processes auto; worker_cpu_affinity auto; error_log /data1/logs/nginx_error.log crit; pid /usr/local/webserver/nginx/nginx.pid; worker_rlimit_nofile 65535; events { use epoll; worker_connections 65535; } # load modules compiled as Dynamic Shared Object (DSO) # #dso { # load ngx_http_fastcgi_module.so; # load ngx_http_rewrite_module.so; #} http { include mime.types; default_type application/octet-stream; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 8m; sendfile on; tcp_nopush on; keepalive_timeout 60; tcp_nodelay on; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; #limit_zone crawler $binary_remote_addr 10m; server_tokens off; #server_tag IIS/6.0; server { listen 80; server_name localhost; root /data0/htdocs/wwwroot; index index.html index.htm index.php; #charset gb2312; #limit_conn crawler 20; #log_format access '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" $http_x_forwarded_for'; #access_log /data1/logs/access.log access; # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # location ~ .*\.(php|php5)?$ { fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 1h; } #error_page 404 /404.html; # redirect server error pages to the static page /50x.html # #error_page 500 502 503 504 /50x.html; #location = /50x.html { # root html; #} # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { # proxy_pass http://127.0.0.1; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { # deny all; #} } server { listen 80; server_name www.itwulin.com; root /data0/htdocs/itwulin.com; index index.html index.htm index.php; #include /usr/local/webserver/nginx/conf/rewrite.conf; #charset gb2312; #limit_req_zone $binary_remote_addr zone=one:3m rate=1r/s; #limit_req_zone $binary_remote_addr $uri zone=two:3m rate=1r/s; #limit_req_zone $binary_remote_addr $request_uri zone=three:3m rate=1r/s; #limit_rate 256k; log_format itwulin-logs '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; access_log /data1/logs/itwulin-logs.log itwulin-logs; #location ~ /static/ { #concat on; #concat_max_files 20; #} location / { try_files $uri $uri/ /index.php$is_args$args; } location ~ .*\.(php|php5)?$ { try_files $uri =404; fastcgi_pass unix:/dev/shm/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(js|css)?$ { expires 1h; } location ~* \.(jpg|jpeg|gif|png|bmp|swf|rar|zip|7z)$ { valid_referers none blocked *.itwulin.com *.baidu.com *.google.com *.google.com.hk ; if ($invalid_referer) { return 412; } expires 30d; break; } } server { listen 80; server_name itwulin.com; rewrite ^/(.*)$ http://www.itwulin.com/$1 permanent; if ($host != 'www.itwulin.com' ) { rewrite ^/(.*)$ http://www.itwulin.com/$1 permanent; } } server { listen 80; server_name status.itwulin.com; location / { stub_status on; access_log off; } } # another virtual host using mix of IP-, name-, and port-based configuration # #server { # listen 8000; # listen somename:8080; # server_name somename alias another.alias; # location / { # root html; # index index.html index.htm; # } #} # HTTPS server # #server { # listen 443; # server_name localhost; # ssl on; # ssl_certificate cert.pem; # ssl_certificate_key cert.key; # ssl_session_timeout 5m; # ssl_protocols SSLv2 SSLv3 TLSv1; # ssl_ciphers HIGH:!aNULL:!MD5; # ssl_prefer_server_ciphers on; # location / { # root html; # index index.html index.htm; # } #} #ADD }
⑤ 创建Tengine服务
创建服务脚本
vi /etc/rc.d/init.d/nginx
输入以下内容
#!/bin/bash # Tengine Startup script# processname: nginx # chkconfig: - 85 15 # description: nginx is a World Wide Web server. It is used to serve # pidfile: /var/run/nginx.pid # config: /usr/local/webserver/nginx/conf/nginx.conf nginxd=/usr/local/webserver/nginx/sbin/nginx nginx_config=/usr/local/webserver/nginx/conf/nginx.conf nginx_pid=/usr/local/webserver/nginx/logs/nginx.pid RETVAL=0 prog="nginx" # Source function library. . /etc/rc.d/init.d/functions # Source networking configuration. . /etc/sysconfig/network # Check that networking is up. [ ${NETWORKING} = "no" ] && exit 0 [ -x $nginxd ] || exit 0 # Start nginx daemons functions. start() { if [ -e $nginx_pid ];then echo "tengine already running...." exit 1 fi echo -n $"Starting $prog: " daemon $nginxd -c ${nginx_config} RETVAL=$? echo [ $RETVAL = 0 ] && touch /var/lock/subsys/nginx return $RETVAL } # Stop nginx daemons functions. stop() { echo -n $"Stopping $prog: " killproc $nginxd RETVAL=$? echo [ $RETVAL = 0 ] && rm -f /var/lock/subsys/nginx /usr/local/webserver/nginx/logs/nginx.pid } reload() { echo -n $"Reloading $prog: " #kill -HUP `cat ${nginx_pid}` killproc $nginxd -HUP RETVAL=$? echo } # See how we were called. case "$1" in start) start ;; stop) stop ;; reload) reload ;; restart) stop start ;; status) status $prog RETVAL=$? ;; *) echo $"Usage: $prog {start|stop|restart|reload|status|help}" exit 1 esac exit $RETVAL
加入启动项
chkconfig --add nginx chkconfig nginx on chmod +x /etc/rc.d/init.d/nginx
启动Tengine服务
service nginx start
[返回目录]
五、Linux的设置与优化
① 配置防火墙
/sbin/iptables -I INPUT -p tcp --dport 22 -j ACCEPT /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT /etc/rc.d/init.d/iptables save service iptables restart
② 修改ulimit连接数最大值
ulimit -SHn 65535 vi /etc/profile
在最下方添加
ulimit -SHn 65535
③ 系统性能优化
vi /etc/sysctl.conf
在最下方添加
# ADD net.ipv4.tcp_max_syn_backlog = 65536 net.core.netdev_max_backlog = 32768 net.core.somaxconn = 32768 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 2 net.ipv4.tcp_syn_retries = 2 net.ipv4.tcp_tw_recycle = 1 #net.ipv4.tcp_tw_len = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_max_orphans = 3276800 #net.ipv4.tcp_fin_timeout = 30 #net.ipv4.tcp_keepalive_time = 120 net.ipv4.ip_local_port_range = 1024 65535 vm.swappiness = 10
使配置立即生效
/sbin/sysctl -p
④ 编写每天定时切割Tengine(Nginx)日志的脚本
vi /usr/local/webserver/nginx/sbin/cut_nginx_log.sh
输入以下内容
#!/bin/bash # This script run at 00:00 # The Nginx logs path logs_path="/usr/local/webserver/nginx/logs/" mkdir -p ${logs_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")/ mv ${logs_path}access.log ${logs_path}$(date -d "yesterday" +"%Y")/$(date -d "yesterday" +"%m")/access_$(date -d "yesterday" +"%Y%m%d").log kill -USR1 `cat /usr/local/webserver/nginx/nginx.pid`
保存后输入
crontab -e
输入以下内容
MAILTO="" 00 00 * * * /bin/bash /usr/local/webserver/nginx/sbin/cut_nginx_log.sh
至此,一台高性能的Web服务器配置完毕了!
本文更新记录: 2014年06月10日 → MariaDB版本由5.5.37更新至5.5.38 2014年06月26日 → PHP版本由5.4.29更新至5.4.30 2014年07月02日 → 防火墙补充22端口的开放,防止一些对LINUX不熟悉的用户开启防火墙后造成SSH无法连接 2014年07月04日 → 由于MariaDB的国内镜像挂掉,更新了下载地址 2014年07月10日 → 增加了编译libiconv出错的解决方案 2014年07月11日 → 增加了安装libiconv的步骤,防止部分应用程序调用libiconv.so.2出错 2014年07月25日 → PHP版本由5.4.30更新至5.4.31 2014年09月08日 → PHP版本由5.4.31更新至5.4.32,MariaDB版本由5.5.38更新至5.5.39 2014年10月25日 → PHP版本由5.4.32更新至5.4.34,MariaDB版本由5.5.38更新至5.5.40 2014年12月19日 → PHP版本由5.4.34更新至5.4.36 2014年12月19日 → PHP版本由5.4.34更新至5.4.36 2014年12月31日 → MariaDB版本由5.5.40更新至5.5.41,PCRE版本由8.35更新至8.36