
前言
现在很多朋友都了解或者已经在使用LNMP架构,一般可以理解为Linux Shell为CentOS/RadHat/Fedora/Debian/Ubuntu/等平台安装LNMP(Nginx/MySQL/PHP),LNMPA(Nginx/MySQL/PHP/Apache),LAMP(Apache/MySQL/PHP)等类似的开发或生产环境。我自己是从SuSE/Oracle商业化环境走出来的,对于开源的部署方案也是在一点一点摸索,我相信其中也必然包含某些坑爹的配置。这篇文章较为详细的描述了基于LTMP架构的部署过程,之后会再考虑独立各个模块分享细节和技巧,如果大家有更合适的配置实践手册欢迎一起分享,文章中的错误和改进点也请帮忙指点下哈。
LTMP(CentOS/Tengine/MySQL/PHP)
更新历史
2015年08月14日 - 更新GitHub自动部署源码和安装包
2015年08月04日 - 初稿
阅读原文 - http://wsgzao.github.io/post/ltmp/
扩展阅读
CentOS - http://www.centos.org/
Tengine - http://tengine.taobao.org/
Nginx - http://nginx.org/en/docs/
MySQL - http://www.mysql.com/
PHP - http://php.net/
LTMP索引 - http://wsgzao.github.io/index/#LTMP
LTMP版本
- CentOS_6.5_64
- Tengine-2.1.0
- MySQL_5.6.25
- PHP_5.5.27
- Apache_2.2.31(酱油)
准备工作
如果允许公网访问会方便很多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
| vi /etc/bashrc
export HISTFILESIZE=1000000000
export HISTSIZE=1000000
export PROMPT_COMMAND="history -a"
export HISTTIMEFORMAT="%Y-%m-%d_%H:%M:%S "
rm -rf /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
/etc/init.d/NetworkManager stop chkconfig NetworkManager off /etc/init.d/network restart
/etc/init.d/iptables stop chkconfig iptables off
echo "nameserver 114.114.114.114" > /etc/resolv.conf
sed 's/MAILTO=root/MAILTO=""/g' /etc/crontab service crond restart
setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
echo ulimit -SHn 65535 >> /etc/profile source /etc/profile
vi /etc/security/limits.conf * soft nproc 11000 * hard nproc 11000 * soft nofile 655350 * hard nofile 655350
sed -i -e '/# End of file/i\* soft nofile 65535\n* hard nofile 65535' /etc/security/limits.conf
vi /etc/sysctl.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 131072 1048576
net.ipv4.tcp_wmem = 4096 131072 1048576
net.core.wmem_default = 8388608
net.core.wmem_max = 16777216
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 2048 65000
fs.file-max = 102400
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
net.bridge.bridge-nf-call-ip6tables = 0 net.bridge.bridge-nf-call-iptables = 0 net.bridge.bridge-nf-call-arptables = 0
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.netfilter.nf_conntrack_max = 1000000 kernel.unknown_nmi_panic = 0 kernel.sysrq = 0 fs.file-max = 1000000 vm.swappiness = 10 fs.inotify.max_user_watches = 10000000 net.core.wmem_max = 327679 net.core.rmem_max = 327679 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0
/sbin/sysctl -p
yum -y install yum-fastestmirror
yum remove httpd mysql mysql-server php php-cli php-common php-devel php-gd -y
yum install -y wget gcc gcc-c++ openssl* curl curl-devel libxml2 libxml2-devel glibc glibc-devel glib2 glib2-devel gd gd2 gd-devel gd2-devel libaio autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel
阿里:http://mirrors.aliyun.com/ 搜狐:http://mirrors.sohu.com/ 网易:http://mirrors.163.com/
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
yum makecache
yum -y install tar zip unzip openssl* gd gd-devel 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 openldap-clients openldap-servers make libmcrypt libmcrypt-devel fontconfig fontconfig-devel libXpm* libtool* libxml2 libxml2-devel t1lib t1lib-devel
mkdir -p /app/{local,data} cd /app/local
wget "ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.37.tar.gz"
wget "http://tengine.taobao.org/download/tengine-2.1.0.tar.gz"
wget "https://downloads.mariadb.com/archives/mysql-5.6/mysql-5.6.25-linux-glibc2.5-x86_64.tar.gz"
wget "http://cn2.php.net/distributions/php-5.6.11.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"
|
配置Tengine
安装PCRE
1 2 3 4 5
| tar zxvf pcre-8.37.tar.gz cd pcre-8.37 ./configure make && make install cd ../
|
安装Tengine
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| groupadd www useradd -g www www
tar zxvf tengine-2.1.0.tar.gz cd tengine-2.1.0
./configure --user=www --group=www \ --prefix=/app/local/nginx \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-pcre=/app/local/pcre-8.37
make && make install cd ../
|
配置Nginx
Nginx配置文件的优化很重要,理解每一步的意义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| vi /app/local/nginx/conf/nginx.conf
user www www;
worker_processes auto; worker_cpu_affinity auto;
error_log logs/error.log error;
pid logs/nginx.pid;
worker_rlimit_nofile 65535;
events{ use epoll; multi_accept on; worker_connections 65536; }
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 off;
gzip on; gzip_disable "MSIE [1-6]\."; gzip_vary on; gzip_proxied any; gzip_comp_level 4; gzip_min_length 1k; gzip_buffers 16 64k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
open_file_cache max=200000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on; client_max_body_size 30M; client_body_timeout 10; client_header_timeout 10; client_header_buffer_size 32k; keepalive_timeout 60; reset_timedout_connection on; send_timeout 10; sendfile on; tcp_nopush on; tcp_nodelay on; limit_conn_zone $binary_remote_addr zone=addr:5m; limit_conn addr 100; fastcgi_buffers 256 16k; fastcgi_buffer_size 128k; fastcgi_connect_timeout 3s; fastcgi_send_timeout 120s; fastcgi_read_timeout 120s; server_names_hash_bucket_size 128; log_not_found off; server_tokens off; server_tag off; server_info off;
include vhosts/*.conf;
server { listen 80; server_name localhost; index index.html index.htm index.php; root /app/data/localhost/; error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } location ~ .*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 1h; } location ~ /\. { deny all; } } }
|
简化配置文件
vi /app/local/nginx/conf/nginx.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| user www www; worker_processes auto; worker_cpu_affinity auto;
error_log logs/error.log crit; pid logs/nginx.pid;
worker_rlimit_nofile 51200; events { use epoll; multi_accept on; worker_connections 51200; }
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 off;
server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 50M;
sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60; server_tokens off; server_tag off; server_info off;
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 256k;
include vhosts/*.conf; }
|
分离server写入vhosts
mkdir -p /app/local/nginx/conf/vhosts/
vi /app/local/nginx/conf/vhosts/localhost.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| server { listen 80; server_name localhost; index index.php index.html index.htm; access_log logs/localhost.log main;
root /app/data/localhost/;
location / { index index.php index.html index.htm; }
location = /50x.html { root html; }
location ~ .*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; }
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|ico)$ { expires 30d; }
location ~ .*\.(js|css)?$ { expires 1h; }
location ~ /\. { deny all; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| /app/local/nginx/sbin/nginx -t
the configuration file /app/local/nginx/conf/nginx.conf syntax is ok configuration file /app/local/nginx/conf/nginx.conf test is successful
mkdir -p /app/data/localhost chmod +w /app/data/localhost echo "<?php phpinfo();?>" > /app/data/localhost/phpinfo.php chown -R www:www /app/data/localhost
echo 'export PATH=$PATH:/app/local/nginx/sbin'>>/etc/profile && source /etc/profile
curl -I http://localhost
HTTP/1.1 200 OK Server: Tengine/2.1.0 Date: Mon, 27 Jul 2015 06:42:25 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive X-Powered-By: PHP/5.6.11
|
添加Tengine到服务
配置服务后便于统一管理
vi /etc/rc.d/init.d/nginx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #!/bin/sh
. /etc/rc.d/init.d/functions
. /etc/sysconfig/network
[ "$NETWORKING" = "no" ] && exit 0 nginx="/app/local/nginx/sbin/nginx" prog=$(basename $nginx) NGINX_CONF_FILE="/app/local/nginx/conf/nginx.conf" [ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx lockfile=/var/lock/subsys/nginx make_dirs() { user=`$nginx -V 2>&1 | grep "configure arguments:" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -` if [ -z "`grep $user /etc/passwd`" ]; then useradd -M -s /bin/nologin $user fi options=`$nginx -V 2>&1 | grep 'configure arguments:'` for opt in $options; do if [ `echo $opt | grep '.*-temp-path'` ]; then value=`echo $opt | cut -d "=" -f 2` if [ ! -d "$value" ]; then mkdir -p $value && chown -R $user $value fi fi done } start() { [ -x $nginx ] || exit 5 [ -f $NGINX_CONF_FILE ] || exit 6 make_dirs echo -n $"Starting $prog: " daemon $nginx -c $NGINX_CONF_FILE retval=$? echo [ $retval -eq 0 ] && touch $lockfile return $retval } stop() { echo -n $"Stopping $prog: " killproc $prog -QUIT retval=$? echo [ $retval -eq 0 ] && rm -f $lockfile return $retval } restart() { configtest || return $? stop sleep 1 start } reload() { configtest || return $? echo -n $"Reloading $prog: " killproc $nginx -HUP RETVAL=$? echo } force_reload() { restart } configtest() { $nginx -t -c $NGINX_CONF_FILE } rh_status() { status $prog } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) rh_status_q && exit 0 $1 ;; stop) rh_status_q || exit 0 $1 ;; restart|configtest) $1 ;; reload) rh_status_q || exit 7 $1 ;; force-reload) force_reload ;; status) rh_status ;; condrestart|try-restart) rh_status_q || exit 0 ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}" exit 2 esac
|
1 2 3 4
| chmod +x /etc/init.d/nginx ulimit -SHn 65535 service nginx start
|
安装MySQL
注意目录和字符集等配置文件,推荐使用InnoDB作为存储引擎
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| mkdir -p /app/local/mysql tar zxvf mysql-5.6.25-linux-glibc2.5-x86_64.tar.gz mv mysql-5.6.25-linux-glibc2.5-x86_64/* /app/local/mysql
groupadd mysql useradd -g mysql mysql mkdir -p /app/data/mysql/data/ mkdir -p /app/data/mysql/binlog/ mkdir -p /app/data/mysql/relaylog/ chown -R mysql:mysql /app/data/mysql/ /app/local/mysql/scripts/mysql_install_db --basedir=/app/local/mysql --datadir=/app/data/mysql/data --user=mysql
sed -i "s#/usr/local/mysql#/app/local/mysql#g" /app/local/mysql/bin/mysqld_safe
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
vi /app/local/mysql/my.cnf
[client] character-set-server = utf8 port = 3306 socket = /tmp/mysql.sock
[mysql]
prompt="\u@\h \R:\m:\s [\d]> "
no-auto-rehash
[mysqld]
server-id = 1 port = 3306 user = mysql basedir = /app/local/mysql datadir = /app/data/mysql/data socket = /tmp/mysql.sock log-error = /app/data/mysql/mysql_error.log pid-file = /app/data/mysql/mysql.pid sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
default-storage-engine = InnoDB
max_connections = 512
max_connect_errors = 100000
table_open_cache = 512
external-locking = FALSE
max_allowed_packet = 32M
slow_query_log = 1 slow_query_log_file = /app/data/mysql/slow.log
open_files_limit = 10240
back_log = 600
sort_buffer_size = 16M join_buffer_size = 16M read_buffer_size = 16M read_rnd_buffer_size = 16M
thread_cache_size = 300
query_cache_size = 128M
query_cache_limit = 4M
query_cache_min_res_unit = 2k
thread_stack = 512K
transaction_isolation = READ-COMMITTED
tmp_table_size = 256M
max_heap_table_size = 256M
long_query_time = 3
log-slave-updates
log-bin = /app/data/mysql/binlog/binlog sync_binlog = 1
binlog_cache_size = 4M
binlog_format = MIXED
max_binlog_cache_size = 8M
max_binlog_size = 1G
relay-log-index = /app/data/mysql/relaylog/relaylog relay-log-info-file = /app/data/mysql/relaylog/relaylog relay-log = /app/data/mysql/relaylog/relaylog
expire_logs_days = 7
key_buffer_size = 128M
read_rnd_buffer_size = 64M
bulk_insert_buffer_size = 256M
myisam_sort_buffer_size = 256M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 4G
innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 64M
innodb_log_file_size = 256M
innodb_log_files_in_group = 2
innodb_max_dirty_pages_pct = 90
innodb_file_per_table = 1
innodb_locks_unsafe_for_binlog = 0
interactive_timeout = 120 wait_timeout = 120
skip-name-resolve
slave-skip-errors = 1032,1062,126,1114,1146,1048,1396
[mysqldump]
quick max_allowed_packet = 32M
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331
|
vi /etc/rc.d/init.d/mysqld
#!/bin/sh basedir=/app/local/mysql datadir=/app/data/mysql/data service_startup_timeout=900 lockdir='/var/lock/subsys' lock_file_path="$lockdir/mysql" mysqld_pid_file_path=/app/data/mysql/mysql.pid if test -z "$basedir" then basedir=/usr/local/mysql bindir=/usr/local/mysql/bin if test -z "$datadir" then datadir=/usr/local/mysql/data fi sbindir=/usr/local/mysql/bin libexecdir=/usr/local/mysql/bin else bindir="$basedir/bin" if test -z "$datadir" then datadir="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" fi datadir_set= lsb_functions="/lib/lsb/init-functions" if test -f $lsb_functions ; then . $lsb_functions else log_success_msg() { echo " SUCCESS! $@" } log_failure_msg() { echo " ERROR! $@" } fi PATH="/sbin:/usr/sbin:/bin:/usr/bin:$basedir/bin" export PATH mode=$1 [ $# -ge 1 ] && shift other_args="$*" case `echo "testing\c"`,`echo -n testing` in *c*,-n*) echo_n= echo_c= ;; *c*,*) echo_n=-n echo_c= ;; *) echo_n= echo_c='\c' ;; esac parse_server_arguments() { for arg do case "$arg" in --basedir=*) basedir=`echo "$arg" | sed -e 's/^[^=]*=//'` bindir="$basedir/bin" if test -z "$datadir_set"; then datadir="$basedir/data" fi sbindir="$basedir/sbin" libexecdir="$basedir/libexec" ;; --datadir=*) datadir=`echo "$arg" | sed -e 's/^[^=]*=//'` datadir_set=1 ;; --pid-file=*) mysqld_pid_file_path=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; --service-startup-timeout=*) service_startup_timeout=`echo "$arg" | sed -e 's/^[^=]*=//'` ;; esac done } wait_for_pid () { verb="$1" pid="$2" pid_file_path="$3" i=0 avoid_race_condition="by checking again" while test $i -ne $service_startup_timeout ; do case "$verb" in 'created') test -s "$pid_file_path" && i='' && break ;; 'removed') test ! -s "$pid_file_path" && i='' && break ;; *) echo "wait_for_pid () usage: wait_for_pid created|removed pid pid_file_path" exit 1 ;; esac if test -n "$pid"; then if kill -0 "$pid" 2>/dev/null; then : else if test -n "$avoid_race_condition"; then avoid_race_condition="" continue fi log_failure_msg "The server quit without updating PID file ($pid_file_path)." return 1 fi fi echo $echo_n ".$echo_c" i=`expr $i + 1` sleep 1 done if test -z "$i" ; then log_success_msg return 0 else log_failure_msg return 1 fi }
if test -x ./bin/my_print_defaults then print_defaults="./bin/my_print_defaults" elif test -x $bindir/my_print_defaults then print_defaults="$bindir/my_print_defaults" elif test -x $bindir/mysql_print_defaults then print_defaults="$bindir/mysql_print_defaults" else conf=/etc/my.cnf print_defaults= if test -r $conf then subpat='^[^=]*basedir[^=]*=\(.*\)$' dirs=`sed -e "/$subpat/!d" -e 's//\1/' $conf` for d in $dirs do d=`echo $d | sed -e 's/[ ]//g'` if test -x "$d/bin/my_print_defaults" then print_defaults="$d/bin/my_print_defaults" break fi if test -x "$d/bin/mysql_print_defaults" then print_defaults="$d/bin/mysql_print_defaults" break fi done fi test -z "$print_defaults" && print_defaults="my_print_defaults" fi
extra_args="" if test -r "$basedir/my.cnf" then extra_args="-e $basedir/my.cnf" else if test -r "$datadir/my.cnf" then extra_args="-e $datadir/my.cnf" fi fi parse_server_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
if test -z "$mysqld_pid_file_path" then mysqld_pid_file_path=$datadir/`hostname`.pid else case "$mysqld_pid_file_path" in /* ) ;; * ) mysqld_pid_file_path="$datadir/$mysqld_pid_file_path" ;; esac fi case "$mode" in 'start') cd $basedir echo $echo_n "Starting MySQL" if test -x $bindir/mysqld_safe then $bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" $other_args >/dev/null 2>&1 & wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$? if test -w "$lockdir" then touch "$lock_file_path" fi exit $return_value else log_failure_msg "Couldn't find MySQL server ($bindir/mysqld_safe)" fi ;; 'stop') if test -s "$mysqld_pid_file_path" then mysqld_pid=`cat "$mysqld_pid_file_path"` if (kill -0 $mysqld_pid 2>/dev/null) then echo $echo_n "Shutting down MySQL" kill $mysqld_pid wait_for_pid removed "$mysqld_pid" "$mysqld_pid_file_path"; return_value=$? else log_failure_msg "MySQL server process #$mysqld_pid is not running!" rm "$mysqld_pid_file_path" fi if test -f "$lock_file_path" then rm -f "$lock_file_path" fi exit $return_value else log_failure_msg "MySQL server PID file could not be found!" fi ;; 'restart') if $0 stop $other_args; then $0 start $other_args else log_failure_msg "Failed to stop running server, so refusing to try to start." exit 1 fi ;; 'reload'|'force-reload') if test -s "$mysqld_pid_file_path" ; then read mysqld_pid < "$mysqld_pid_file_path" kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL" touch "$mysqld_pid_file_path" else log_failure_msg "MySQL PID file could not be found!" exit 1 fi ;; 'status') if test -s "$mysqld_pid_file_path" ; then read mysqld_pid < "$mysqld_pid_file_path" if kill -0 $mysqld_pid 2>/dev/null ; then log_success_msg "MySQL running ($mysqld_pid)" exit 0 else log_failure_msg "MySQL is not running, but PID file exists" exit 1 fi else mysqld_pid=`pidof $libexecdir/mysqld` pid_count=`echo $mysqld_pid | wc -w` if test $pid_count -gt 1 ; then log_failure_msg "Multiple MySQL running but PID file could not be found ($mysqld_pid)" exit 5 elif test -z $mysqld_pid ; then if test -f "$lock_file_path" ; then log_failure_msg "MySQL is not running, but lock file ($lock_file_path) exists" exit 2 fi log_failure_msg "MySQL is not running" exit 3 else log_failure_msg "MySQL is running but PID file could not be found" exit 4 fi fi ;; *) basename=`basename "$0"` echo "Usage: $basename {start|stop|restart|reload|force-reload|status} [ MySQL server options ]" exit 1 ;; esac exit 0
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| chmod +x /etc/init.d/mysqld service mysqld start
echo 'export PATH=$PATH:/app/local/mysql/bin'>>/etc/profile && source /etc/profile
tail -f /var/log/mysqld.log
/app/local/mysql/bin/mysql -uroot -p 直接回车空密码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| #进入数据库 use mysql; #设置root密码 UPDATE mysql.user SET Password=password('root') WHERE User='root'; #清除root密码 update user set password='' where user='root'; #删除无名用户 DELETE FROM mysql.user WHERE User=''; #删除root远程访问(可选) #DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1'); #删除“test”数据库 DROP database test; #允许远程访问 update user set host='%' where user='root' AND host='localhost'; #查看所有用户权限 SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user; #立即生效并退出MYSQL命令窗体 FLUSH PRIVILEGES;QUIT;
#创建数据库 create database ooxx; #创建用户 create user ooxx@'%' identified by 'ooxx'; #对用户授权 grant all privileges on ooxx.* to ooxx; #刷新MySQL的系统权限相关表 flush privileges; #查看所有用户权限 SELECT DISTINCT CONCAT('User: ''',user,'''@''',host,''';') AS query FROM mysql.user;
|
安装Apache
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| cd /app/local tar zxvf httpd-2.2.29.tar.gz cd httpd-2.2.29
./configure --prefix=/app/local/apache \ --enable-so \ --enable-rewrite \ --enable-modes-shared=most
make && make install
vi /app/local/apache/conf/httpd.conf
ServerName localhost:80
AddType application/x-httpd-php .php
DirectoryIndex index.html index.htm index.php
/app/local/apache/bin/apachectl -t cp /app/local/apache/bin/apachectl /etc/init.d/httpd
|
安装PHP
PHP基础环境
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| yum install libmcrypt libmcrypt-devel mcrypt mhash
http://sourceforge.net/projects/mcrypt/files/Libmcrypt/ http://sourceforge.net/projects/mcrypt/files/MCrypt/ http://sourceforge.net/projects/mhash/files/mhash/
tar -zxvf libmcrypt-2.5.8.tar.gz cd libmcrypt-2.5.8 ./configure make && make install cd ../
3.安装mhash
tar -zxvf mhash-0.9.9.9.tar.gz cd mhash-0.9.9.9 ./configure make && make install cd ../
4.安装mcrypt
tar -zxvf mcrypt-2.6.8.tar.gz cd mcrypt-2.6.8 LD_LIBRARY_PATH=/usr/local/lib ./configure make && make install cd ../
>extension按需定制,支持phpize动态增加,新增的OPcache建议酌情开启
``` bash tar zxvf php-5.5.27.tar.gz cd php-5.5.27
./configure --prefix=/app/local/php \ --with-config-file-path=/app/local/php/etc \ --enable-fpm \ --enable-mbstring \ --with-mhash \ --with-mcrypt \ --with-curl \ --with-openssl \ --with-mysql=mysqlnd \ --with-mysqli=mysqlnd \ --with-pdo-mysql=mysqlnd \ --with-apxs2=/app/local/apache/bin/apxs
make && make install
cp php.ini-development /app/local/php/etc/php.ini
sed -i "s#;date.timezone =#date.timezone = Asia/Shanghai#g" /app/local/php/etc/php.ini
sed -i "s#;cgi.fix_pathinfo=1#cgi.fix_pathinfo=0#g" /app/local/php/etc/php.ini
sed -i "s#expose_php = On#expose_php = Off#g" /app/local/php/etc/php.ini
[OPcache] zend_extension = opcache.so opcache.enable=1 opcache.memory_consumption=128 opcache.interned_strings_buffer=8 opcache.max_accelerated_files=4000 opcache.revalidate_freq=1 opcache.fast_shutdown=1 opcache.enable_cli=1
|
配置php-fpm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| cp /app/local/php/etc/php-fpm.conf.default /app/local/php/etc/php-fpm.conf vi /app/local/php/etc/php-fpm.conf
[global] ;错误日志 error_log = log/php-fpm.log ;错误日志级别 log_level = notice [www] ;php-fpm监听端口 listen = 127.0.0.1:9000 ;启动进程的帐户和组 user = www group = www ;如果选择static,则由pm.max_children指定固定的子进程数。如果选择dynamic,则由后面3个参数动态决定 pm = dynamic ;子进程最大数 pm.max_children = 384 ;启动时的进程数 pm.start_servers = 20 ;保证空闲进程数最小值,如果空闲进程小于此值,则创建新的子进程 pm.min_spare_servers = 5 ;保证空闲进程数最大值,如果空闲进程大于此值,此进行清理 pm.max_spare_servers = 35
;设置每个子进程重生之前服务的请求数。对于可能存在内存泄漏的第三方模块来说是非常有用的。如果设置为 '0' 则一直接受请求。等同于 PHP_FCGI_MAX_REQUESTS 环境变量。默认值: 0。 pm.max_requests = 1000 ;每个子进程闲置多长时间就自杀 pm.process_idle_timeout = 10s ;设置单个请求的超时中止时间。该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用。设置为 '0' 表示 'Off'.当经常出现502错误时可以尝试更改此选项。 request_terminate_timeout = 120 ;当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中。设置为 '0' 表示 'Off' request_slowlog_timeout = 3s ;慢请求的记录日志,配合request_slowlog_timeout使用 slowlog = /app/local/php/var/log/php-fpm.slow.log ;设置文件打开描述符的rlimit限制。默认值: 系统定义值默认可打开句柄是1024,可使用 ulimit -n查看,ulimit -n 2048修改。 rlimit_files = 65535
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
echo 'export PATH=$PATH:/app/local/php/bin'>>/etc/profile && source /etc/profile touch /app/local/php/var/log/php-fpm.slow.log
cp /app/local/php-5.5.27/sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm chmod +x /etc/rc.d/init.d/php-fpm service php-fpm start
vi /etc/rc.local
ulimit -SHn 65535 service php-fpm start service nginx start service mysqld start
|
配置memcache/mongo/redis
其它extension扩展都可以动态添加,没事的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| cd /app/local tar zxvf memcache-3.0.8.tgz cd memcache-3.0.8 /app/local/php/bin/phpize ./configure --enable-memcache \ --with-php-config=/app/local/php/bin/php-config \ --with-zlib-dir make && make install
cd /app/local tar zxvf mongo-1.6.10.tgz cd mongo-1.6.10 /app/local/php/bin/phpize ./configure --with-php-config=/app/local/php/bin/php-config make && make install
cd /app/local tar zxvf redis-2.2.7.tgz cd redis-2.2.7 /app/local/php/bin/phpize ./configure --with-php-config=/app/local/php/bin/php-config make && make install
vi /app/local/php/etc/php.ini
[memcached] extension=memcached.so [mongodb] extension=mongo.so [redis] extension=redis.so
service php-fpm restart php -i | grep php.ini php -m
|
自动化部署
服务器的上传目录可以自定义,安装目录默认统一修改为/app/{local,data},执行脚本为web.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
#!/bin/bash
ltmp_local=$(cd "$(dirname "$0")"; pwd) mkdir -p /app/{local,data} unalias cp ltmp_init=$ltmp_local/init/ ltmp_src=$ltmp_local/src/
cp ${ltmp_init}bashrc /etc/
rm -rf /etc/localtime ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
sed 's/MAILTO=root/MAILTO=""/g' /etc/crontab service crond restart
setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
echo ulimit -SHn 65535 >> /etc/profile source /etc/profile cp ${ltmp_init}limits.conf /etc/security/
cp ${ltmp_init}sysctl.conf /etc/
yum -y install yum-fastestmirror yum remove httpd mysql mysql-server php php-cli php-common php-devel php-gd -y yum install -y wget gcc gcc-c++ openssl* curl curl-devel libxml2 libxml2-devel glibc glibc-devel glib2 glib2-devel gd gd2 gd-devel gd2-devel libaio autoconf libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel
cd /app/local
cd $ltmp_local
tar zxvf pcre-8.37.tar.gz 1> /dev/null cd pcre-8.37 ./configure make && make install cd ../
groupadd www useradd -g www www
cd $ltmp_local tar zxvf tengine-2.1.0.tar.gz 1> /dev/null cd tengine-2.1.0 ./configure --user=www --group=www \ --prefix=/app/local/nginx \ --with-http_stub_status_module \ --with-http_ssl_module \ --with-pcre=${ltmp_local}/pcre-8.37 make && make install cd ../
cd $ltmp_local cp ${ltmp_init}nginx.conf /app/local/nginx/conf/ cp -r ${ltmp_init}vhosts /app/local/nginx/conf/ mkdir -p /app/data/localhost chmod +w /app/data/localhost echo "<?php phpinfo();?>" > /app/data/localhost/phpinfo.php chown -R www:www /app/data/localhost echo 'export PATH=$PATH:/app/local/nginx/sbin'>>/etc/profile && source /etc/profile cp ${ltmp_init}nginx /etc/rc.d/init.d/ chmod +x /etc/init.d/nginx ulimit -SHn 65535 service nginx start
cd $ltmp_src tar -zxvf libmcrypt-2.5.8.tar.gz 1> /dev/null cd libmcrypt-2.5.8 ./configure make && make install cd ../
cd $ltmp_src tar -zxvf mhash-0.9.9.9.tar.gz 1> /dev/null cd mhash-0.9.9.9 ./configure make && make install cd ../
cd $ltmp_src tar -zxvf mcrypt-2.6.8.tar.gz 1> /dev/null cd mcrypt-2.6.8 LD_LIBRARY_PATH=/usr/local/lib ./configure make && make install cd ../
cd $ltmp_local tar zxvf php-5.5.27.tar.gz 1> /dev/null cd php-5.5.27 ./configure --prefix=/app/local/php \ --with-config-file-path=/app/local/php/etc \ --enable-fpm \ --enable-mbstring \ --with-mhash \ --with-mcrypt \ --with-curl \ --with-openssl \ --with-mysql=mysqlnd \ --with-mysqli=mysqlnd \ --with-pdo-mysql=mysqlnd make && make install
cd $ltmp_src tar zxvf memcache-3.0.8.tgz 1> /dev/null cd memcache-3.0.8 /app/local/php/bin/phpize ./configure --enable-memcache \ --with-php-config=/app/local/php/bin/php-config \ --with-zlib-dir make && make install
cd $ltmp_src tar zxvf mongo-1.6.10.tgz 1> /dev/null cd mongo-1.6.10 /app/local/php/bin/phpize ./configure --with-php-config=/app/local/php/bin/php-config make && make install
cd $ltmp_src
tar zxvf redis-2.2.7.tgz 1> /dev/null cd redis-2.2.7 /app/local/php/bin/phpize ./configure --with-php-config=/app/local/php/bin/php-config make && make install
cp ${ltmp_init}php.ini /app/local/php/etc/ cp ${ltmp_init}php-fpm.conf /app/local/php/etc/ echo 'export PATH=$PATH:/app/local/php/bin'>>/etc/profile && source /etc/profile touch /app/local/php/var/log/php-fpm.slow.log cp ${ltmp_local}/php-5.5.27/sapi/fpm/init.d.php-fpm /etc/rc.d/init.d/php-fpm chmod +x /etc/rc.d/init.d/php-fpm service php-fpm start
|
GitHub源码仓库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| file://E:\QQDownload\LTMP (2 folders, 5 files, 27.66 MB, 30.76 MB in total.) │ httpd-2.2.29.tar.gz 7.19 MB │ pcre-8.37.tar.gz 1.95 MB │ php-5.5.27.tar.gz 16.95 MB │ tengine-2.1.0.tar.gz 1.58 MB │ web.sh 4.10 KB ├─init (1 folders, 12 files, 91.42 KB, 92.23 KB in total.) │ │ allow.conf 35 bytes │ │ bashrc 2.99 KB │ │ deny.conf 35 bytes │ │ limits.conf 1.86 KB │ │ my.cnf 1.99 KB │ │ mysqld 8.39 KB │ │ nginx 2.22 KB │ │ nginx.conf 1.34 KB │ │ php-fpm 2.30 KB │ │ php-fpm.conf 416 bytes │ │ php.ini 67.83 KB │ │ sysctl.conf 2.03 KB │ └─vhosts (0 folders, 1 files, 826 bytes, 826 bytes in total.) │ localhost.conf 826 bytes └─src (0 folders, 6 files, 3.01 MB, 3.01 MB in total.) libmcrypt-2.5.8.tar.gz 1.27 MB mcrypt-2.6.8.tar.gz 460.85 KB memcache-3.0.8.tgz 68.87 KB mhash-0.9.9.9.tar.gz 909.61 KB mongo-1.6.10.tgz 204.19 KB redis-2.2.7.tgz 131.19 KB
|
LTMP - https://github.com/wsgzao/LTMP