LAM(M)P:
L: linux
A: apache (httpd)
M: mysql, mariadb M:memcached
P: php, perl, python

先介绍下在centos7中快速安装:

#php为httpd的扩展安装
yum install httpd, php, php-mysql, mariadb-server
systemctl start httpd.service
systemctl start mariadb.service

#php-fpm安装
yum -y install httpd mariadb-server php-fpm php-mysql
systemctl start httpd
systemctl start mariadb
systemctl start php-fpm

httpd-2.4介绍

配置文件

/etc/httpd/conf/httpd.conf
/etc/httpd/conf.d/.conf
模块相关的配置文件:/etc/httpd/conf.modules.d/
.conf

启动脚本

/usr/lib/systemd/system/httpd.service #脚本位置
systemctl enable|disable httpd.service #开机启动
systemctl {start|stop|restart|status} httpd.service #脚本控制

日志文件

/var/log/httpd/access_log:访问日志
/var/log/httpd/error_log:错误日志

MPM:Multipath processing Modules (多路处理模块)

1、prefork:多进程模型,每个进程响应一个请求;

  • 一个主进程:负责生成子进程及回收子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
  • n个子进程:每个子进程处理一个请求;
  • 工作模型:会预先生成几个空闲进程,随时等待用于响应用户请求;最大空闲和最小空闲;
    2、worker:多进程多线程模型,每线程处理一个用户请求;
  • 一个主进程:负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
  • 多个子进程:每个子进程负责生成多个线程;
  • 每个线程:负责响应用户请求;
  • 并发响应数量:m*n
    3、 event:事件驱动模型,多进程模型,每个进程响应多个请求; http2.4 event可以在生产上使用,但是prefork更加稳定
  • 一个主进程 :负责生成子进程;负责创建套接字;负责接收请求,并将其派发给某子进程进行处理;
  • 子进程:基于事件驱动机制直接响应多个请求;

httpd2.4 配置介绍

1、配置前言

主配置文件的最后一行引入 IncludeOptional conf.d/*.conf,所以私有设置尽量放着这个目录下,方便移除

语法测试
[root@ns1 conf.d]# httpd -t
#重启
[root@ns1 www]# systemctl restart httpd
#重载
[root@ns1 www]# systemctl reload httpd

2、端口设置

#默认端口在主配置文件上  端口添加不是覆盖  可重复使用
[root@ns1 conf.d]# vim /etc/httpd/conf.d/port.conf
Listen 8080
Listen 172.16.86.162:8081

lamp快速搭建_第1张图片
lamp快速搭建_第2张图片

3、长链接

KeepAlive 的值要根据网站的资源,跟请求时间得出一个合理值。 长时间占用会影响并发,tcp握手断开次数过多会增加服务器压力,对于web网站是一个很重要的优化值

KeepAlive  On|Off     
KeepAliveTimeout  15       #超时时间 默认秒   2.2版本只能到秒   2.4版本可以到毫秒  15ms
MaxKeepAliveRequests  100  #最大请求资源个数         时间跟数量哪个先到达就先断开
-----------------------------------------------------------
[root@ns1 conf.d]# vim /etc/httpd/conf.d/keepalive.conf
KeepAlive  On
KeepAliveTimeout  15
MaxKeepAliveRequests  100
-----------------------------------------------------------
#测试  
#如果off 请求完毕立马结束  
#如果on  请求完毕后等待时间 或者资源数到最大值后退出
[root@ns1 conf.d]# telnet 192.168.1.102 80
Trying 192.168.1.102...
Connected to 192.168.1.102.
Escape character is '^]'.
GET /index.html HTTP/1.1
Host:192.168.1.102

lamp快速搭建_第3张图片

4、MPM ab

#static静态编译模块无法任意卸载加载,固定的
#shared动态编译模块可以任意加载卸载,配置很方便

#静态编译模块说明
[root@node1 conf]# httpd  -l
Compiled in modules:
  core.c
  prefork.c
  http_core.c
  mod_so.c

#动态编译和静态编译
[root@node1 conf]# httpd -M
httpd: apr_sockaddr_info_get() failed for node1.marvin.com  #httpd 不认识node1.marvin.com
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName   # 这个是因为ServerName 完全限定名称没能得到反解  
Loaded Modules:
 core_module (static)
 auth_basic_module (shared)
2.4的静态资源
[root@ns1 ~]# httpd -l   #只有httpd一个
Compiled in modules:
  core.c
  mod_so.c
  http_core.c

查看当前加载模块
[root@ns1 conf.d]# httpd -M|egrep '(event|worker|prefor)'
 mpm_event_module (shared)

/_______________________________________________________
#配置选项
[root@ns1 conf.d]# vim /etc/httpd/conf.modules.d/00-mpm.conf
LoadModule mpm_worker_module modules/mod_mpm_worker.so

StartServers       8        服务启动后立即创建多少子进程
MinSpareServers    5        最小空闲子进程
MaxSpareServers   20        最大空闲子进程
ServerLimit      256        同时在生命周期内活动状态的最大子进程        这个值 ServerLimit <= MaxClients
MaxClients       256        最大启动子进程                           如果最大子进程256  这里包含活动的 和 非活动的 
MaxRequestsPerChild  4000   一个子进程最多能接4000次请求



StartServers         4      服务启动后立即创建多少子进程
MaxClients         300      每个子进程创建最大的线程数
MinSpareThreads     25      一共最小空闲线程
MaxSpareThreads     75      一共最大空闲线程
ThreadsPerChild     25      每个子进程启动后创建25个线程     默认配置 25*4  超出 75 然后在杀死一个进程
MaxRequestsPerChild  0      单个进程最大响应多少次  0不限制


   官方说配置跟worker一样   event工作模式是每个进程能响应很大请求
StartServers         4        服务启动后立即创建多少子进程   最大个数跟cpu一样   
MaxClients         300      
MinSpareThreads     25      
MaxSpareThreads     75      
ThreadsPerChild     25      
MaxRequestsPerChild  0      


[root@ns1 conf.d]# systemctl restart httpd
[root@ns1 conf.d]# httpd -M|egrep '(event|worker|prefor)'
 mpm_worker_module (shared)
测压

mpm_prefork_module测压

 1、测压mpm_prefork_module

marvindeMacBook-Pro:65 marvin$  ab -c 1000 -n 10000 http://192.168.1.102/manual/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.102 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        Apache/2.4.6
Server Hostname:        192.168.1.102
Server Port:            80

Document Path:          /manual/
Document Length:        8881 bytes                                        #(供测试的URL返回的文档大小)

Concurrency Level:      1000                                              #并发  1000  请求10000次
Time taken for tests:   4.300 seconds                                     #耗时
Complete requests:      10000                                             #总次数
Failed requests:        0                                                 #失败次数
Total transferred:      91450000 bytes                                    #报文首部(传输的总数据量)
HTML transferred:       88810000 bytes                                    #body(HTML文档的总数据量)
Requests per second:    2325.48 [#/sec] (mean)                            #(平均每秒的请求数) 这个是非常重要的参数数值,服务器的吞吐量 
Time per request:       430.019 [ms] (mean)                               #(所有并发用户(这里是1000)都请求一次的平均时间)
Time per request:       0.430 [ms] (mean, across all concurrent requests) #(单个用户都请求一次的平均时间)
Transfer rate:          20768.06 [Kbytes/sec] received                    #每秒获取的数据长度 (传输速率,单位:KB/s)  实际生产中这个带宽要  160Mbps

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   29  44.2     11     423                                #链接
Processing:    15  241 642.9     46    4212                                #处理请求
Waiting:       10  235 643.5     40    4211                                #发送报文等待时间
Total:         22  270 648.1     61    4247                                #最后一行是一个报文的最小 平均 中间 最大值  

Percentage of the requests served within a certain time (ms)
  50%     61
  66%    152
  75%    205
  80%    215
  90%    397
  95%   1387
  98%   2448
  99%   4239
 100%   4247 (longest request)    #95%在合理时间内的话,有时候5%是可以牺牲下的

mpm_worker_module

 marvindeMacBook-Pro:65 marvin$  ab -c 1000 -n 10000 http://192.168.1.102/manual/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.102 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        Apache/2.4.6
Server Hostname:        192.168.1.102
Server Port:            80

Document Path:          /manual/
Document Length:        8881 bytes

Concurrency Level:      1000
Time taken for tests:   4.313 seconds
Complete requests:      10000
Failed requests:        13
   (Connect: 0, Receive: 0, Length: 13, Exceptions: 0)
Total transferred:      91417995 bytes
HTML transferred:       88778259 bytes
Requests per second:    2318.34 [#/sec] (mean)
Time per request:       431.343 [ms] (mean)
Time per request:       0.431 [ms] (mean, across all concurrent requests)
Transfer rate:          20697.06 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   45  70.4     13    1170
Processing:    10  224 520.6     54    4247
Waiting:        7  216 519.5     46    4244
Total:         21  269 532.4     94    4306

Percentage of the requests served within a certain time (ms)
  50%     94
  66%    204
  75%    233
  80%    274
  90%    480
  95%    907
  98%   2416
  99%   2613
 100%   4306 (longest request)

mod_mpm_event

 marvindeMacBook-Pro:65 marvin$  ab -c 1000 -n 10000 http://192.168.1.102/manual/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.1.102 (be patient)
Completed 1000 requests
Completed 2000 requests
Completed 3000 requests
Completed 4000 requests
Completed 5000 requests
Completed 6000 requests
Completed 7000 requests
Completed 8000 requests
Completed 9000 requests
Completed 10000 requests
Finished 10000 requests

Server Software:        Apache/2.4.6
Server Hostname:        192.168.1.102
Server Port:            80

Document Path:          /manual/
Document Length:        8881 bytes

Concurrency Level:      1000
Time taken for tests:   3.067 seconds
Complete requests:      10000
Failed requests:        0
Total transferred:      91450000 bytes
HTML transferred:       88810000 bytes
Requests per second:    3260.46 [#/sec] (mean)   #吞吐量  明显大于上面2个
Time per request:       306.705 [ms] (mean)
Time per request:       0.307 [ms] (mean, across all concurrent requests)
Transfer rate:          29118.08 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        6   70  44.7     54     392
Processing:    10  193 248.7    115    2168
Waiting:        6  143 219.9     63    2167
Total:         26  263 254.5    205    2333

Percentage of the requests served within a certain time (ms)
  50%    205
  66%    243
  75%    297
  80%    329
  90%    479
  95%    704
  98%    900
  99%   1701
 100%   2333 (longest request)
以上测压可以看到event的吞吐量最好,但是apache一般模式还是用prefork偏多,因为他相对稳定

5、目录访问控制

 # Relax access to content within /var/www.
#这项说 /var/www 也可以做为文件跟目录,但是默认不目录在/var/www/html,需要设置DocumentRoot,或者个alias
#

    Options Indexes FollowSymLinks
    AllowOverride None
    # Allow open access:
    Require all granted
 
    #
    # The Options directive is both complicated and important.  Please see
    # http://httpd.apache.org/docs/2.4/mod/core.html#options

    #Options None  关闭所有
    #Options All   开启所有
    #这两项说明 开启文件目录索引  链接文件可以被访问
    Options Indexes FollowSymLinks  

    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    AllowOverride None

        #基于IP控制:
        #    Require ip  IP地址或网络地址
        #    Require not ip IP地址或网络地址
        #基于主机名控制:
        #    Require host 主机名或域名
        #    Require not host 主机名或域名
        #要放置于配置块中或配置块中;
    #同意所有
    Require all granted
    #拒绝所有
    #Require all denied

6、别名

    
    Alias /cgi-bin/ "/var/www/cgi-bin/"


[root@ns1 httpd]# cd /var/www/cgi-bin/
[root@ns1 cgi-bin]# touch a.html
[root@ns1 cgi-bin]# echo 123 > a.html
[root@ns1 cgi-bin]# systemctl restart httpd

lamp快速搭建_第4张图片

7、日志

 
     LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
     LogFormat "%h %l %u %t \"%r\" %>s %b" common
     
      # You need to enable mod_logio.c to use %I and %O
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    
     CustomLog "logs/access_log" combined
 

 [root@ns1 httpd]# cat logs/access_log

192.168.1.101 - - [12/May/2018:22:11:10 -0400] "GET / HTTP/1.1" 403 4897 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
 ---------------------------------------------------------------------------

LogFormat format strings:

%h:客户端IP地址;
%l:Remote User, 通常为一个减号(“-”);基于identd模块登入
%u:Remote user (from auth; may be bogus if return status (%s) is 401);非为登录访问时,其为一个减号; 基于auth登入有用
%t:服务器收到请求时的时间;
%r:First line of request,即表示请求报文的首行;记录了此次请求的“方法”,“URL”以及协议版本;
%>s:响应状态码;
%b:响应报文的大小,单位是字节;不包括响应报文的http首部;
%{Referer}i:请求报文中首部“referer”的值;即从哪个页面中的超链接跳转至当前页面的;
%{User-Agent}i:请求报文中首部“User-Agent”的值;即发出请求的应用程序;
%{headerkey}

日志存放位置

[root@ns1 httpd]# ll /etc/httpd
lrwxrwxrwx. 1 root root  19 May 11 21:15 logs -> ../../var/log/httpd

8、基本用户访问控制

basic 配置:

使用专用命令完成此类文件的创建及用户管理
        htpasswd  [options]   /PATH/TO/HTTPD_PASSWD_FILE  username 
            -c:自动创建此处指定的文件,因此,仅应该在此文件不存在时使用;    #慎用
            -m:md5格式加密
            -s: sha格式加密
            -D:删除指定用户
            -b:批模式添加用户 
                htpasswd -b  [options]   /PATH/TO/HTTPD_PASSWD_FILE  username password

------------------------------------------------------------------------------------
[root@ns1 httpd]# htpasswd  -s -c   test.users zander zander
[root@ns1 httpd]# htpasswd  -b -m   test.users tom tom
[root@ns1 httpd]# htpasswd  -b -m   test.users jerry jerry
[root@ns1 httpd]# htpasswd  -b -m   test.users jack 123456

[root@ns1 httpd]# cat test.users
jack:$apr1$4AM.U0Kk$9ZqiF4vHk/9R8TfpkxmPK1
tom:$apr1$L.PSF0Co$2V2Znhy6.3n10P4X9cTyP/
jerry:$apr1$GRULnii4$67yoYq8NuR5hnZJlAdq9F/
zander:{SHA}zS0U/xNGl8n4yzQjRDQ62OChq1s=


    Options Indexes FollowSymLinks
    AllowOverride None
    AuthType Basic
    AuthName "private area"
    AuthDigestProvider file
    AuthUserFile "/etc/httpd/test.users"   #生产用.htpasswd
    Require user jack tom jerry zander
    #Require valid-user
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,cy;q=0.7
Authorization: Basic dG9tOnRvbQ==    #base64 转码而已   base64("tom:tom")   所以是不安全的
Cache-Control: max-age=0
Connection: keep-alive
Host: 192.168.1.102
If-Modified-Since: Sun, 13 May 2018 03:36:07 GMT
If-None-Match: W/"3-56c0e11cec3ad"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36

lamp快速搭建_第5张图片

digest加密配置

#realm  “digest” 必须跟  AuthName "digest" 要保持一直,否则验证不通过
[root@ns1 httpd]# htdigest  -c  test2.users "digest" tom
[root@ns1 httpd]# htdigest    test2.users "digest" zander   


    Options Indexes FollowSymLinks
    AllowOverride None
    AuthType Digest
    #AuthDigestDomain /
    AuthName "digest"
    AuthDigestProvider file
    AuthUserFile "/etc/httpd/test2.users"   #htdigest生产的文件   生产用.htpasswd
    Require user jack tom jerry zander
    #Require valid-user
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,cy;q=0.7
Authorization: Digest username="jack", realm="digest", nonce="lpFuDA5sBQA=2bcc3a585d202e95520cc3213cbe7ae4a978347d", uri="/", algorithm=MD5, response="7baab410ca5938d7886b4372ae832381", qop=auth, nc=00000007, cnonce="db374da2da3cd9b2"
Cache-Control: max-age=0
Connection: keep-alive
Host: 192.168.1.102
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36

查看日志参数

 [root@ns1 httpd]# cat logs/access_log   #auth用户名已成功
192.168.1.101 - jack [12/May/2018:23:15:48 -0400] "GET /favicon.ico HTTP/1.1" 404 209 "http://192.168.1.102/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"

9、虚拟主机

VirtualHost :81 VirtualHost ip:81 特别说明,这里最好要么全部ip,要么全部

1、ip访问

 [root@ns1 conf.d]# /etc/httpd/conf.d
[root@ns1 conf.d]# vim vhost.conf

        ServerName www.ip.develop
        DocumentRoot "/web/data/ip"
        
                options None
                AllowOverride None
                Require all granted
        
        ErrorLog "logs/ip_error_log"
        CustomLog "logs/ip_access_log" combined

lamp快速搭建_第6张图片

2、基于端口访问

 [root@ns1 conf.d]# /etc/httpd/conf.d
[root@ns1 conf.d]# vim vhost.conf
Listen 81

        ServerName www.port.develop
        DocumentRoot "/web/data/port"
        
                options None
                AllowOverride None
                Require all granted
        
        ErrorLog "logs/port_error_log"
        CustomLog "logs/port_access_log" combined

lamp快速搭建_第7张图片

3、FQDN

 #完全域名访问没必要加端口,这里只是实验而已,但是客户端域名解析必须能接到对对应ip地址
Listen 81
      #    
        ServerName www.fqdn.develop
        DocumentRoot "/web/data/fqdn"
        
                options None
                AllowOverride None
                Require all granted
        
        ErrorLog "logs/fqdn_error_log"
        CustomLog "logs/fqdn_access_log" combined


-----------------------------------------------------------------
注意:如果是httpd-2.2,则使用基于FQDN的虚拟主机时,需要事先使用如下指令:
        NameVirtualHost IP:PORT

lamp快速搭建_第8张图片

9、status

 LoadModule  status_module  modules/mod_status.so

        httpd-2.2
            
                SetHandler server-status
                Order allow,deny
                Allow from 172.16
            

        httpd-2.4
            
                SetHandler server-status
                
                    Require all granted        #生产环境一定要注意
                
                         

Listen 81    

        ServerName www.fqdn.develop
        DocumentRoot "/web/data/fqdn"
        
                options None
                AllowOverride None
                Require all granted
        
           #/server-status 随意
                SetHandler server-status     #server-status 固定
                
                        Require all granted
                
        
        ErrorLog "logs/port_error_log"
        CustomLog "logs/port_access_log" combined
 http://www.fqdn.develop:81/server-status

Apache Server Status for www.fqdn.develop (via 192.168.1.102)
Server Version: Apache/2.4.6 (CentOS)
Server MPM: worker
Server Built: Apr 20 2018 18:10:38
Current Time: Sunday, 13-May-2018 01:14:53 EDT
Restart Time: Sunday, 13-May-2018 01:11:03 EDT
Parent Server Config. Generation: 1
Parent Server MPM Generation: 0
Server uptime: 3 minutes 50 seconds
Server load: 0.00 0.01 0.05
Total accesses: 41 - Total Traffic: 141 kB
CPU Usage: u.01 s.01 cu0 cs0 - .0087% CPU load
.178 requests/sec - 627 B/second - 3521 B/request
1 requests currently being processed, 49 idle workers
........................._____W_________________________________
___________.....................................................
................................................................
................................................................
............................................
Scoreboard Key:
"_" Waiting for Connection, "S" Starting up, "R" Reading Request,   这个是worker模式 _表示可链接线程 
"W" Sending Reply, "K" Keepalive (read), "D" DNS Lookup,
"C" Closing connection, "L" Logging, "G" Gracefully finishing,
"I" Idle cleanup of worker, "." Open slot with no current process
Srv PID Acc M   CPU SS  Req Conn    Child   Slot    Client  VHost   Request
1-0 97189   0/0/0   W   0.00    0   0   0.0 0.00    0.00    192.168.1.101   www.fqdn.develop:81 GET //server-status HTTP/1.1
1-0 97189   0/39/39 _   0.02    184 0   0.0 0.14    0.14    192.168.1.101   www.port.develop:81 NULL
2-0 97191   0/2/2   _   0.00    184 0   0.0 0.00    0.00    192.168.1.101   www.port.develop:81 NULL
Srv Child Server number - generation
PID OS process ID
Acc Number of accesses this connection / this child / this slot
M   Mode of operation
CPU CPU usage, number of seconds
SS  Seconds since beginning of most recent request
Req Milliseconds required to process most recent request
Conn    Kilobytes transferred this connection
Child   Megabytes transferred this child
Slot    Total megabytes transferred this slot

10、压缩

压缩模块

 [root@ns1 conf.d]# httpd -M |grep deflate
 deflate_module (shared)
 SetOutputFilter DEFLATE   #对DEFLATE这类行进行压缩, 下面都是DEFLATE类型的
DeflateCompressionLevel 6 #9最高 1最低   6差不多行了
# Restrict compression to these MIME types
AddOutputFilterByType DEFLATE text/plain 
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css

#以下几个是为了兼容   并非必须
# Netscape 4.x has some problems.
BrowserMatch ^Mozilla/4  gzip-only-text/html

# Netscape 4.06-4.08 have some more problems
BrowserMatch  ^Mozilla/4\.0[678]  no-gzip

# MSIE masquerades as Netscape, but it is fine
BrowserMatch \bMSI[E]  !no-gzip !gzip-only-text/html

测试压缩

[root@ns1 ip]# ll
total 164
-rwxr-xr-x. 1 root root 155485 May 13 03:48 main.css

不开启压缩

Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 155485
Content-Type: text/css
Date: Sun, 13 May 2018 07:52:44 GMT
ETag: "25f5d-56c11973af074"
Keep-Alive: timeout=15, max=100
Last-Modified: Sun, 13 May 2018 07:48:11 GMT
Server: Apache/2.4.6 (CentOS)

开启压缩

[root@ns1 conf.d]# vim  /etc/httpd/conf.d/compress.conf
setOutputFilter DEFLATE
DeflateCompressionLevel 6
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/css
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 17701      #明显少了很多
Content-Type: text/css
Date: Sun, 13 May 2018 07:54:30 GMT
ETag: "25f5d-56c11973af074-gzip"
Keep-Alive: timeout=15, max=100
Last-Modified: Sun, 13 May 2018 07:48:11 GMT
Server: Apache/2.4.6 (CentOS)
Vary: Accept-Encoding

11、https

私有证书请参考 https://blog.51cto.com/marvin89/2114273

 Listen 443
   #主要这里 配置多个的话  要么全部用ip 要么全部写*,不能混用
        SSLEngine On
        ServerName www.fqdn.develop:443
        DocumentRoot "/web/data/fqdn"
        SSLCertificateFile /etc/httpd/ssl/http.crt
        SSLCertificateKeyFile /etc/httpd/ssl/http.key
        SSLCACertificateFile /etc/httpd/ssl/http.cer
        SSLVerifyClient require
       SSLVerifyDepth  10
        
                options None
                AllowOverride None
                Require all granted
        

        ErrorLog "logs/port_error_log"
        CustomLog "logs/port_access_log" combined

php集成安装

 [root@ns1 port]# yum install php

 [root@ns1 port]# rpm -ql php
/etc/httpd/conf.d/php.conf
 [root@ns1 port]# cat /etc/httpd/conf.d/php.conf
#
# Cause the PHP interpreter to handle files with a .php extension.
#

    SetHandler application/x-httpd-php


#
# Allow php to handle Multiviews
#
AddType text/html .php

#
# Add index.php to the list of files that will be served as directory
# indexes.
#
DirectoryIndex index.php

#
# Uncomment the following lines to allow PHP to pretty-print .phps
# files as PHP source code:
#
#
#    SetHandler application/x-httpd-php-source
#

#
# Apache specific PHP configuration options
# those can be override in each configured vhost
#
php_value session.save_handler "files"
php_value session.save_path    "/var/lib/php/session"

php-fpm安装

 [root@ns1 ~]# yum  install php-fpm 

配置文件

 [root@ns1 ~]# cd /etc/php-fpm.d/
[root@ns1 php-fpm.d]# ls
www.conf
[root@ns1 php-fpm.d]# cp www.conf{,.bak}
listen = 127.0.0.1:9000
;listen.backlog = -1  #-1 表示无限  半连接池
listen.allowed_clients = 127.0.0.1

pm = dynamic   #static|dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500  #每个进程响应多少次之后杀掉

pm.status_path = /pm-status  #内置状态页pm-status

ping.path = /ping   #状态监测
ping.response = pong

;request_terminate_timeout = 0  #超时时间  0 不超时

#session
php_value[session.save_handler] = files
php_value[session.save_path] = /var/lib/php/session

连接池:

pm = static|dynamic
static:固定数量的子进程;pm.max_children;
dynamic:子进程数据以动态模式管理;
pm.start_servers
pm.min_spare_servers
pm.max_spare_servers
;pm.max_requests = 500

[root@ns1 php-fpm.d]# ll -d /var/lib/php/session
drwxrwx---. 2 root apache 6 Apr 12 15:04 /var/lib/php/session
创建session目录,并确保运行php-fpm进程的用户对此目录有读写权限;
    # mkdir  /var/lib/php/session
    # chown apache.apache /var/lib/php/session  

启动脚本

 [root@ns1 php-fpm.d]# systemctl start php-fpm

查看apache是否开启fcgi模块

 [root@ns1 php-fpm.d]# httpd -M|grep cgi
 proxy_fcgi_module (shared)

下面只要配置虚拟主机部分就行

 (1) 配置httpd,添加/etc/httpd/conf.d/fcgi.conf配置文件,内容类似:

    DirectoryIndex index.php
    ProxyRequests Off
    ProxyPassMatch ^/(.*\.php)$  fcgi://127.0.0.1:9000/var/www/html/$1              

(2) 虚拟主机配置


        ServerName www.ip.develop
        DocumentRoot "/web/data/ip"
        ProxyRequests Off
        ProxyPassMatch ^/(ping|pm-status)$  fcgi://127.0.0.1:9000/$1
        ProxyPassMatch ^/(.*\.php)$  fcgi://127.0.0.1:9000/web/data/ip/$1
        
                DirectoryIndex index.php
                options None
                AllowOverride None
                Require all granted
        
        CustomLog "logs/ip_access_log" combined

lamp快速搭建_第9张图片

lamp快速搭建_第10张图片


mariadb

centos7默认安装Mariadb

 yum install  mysql-server

配置文件

 [root@ns1 mysql]# vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd

#添加关闭域名反解
skip-name-resolve=ON   
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

数据库部分之后会做详细介绍,这里先略过了。


分享一段自动化安装脚本

python3运行环境,没有安装py3的朋友可以参考最下面一段安装脚本
目录结构:

lamp快速搭建_第11张图片

install.py

#!/root/.virtualenvs/shellenv/bin/python
import os,sys,copy
import subprocess
import logging
import configparser
from concurrent.futures import ProcessPoolExecutor

class AppInstall:

    package_path = '/www/packages'
    log_path = '/www/packages/logs'
    source_path = '/www/server/source'
    link_path = '/www/server'
    data_path = '/www/data'
    mode='quiet'

    def work(self,install='', mode='quiet'):
        self.mode = mode
        self.logname = install
        self.current_dir = os.path.dirname(os.path.abspath(__file__))
        self.init_workdir()
        self.__logs()
        print(install)
        if install == 'apache':
            self.start('conf/apache.yaml')
        if install == 'php':
            self.start('conf/php.yaml')
        if install == 'php-fpm':
            self.start('conf/php-fpm.yaml')
        if install == 'mysql':
            self.start('conf/mysql.yaml')
        if install == 'nginx':
            self.start('conf/nginx.yaml')

    def start(self,configpath):
        import yaml
        config = yaml.load(open(configpath))

        if not config:
            self.__error(configpath+': is error ')

        config = self.init_config(config)
        os.chdir(self.package_path)

        self.logger.info('-----------------------------start {name}---------------------------------'.format(name=config['name']))

        if config.get('yum'):
            self.do_yum(config['yum'])
        if config.get('downloads') :
            self.do_download(config['downloads'])
        if config.get('cmds') :
            self.foreach_cmds(config['cmds'])

        if config.get('depends'):
            for depend in config.get('depends'):
                self.do_compile(depend['uncompress'], depend['uncompress_dir'], depend['compile'])

        if config.get('compile'):
            self.do_compile(config['uncompress'], config['uncompress_dir'], config['compile'])

        if config.get('init').get('linkname'):
            linkpath = self.link_path+'/'+config.get('init').get('linkname')
            if not os.path.exists(linkpath):
                self.__cmd('ln -sv {source_path}/{name}{version}  {link_path}/{link_name}'.format(version=config['version'],
                                                                                      source_path=self.source_path,
                                                                                      link_path=self.link_path,
                                                                                      link_name=config.get('init').get('linkname'),
                                                                                      name=config['name']))

        if config.get('init').get('cmds'):
            self.foreach_cmds(config['init']['cmds'])

        if config.get('init').get('systemctl'):
            self.write_systemctl(config['init']['systemctl']['path'], config['init']['systemctl']['content'])

        self.logger.info('-----------------------------finish {name}---------------------------------'.format(name=config['name']))
        os.chdir(self.current_dir)

    def init_config(self, config):

        config = self.__init_denpends_config(config)
        config_tmp = copy.deepcopy(config)
        config_tmp = str(config_tmp)
        config_tmp = config_tmp.replace('{version}', config["version"])
        config_tmp = config_tmp.replace('{name}', config["name"])
        config_tmp = config_tmp.replace('{source_path}', self.source_path)
        config_tmp = config_tmp.replace('{link_path}', self.link_path)
        config_tmp = config_tmp.replace('{data_path}', self.data_path)
        config = eval(config_tmp)

        config["downloads"]=[]
        for key in config:
            if key == 'download':
                config["downloads"].append(config['download'])
            if key == 'depends':
                for i in config['depends']:
                    for j in i:
                        if j == 'download':
                            config["downloads"].append(i['download'])

        return config

    def __init_denpends_config(self, config):
        if config.get('depends'):
            depends = copy.deepcopy(config['depends'])
            for i in depends:
                config['depends'].remove(i)
                for j in i :
                    i[j] = i[j].format(version=i['version'])
                config['depends'].append(i)
        return config

    def foreach_cmds(self, cmds):
        for cmd in cmds:
            self.__cmd(cmd)
        return True

    def do_yum(self, yums):
        for yum in yums:
            self.__cmd(yum)
        return True

    def do_compile(self, uncompress, uncompress_dir, compile):
        os.path.exists(uncompress_dir) and self.__cmd('rm -fr {uncompress_dir}'.format(uncompress_dir=uncompress_dir))
        self.__cmd(uncompress)
        if compile:
            self.__cmd('cd '+uncompress_dir+' && ' + compile)

    def do_download(self, downloads):
        os.chdir(self.package_path)
        for url in downloads:
            arr_url = url.split(' -O ')
            if len(arr_url) == 2:
                filename = self.package_path + '/' + arr_url[-1].strip()
            else:
                filename = self.package_path + '/' + os.path.basename(url)

            if not os.path.isfile(filename):
                if  not self.__cmd('wget '+url, False):
                    self.__remove(filename)
                    sys.exit(1)
        return True

    def init_workdir(self):
        os.path.exists(self.package_path) or os.makedirs(self.package_path)
        os.path.exists(self.link_path) or os.makedirs(self.link_path)
        os.path.exists(self.source_path) or os.makedirs(self.source_path)
        os.path.exists(self.data_path) or os.makedirs(self.data_path)
        os.path.exists(self.log_path) or os.makedirs(self.log_path)

    def write_systemctl(self, path, data={}):
        config = configparser.ConfigParser()
        config.optionxform = str
        self.configparser = config
        for key in data:
            config[key] = data[key]
        config.write(open(path, 'w'))

    def __cmd(self, cmd, isexit=True):
        print('doing............'+cmd)
        if self.mode == 'quiet':
            res = subprocess.getstatusoutput(cmd)
        else:
            tmp = os.system(cmd)
            res=[]
            res.append(tmp)
            res.append('debug')

        if res[0] != 0:
            self.logger.error(cmd + ' ' + res[1])
            if isexit:
                sys.exit(1)
            else:
                return False
        else:
            self.logger.info(cmd)
            return True

    def __remove(self,filename):
        os.path.isfile(filename) and os.remove(filename)

    def __logs(self):
        print(self.log_path+'/'+self.logname+'.logs')
        logger = logging.getLogger('log1')
        fh = logging.FileHandler(self.log_path+'/'+self.logname+'.logs')
        ch = logging.StreamHandler()
        fm = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
        fh.setFormatter(fm)
        ch.setFormatter(fm)
        logger.setLevel(logging.DEBUG)
        logger.addHandler(fh)
        logger.addHandler(ch)
        self.logger = logger

    def __error(self,data):
        self.logger.error(data)
        exit(1)

if __name__ == '__main__':

    pydepends = ['pyyaml']
    for i in pydepends:
        os.system('/root/.virtualenvs/shellenv/bin/pip install  requests -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com '+i)

    pools = ProcessPoolExecutor(4)
    # installs = ['apache', 'php-fpm', 'mysql']
    installs = ['apache']
    appobj = AppInstall()
    for app in installs:
        pools.submit(appobj.work,app, 'debug')
    pools.shutdown(wait=True)

    print('-----------------------Installed ^_^ All-----------------------')

conf/apache.yaml

 name: apache
version: 2.4.33
download: http://mirrors.hust.edu.cn/apache/httpd/httpd-{version}.tar.gz
cmds:
  - id apache ||  useradd -r -M -s /sbin/nologin apache
yum:
  - yum -y groupinstall "Development tools"
  - yum -y install pcre-devel wget zlib-devel openssl-devel expat-devel
  - yum -y update openssl

uncompress: tar xf httpd-{version}.tar.gz
uncompress_dir: httpd-{version}
compile: ./configure --prefix={source_path}/{name}{version}
                                              --sysconfdir={source_path}/{name}{version}/conf
                                              --enable-so
                                              --enable-ssl
                                              --enable-fcgi
                                              --enable-cgi
                                              --enable-deflate
                                              --enable-rewrite
                                              --with-zlib
                                              --with-pcre
                                              --with-apr=/usr/local/apr
                                              --with-apr-util=/usr/local/apr-util
                                              --enable-modeles=most
                                              --enable-mpms-shared=all
                                              --with-mpm=event
                                              && make && make install
depends:
  - name: apr
    version: 1.6.3
    download: http://mirrors.shu.edu.cn/apache/apr/apr-{version}.tar.gz
    uncompress: tar xf apr-{version}.tar.gz
    uncompress_dir: apr-{version}
    compile:  ./configure --prefix=/usr/local/apr && make && make install
  - name: apr-util
    version: 1.6.1
    download: http://mirror.bit.edu.cn/apache/apr/apr-util-{version}.tar.bz2
    uncompress: tar xf apr-util-{version}.tar.bz2
    uncompress_dir: apr-util-{version}
    compile: ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr && make && make install
init:
    linkname: apache
    cmds:
      -  echo 'export PATH={link_path}/{name}/bin:$PATH'>/etc/profile.d/httpd.sh
      -  "cat {source_path}/{name}{version}/conf/httpd.conf|egrep '^IncludeOptional conf' || echo 'IncludeOptional conf/conf.d/*.conf'>>{source_path}/{name}{version}/conf/httpd.conf"
      - '[ -d {source_path}/{name}{version}/conf/conf.d ] || mkdir  {source_path}/{name}{version}/conf/conf.d'
      - sed -i  's#^User daemon$#User apache#' {source_path}/{name}{version}/conf/httpd.conf
      - sed -i  's#^Group daemon$#Group apache#' {source_path}/{name}{version}/conf/httpd.conf

    systemctl:
          path: /etc/systemd/system/myhttpd.service
          content:
              Unit:
                  Description: The Apache HTTP Server
                  After: network.target remote-fs.target nss-lookup.target
                  Documentation: man:httpd(8)
                  Documentation: man:apachectl(8)
              Service:
                  Type: forking
                  PIDFILE: '{link_path}/{name}/logs/httpd.pid'
                  ExecStart: '{link_path}/{name}/bin/apachectl start'
                  ExecReload: '{link_path}/{name}/bin/apachectl  graceful'
                  ExecStop: '{link_path}/{name}/bin/apachectl stop'
                  PrivateTmp: true
                  LimitNOFILE: infinity
              Install:
                  WantedBy: multi-user.target

conf/php

 name: php
version: 7.2.5
download: http://hk2.php.net/distributions/php-{version}.tar.gz

yum:
  - yum -y groupinstall "Development tools"
  - yum install -y freetype-devel libpng-devel gd-devel libcurl-devel libjpeg-turbo-devel libxslt-devel zlib-devel libxml2-devel  libiconv-devel  bzip2-devel libmcrypt-devel

uncompress: tar xf php-{version}.tar.gz
uncompress_dir: php-{version}
compile: ./configure --prefix={source_path}/{name}{version}
                            --enable-mysqlnd
                            --with-mysqli=mysqlnd
                            --with-openssl
                            --with-pdo-mysql=mysqlnd
                            --enable-mbstring
                            --with-freetype-dir
                            --with-jpeg-dir
                            --with-png-dir
                            --with-zlib
                            --with-iconv
                            --enable-zip
                            --with-libxml-dir
                            --with-gd
                            --enable-xml
                            --enable-sockets
                            --with-apxs2=/www/server/apache/bin/apxs
                            --with-config-file-path={source_path}/{name}{version}/conf
                            --with-config-file-scan-dir={source_path}/{name}{version}/php.d
                            --enable-maintainer-zts
                            --enable-opcache
                            --enable-session
                            --with-curl
                            --enable-maintainer-zts
                            --enable-fileinfo
                            && make && make install
init:
    linkname: php
    cmds:
      - mkdir {source_path}/{name}{version}/conf
      - mkdir {source_path}/{name}{version}/conf.d
      - cd php-{version} && cp php.ini-production {source_path}/{name}{version}/conf/php.ini

conf/php-fpm

 name: php-fpm
version: 7.2.5
download: http://hk2.php.net/distributions/php-{version}.tar.gz

yum:
  - yum -y groupinstall "Development tools"
  - yum install -y freetype-devel libpng-devel gd-devel libcurl-devel libjpeg-turbo-devel libxslt-devel zlib-devel libxml2-devel  libiconv-devel  bzip2-devel libmcrypt-devel

uncompress: tar xf php-{version}.tar.gz
uncompress_dir: php-{version}
compile: ./configure --prefix={source_path}/{name}{version}
                            --enable-mysqlnd
                            --with-mysqli=mysqlnd
                            --with-openssl
                            --with-pdo-mysql=mysqlnd
                            --enable-mbstring
                            --with-freetype-dir
                            --with-jpeg-dir
                            --with-png-dir
                            --with-zlib
                            --with-iconv
                            --enable-zip
                            --with-libxml-dir
                            --with-gd
                            --enable-xml
                            --enable-sockets
                            --enable-fpm
                            --with-config-file-path={source_path}/{name}{version}/conf
                            --with-config-file-scan-dir={source_path}/{name}{version}/php.d
                            --enable-maintainer-zts
                            --enable-opcache
                            --enable-session
                            --with-curl
                            --enable-maintainer-zts
                            --enable-fileinfo
                            && make && make install
init:
    linkname: php-fpm
    cmds:
      - '[ -d /www/server/source/php-fpm7.2.5/conf ] || mkdir {source_path}/{name}{version}/conf'
      - '[ -d /www/server/source/php-fpm7.2.5/conf.d ] || mkdir {source_path}/{name}{version}/conf.d'
      - '[ -f {source_path}/{name}{version}/conf/php.ini ] || cp php-{version}/php.ini-production {source_path}/{name}{version}/conf/php.ini'
      - '[ -f {source_path}/{name}{version}/etc/php-fpm.conf ]  || cp {source_path}/{name}{version}/etc/php-fpm.conf.default {source_path}/{name}{version}/etc/php-fpm.conf'
      - '[ -f {source_path}/{name}{version}/etc/php-fpm.d/www.conf ] || cp {source_path}/{name}{version}/etc/php-fpm.d/www.conf.default {source_path}/{name}{version}/etc/php-fpm.d/www.conf'
    systemctl:
      path: /etc/systemd/system/myphp-fpm.service
      content:
          Unit:
              Description: Description=The PHP FastCGI Process Manager
              After: syslog.target network.target
          Service:
              Type: forking
              PIDFILE: '{link_path}/{name}/var/run/php-fpm.pid'
              ExecStart: '{link_path}/{name}/sbin/php-fpm'
              ExecReload: '/bin/kill -USR2 $MAINPID'
              PrivateTmp: true
          Install:
              WantedBy: multi-user.target

conf/mysql

 name: mysql
version: 5.7.22
download: https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-{version}-linux-glibc2.12-x86_64.tar.gz

yum:
  - yum -y groupinstall "Development tools"
  - yum -y install readline-devel zlib-devel openssl-devel libaio*

cmds:
  - 'tar xf mysql-{version}-linux-glibc2.12-x86_64.tar.gz && cp -r mysql-{version}-linux-glibc2.12-x86_64 {source_path}/{name}{version}'
  - 'id mysql || useradd  -r -s /sbin/nologin -M  mysql'
  - '[ -d {data_path}/mysql/data ] || mkdir {data_path}/mysql/data -pv'
  - '[ -d {data_path}/mysql/log-bin ] || mkdir {data_path}/mysql/log-bin -pv'
  - '[ -d {source_path}/{name}{version}/etc ] || mkdir {source_path}/{name}{version}/etc -pv'
  - 'chown -R mysql:mysql {data_path}/mysql/'
  - 'chown -R mysql:mysql {source_path}/{name}{version}'
  - 'rm -fr {data_path}/mysql/data/*'
  - '{source_path}/{name}{version}/bin/mysqld --explicit_defaults_for_timestamp   --initialize  --user=mysql  --datadir={data_path}/mysql/data/ --basedir={source_path}/{name}{version}&>{source_path}/{name}{version}/tmpPasswd.txt'
  - '{source_path}/{name}{version}/bin/mysql_ssl_rsa_setup --datadir={data_path}/mysql/data/'
  - 'chown -R root.root {source_path}/{name}{version}/'

init:
    linkname: mysql
    cmds:
      - '[ -f {source_path}/{name}{version}/bin/mysql.server ] || cp {source_path}/{name}{version}/support-files/mysql.server {source_path}/{name}{version}/bin/'
      - sed -i  's#^basedir=$#basedir={link_path}/{name}#' {source_path}/{name}{version}/bin/mysql.server
      - sed -i  's#^datadir=$#datadir={data_path}/mysql/data/#' {source_path}/{name}{version}/bin/mysql.server
      - echo 'export PATH={link_path}/{name}/bin:$PATH'>/etc/profile.d/mysql.sh
    systemctl:
      path: /etc/systemd/system/mysql.service
      content:
          Unit:
              Description: Description=Mysql database server
              After: syslog.target network.target
          Service:
              Type: forking
              User: mysql
              Group: mysql
              PIDFILE: '{data_path}/mysql/data/localhost.localdomain.pid'
              ExecStart: '{link_path}/{name}/bin/mysql.server start'
              ExecReload: '{link_path}/{name}/bin/mysql.server stop'
          Install:
              WantedBy: multi-user.target

以上脚本安装lamp,下载时间除外,安装大概12分钟


python3 自动化安装脚本

 #!/usr/bin/python
#coding=utf-8

import os,sys
version='3.6.5'
package_path='/www/packages'
source_path='/www/server/source'
link_path='/www/server/python'

res1 = os.system('yum install  zlib zlib-devel -y')
res2 = os.system('yum install  wget -y')
res3 = os.system('yum groupinstall "Development tools" -y')
if res1 != 0  or res2 != 0 or res3 != 0:
    print '依赖安装失败'
    sys.exit(1)

if os.getuid() == 0:
    pass
else:
    print '需要root用户运行'
    sys.exit(1)

if not os.path.exists(package_path):
    os.makedirs(package_path)
if not os.path.exists(source_path):
    os.makedirs(source_path)

os.chdir(package_path)
print os.getcwd()

downloadurl = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'.format(version=version)
#

#下载
if not os.path.isfile('Python-{version}.tgz'.format(version=version)):
    cmd = 'wget  '+downloadurl
    print cmd
    res = os.system(cmd)
    if res != 0:
        os.path.exists('Python-{version}.tgz'.format(version=version)) and os.remove('Python-{version}.tgz'.format(version=version))
        print '下载失败'
        sys.exit(1)
#
os.path.exists('Python-{version}'.format(version=version)) and os.system('rm -fr Python-{version}'.format(version=version))
cmd = 'tar xf Python-{version}.tgz'.format(version=version)
res = os.system(cmd)
if res != 0:
    print '解压失败'
    sys.exit(1)

os.path.exists('{source_path}/python{version}'.format(version=version,source_path=source_path)) and os.system('rm -fr {source_path}/python{version}'.format(version=version,source_path=source_path))
cmd = 'cd Python-{version} && ./configure --prefix={source_path}/python{version} && make && make install'.format(version=version,source_path=source_path)
res = os.system(cmd)
if res != 0:
    print '编译失败'
    sys.exit(1)

if not os.path.exists('{link_path}/python{version}'.format(version=version,link_path=link_path)):
    res = os.system('ln -sv {source_path}/python{version}  {link_path}'.format(version=version,source_path=source_path,link_path=link_path))
    if res != 0:
        print 'ln -sv error'
        sys.exit(1)

####------init----------
res = os.system('ln -sv {link_path}/bin/python3.6 /usr/local/bin/'.format(link_path=link_path))
if res != 0:
    print 'ln -sv  /usr/local/bin/python3.6 error'
    sys.exit(1)

res = os.system('ln -sv {link_path}/bin/pip3.6 /usr/local/bin/'.format(link_path=link_path))
if res != 0:
    print 'ln -sv  /usr/local/bin/pip3.6 error'
    sys.exit(1)
#
res = os.system('ln -sv {link_path}/bin/virtualenv /usr/local/bin/'.format(link_path=link_path))
if res != 0:
    print 'ln -sv  /usr/local/bin/virtualenv error'
    sys.exit(1)

res = os.system('pip3.6 install requests -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com  virtualenvwrapper')
if res != 0:
    print 'pip3.6 install virtualenvwrapper error'
    sys.exit(1)
else:
    os.system('echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.bashrc')
    os.system('echo "export VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3.6" >> ~/.bashrc')
    os.system('echo "source /www/server/python/bin/virtualenvwrapper.sh" >> ~/.bashrc')

res = os.system('source ~/.bashrc && mkvirtualenv shellenv')
if res != 0:
    print 'mkvirtualenv shellenv'
    sys.exit(1)

print 'init python finish'