本文发布于Cylon的收藏册,转载请著名原文链接~


httpd下载地址:Historical releases

安装httpd

$ ls
ABOUT_APACHE  buildconf	emacs-style  INSTALL			LICENSE			os		srclib
acinclude.m4  CHANGES		httpd.dep    InstallBin.dsp  	Makefile.in    README 	support
Apache.dsw    config.layout  httpd.dsp LAYOUT          	Makefile.win   README.platforms test
build    configure  httpd.mak  libhttpd.dep  modules    README-win32.txt  VERSIONING
BuildAll.dsp  configure.in   httpd.spec   libhttpd.dsp    NOTICE   ROADMAP
BuildBin.dsp  docs            include      libhttpd.mak    NWGNUmakefile  server

httpd 编译参数

参数选项 注释说明
./configure 配置源代码树
–prefix=/usr/local/apache2 体系无关文件的顶级安装目录PREFIX,也就Apache的安装目录。
–enable-module=so [-enable-deflate] 打开so模块,so模块是用来提DSO支持的apache核心模块
–enable-deflate=shared [-enable-expires] 支持网页压缩
–enable-expires=shared [-enable-rewrite] 支持缓存过期控制
–enable-rewrite=shared 支持URL重写
–enable-cache 支持缓存
–enable-file-cache 支持文件缓存
–enable-mem-cache 支持记忆缓存
–enable-disk-cache 支持磁盘缓存
–enable-static-support 支持静态连接(默认为动态连接)
–enable-static-htpasswd 使用静态连接编译htpasswd–管理用于基本认证的用户文件
–enable-static-htdigest 使用静态连接编译htdigest–管理用于摘要认证的用户文件
–enable-static-rotatelogs 使用静态连接编译rotatelogs–滚动Apache日志的管道日志程序
–enable-static-logresolve 使用静态连接编译logresolve–解析Apache日志中的IP地址为主机名
–enable-static-htdbm 使用静态连接编译htdbm–操作DBM密码数据库
–enable-static-ab 使用静态连接编译ab–Apache服务器性能测试工具
–enable-static-checkgid 使用静态连接编译checkgid
–disable-cgid 禁止用一个外部CGI守护进程执行CGI脚本
–disable-cgi 禁止编译CGI版本的PHP
–disable-userdir 禁止用户从自己的主目录中提供页面
–with-mpm=worker 让apache以worker方式运行
–enable-authn-dbm=shared 对动态数据库进行操作。Rewrite时需要。
以下是分门别类的更多参数注解,与上面的会有重复
用于apr的configure脚本的选项
可选特性
–enable-experimental-libtool 启用试验性质的自定义libtool
–disable-libtool-lock 取消锁定(可能导致并行编译崩溃)
–enable-debug 启用调试编译,仅供开发人员使用。
–enable-maintainer-mode 打开调试和编译时警告,仅供开发人员使用。
–enable-profile 打开编译profiling(GCC)
–enable-pool-debug[=yes|no|verbose|verbose-alloc|lifetime|owner|all] 打开pools调试
–enable-malloc-debug 打开BeOS平台上的malloc_debug
–disable-lfs 在32-bit平台上禁用大文件支持(large file support)
–enable-nonportable-atomics 若只打算在486以上的CPU上运行Apache,那么使用该选项可以启用更加高效的基于互斥执行 的原子操作。
–enable-threads 启用线程支持在线程型的MPM上必须打开它
–disable-threads 禁用线程支持,如果不使用线程化的MPM,可以关闭它以减少系统开销。
–disable-dso 禁用DSO支持
–enable-other-child 启用可靠子进程支持
–disable-ipv6 禁用IPv6支持
**可选的额外程序包**
–with-gnu-ld 指定C编译器使用GNU ld
–with-pic 只使PIC/non-PIC对象[默认为两者都使用]
–with-tags[=TAGS] 包含额外的配置
–with-installbuilddir=DIR 指定APR编译文件的存放位置(默认值为:’${datadir}/build’)
–without-libtool 禁止使用libtool连接库文件
–with-efence[=DIR] 指定Electric Fence的安装目录
–with-sendfile 强制使用sendfile(译者注:Linux2.4/2.6内核都支持)
–with-egd[=DIR] 使用EDG兼容的socket
–with-devrandom[=DEV] 指定随机设备[默认为:/dev/random]
用于apr-util的configure脚本的选项
可选的额外程序包
–with-apr=PATH 指定APR的安装目录(–prefix选项值或apr-config的路径)
–with-ldap-include=PATH ldap包含文件目录(带结尾斜线)
–with-ldap-lib=PATH ldap库文件路径
–with-ldap=library 使用的ldap库
–with-dbm=DBM 选择使用的DBM类型DBM={sdbm,gdbm,ndbm,db,db1,db185,db2,db3,db4,db41,db42,db43,db44}
–with-gdbm=PATH 指定GDBM的位置
–with-ndbm=PATH 指定NDBM的位置
–with-berkeley-db=PATH 指定Berkeley DB的位置
–with-pgsql=PATH 指定PostgreSQL的位置
–with-mysql=PATH 参看INSTALL.MySQL文件的内容
–with-sqlite3=PATH 指定sqlite3的位置
–with-sqlite2=PATH 指定sqlite2的位置
–with-expat=PATH 指定Expat的位置或builtin
–with-iconv=PATH iconv的安装目录

关于 2.2 编译参数

 ./configure \
    --prefix=/app/apache2.4.28 \
    --enable-deflate \
    --enable-expires \
    --enable-headers \
    --enable-modules=most \
    --enable-so \
    --with-mpm=worker \
    --enable-rewrite

关于 2.4 编译参数

./configure \
    --prefix=/app/apache-2.4.25.1 \
    --enable-so \
    --enable-deflate=shared \
    --enable-ssl=shared \
    --enable-expires=shared \
    --enable-headers=shared \
    --enable-rewrite=shared \
    --enable-static-support \
    --with-included-apr \
    --with-mpm=worker

开始安装httpd

先安装依赖包

yum -y install \
	gcc \
	gcc-c++ \
	openssl-devel \
	zlib-devel \
	pcre-devel 

Troubleshooting

configure: error: Bundled APR requested but not found

configure: error: Bundled APR requested but not found at ./srclib/. Download and unpack the corresponding apr and apr-util packages to ./srclib/.

编译时需要下载 aprapr-util 解压到 httpd/srclib/ 目录里 http://apr.apache.org/download

error: ‘PCRE_DUPNAMES’ undeclared (first use in this function)

网上搜了下说是yum安装的pcre的版本太老了,不支持PCRE_DUPNAMES 和 PCRE_JAVASCRIPT_COMPAT 这样的PCRE特性。好吧,我去下个最新版的pcre来编译安装。

解决方法:编译安装pcre后,我们重新对httpd-2.4.9执行编译,这下就不会继续报错.

wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.35.tar.gz
tar zxf pcre-8.35.tar.gz && cd pcre-8.35
./configure
make && make install

cannot restore segment prot after reloc: Permission denied

错误如下:

httpd: Syntax error on line 149 of /usr/local/apache/conf/httpd.conf: Cannot load modules/libphp5.so into server: /usr/local/apache/modules/libphp5.so: cannot restore segment prot after reloc: Permission denied

解决方法:很明显的selinux的权限问题

chown -R apache:apache /usr/local/apache
setenforce 0
chcon -c -v -R -u system_u -r object_r -t textrel_shlib_t /usr/local/apache/modules/libphp5.so

configure: WARNING: OpenSSL version is too old

错误现象:CentOS 6.x

checking for OpenSSL version >= 0.9.8a... FAILED
configure: WARNING: OpenSSL version is too old
no
checking whether to enable mod_ssl... configure: error: mod_ssl has been requested but can not be built due to prerequisite failures

解决方法:

yum install openssl openssl-devel

zlib location… not found

错误现象:

checking for zlib location... not found
checking whether to enable mod_deflate... configure: error: mod_deflate has been requested but can not be built due to prerequisite failures

解决方法

yum install zlib zlib-devel -y

no acceptable C compiler found in $PATH

错误现象:

configure: error: no acceptable C compiler found in $PATH

解决方法:gcc工具没安装,或开发工具包没安装 [CentOS 6.x]

yum groupinstall "Development tools" -y
yum install gcc -y

httpd: Could not reliably determine the server’s fully qualified domain name,

错误现象:

$ ./bin/apachectl graceful
httpd: apr_sockaddr_info_get() failed for web-lamp01
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName

错误原因:找不到完整的 fqdn www.etiantian.com 为一个完整的 fqdn 使用 127.0.0.1 替代

解决方法:在 httpd.conf 如果没有注册的DNS域名,用IP地址替换它

启动参数

apachectl参数

选项参数 注释说明
configtest 检查设置文件中的语法是否正确。
fullstatus 显示服务器完整的状态信息。
graceful 重新启动Apache服务器,但不会中断原有的连接。
help 显示帮助信息。
restart 重新启动Apache服务器。
start 启动Apache服务器。
status 显示服务器摘要的状态信息。
stop 停止Apache服务器。

httpd参数

参数选项 注释说明
-c <httpd指令> 在读取配置文件前,先执行选项中的指令。
-C <httpd指令> 在读取配置文件后,再执行选项中的指令。
-d <服务器根目录> 指定服务器的根目录。
-D <设定文件参数> 指定要传入配置文件的参数。
-f <设定文件> 指定配置文件。
-h 显示帮助。
-l 显示服务器编译时所包含的模块。
-L 显示httpd指令的说明。
-S 显示配置文件中的设定。
-t 测试配置文件的语法是否正确。
-v 显示版本信息。
-V 显示版本信息以及建立环境。
-X 以单一程序的方式来启动服务器。
$ /app/apache/bin/apachectl start

$ lsof -i:80
COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
httpd   5871   root    4u  IPv6  69297      0t0  TCP *:http (LISTEN)
httpd   5873 daemon    4u  IPv6  69297      0t0  TCP *:http (LISTEN)
httpd   5874 daemon    4u  IPv6  69297      0t0  TCP *:http (LISTEN)
httpd   5875 daemon    4u  IPv6  69297      0t0  TCP *:http (LISTEN)

$ ps -ef|grep httpd
root      5871     1  0 03:12 ?        00:00:00 /app/apache2.2.27/bin/httpd -k start
daemon    5872  5871  0 03:12 ?        00:00:00 /app/apache2.2.27/bin/httpd -k start
daemon    5873  5871  0 03:12 ?        00:00:00 /app/apache2.2.27/bin/httpd -k start
daemon    5874  5871  0 03:12 ?        00:00:00 /app/apache2.2.27/bin/httpd -k start
daemon    5875  5871  0 03:12 ?        00:00:00 /app/apache2.2.27/bin/httpd -k start
root      5960  2056  0 03:12 pts/0    00:00:00 grep --color=auto httpd

httpd目录结构

$ tree -L 1

.
├── bin #这是apache命令目录,如apache启动命令apachectl
      ├── ab #压力测试工具 同类软件还有jmeter loadrunner webench等
  ├── apachectl  #apache启动命令,需重点掌握,apachectl是一个脚本
      ├── apxs # apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,在进行DOS当时编译模块时会用到 
      ├── htcacheclean #这是清理磁盘缓冲区的命令,需要在编译时指定相关参数才可以使用,一般很少用
      ├── htpasswd # 建立和更新基本认证文件,如:配置nagios等监控服务时会用到
      ├── httpd #httpd为apache的控制命令程序,apachectl执行时会调用httpd
      └── rotatelogs #apache自带的日志轮询命令,其他未使用过的略过未提级,以便大家学习主要的命令
├── build
├── cgi-bin
├── conf # apache所有配置文件的目录
  ├── extra # 额外的apache配置目录,这个目录里的文件我们会经常访问修改,如:httpd-vhosts.conf默认就在此目录
  ├── httpd.conf #apache的主配置文件,这个文件我们会经常访问修改,其中的每一行的参数作用都应该闹明白
  ├── magic
  ├── mime.types
  └── original

├── error
├── htdocs # 默认的apache的站点目录
├── icons
├── include
├── lib
├── logs # 这个时apache的日志默认路径,包括错误日志及访问日志
  ├── access_log #这是apache的默认访问日志
  ├── cgisock.5871
  ├── error_log # apache的错误日志
  └── httpd.pid # httpd的pid文件,httpd进程启动后,会把所有的进程号ID写到此文件
├── man
├── manual
└── modules # apache模块的目录,如memcache

httpd主配置文件说明

grep -Ev "#|^$" httpd.conf >httpd.conf.ori
# 服务的根目录 软件安装到哪
ServerRoot "/app/apache2.2.27"

# web服务监听的端口 监听的ip默认为本机的所有ip地址 listen可以为多个,也可以指定ip
# 没有listen端口是开启不了的
Listen 80
Listen 8000
Listen 192.168.59.1:90 # 如不加默认为所有

<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>

User daemon # 编译安装软件默认用户是daemon 用户
Group daemon #组
</IfModule>
</IfModule>

#管理员的邮箱 当前网站出问题了,会在页面显示
ServerAdmin you@example.com

# 默认的站点目录
DocumentRoot "/app/apache2.2.27/htdocs"

# 权限控制 表示根目录拒绝其他人访问
<Directory />
    Options FollowSymLinks #带符号连接
    AllowOverride None #禁止相关的功能 如.htaccess
    Order deny,allow #不让任何人访问这个目录
    Deny from all 
</Directory>

# 如果新增加一个站点目录必须增加这6行,否则网站打不开
<Directory "/app/apache2.2.27/htdocs">
    Options Indexes FollowSymLinks #Indexs 没有index展示所有目录
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

# 指定访问的首页 如果有多个用空格分开
<IfModule dir_module>
    DirectoryIndex index.html index.php
</IfModule>


<FilesMatch "^\.ht">
    Order allow,deny
    Deny from all
    Satisfy All
</FilesMatch>

#错误日志
ErrorLog "logs/error_log"

#日志级别 警告
LogLevel warn

#访问日志的类型
<IfModule log_config_module>
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%h %l %u %t \"%r\" %>s %b" common
    <IfModule logio_module>
      LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
    CustomLog "logs/access_log" common
</IfModule>

# cgi的配置 现在已经过时了,工作中应该删掉
<IfModule alias_module>
    ScriptAlias /cgi-bin/ "/app/apache2.2.27/cgi-bin/"
</IfModule>
<IfModule cgid_module>
</IfModule>
<Directory "/app/apache2.2.27/cgi-bin">
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
</Directory>

# 缺省的类型
DefaultType text/plain

#添加的类型,对什么类型做什么控制
<IfModule mime_module>
    TypesConfig conf/mime.types
     AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
</IfModule>
<IfModule ssl_module>
SSLRandomSeed startup builtin
SSLRandomSeed connect builtin
</IfModule>

httpd的扩展配置文件

$ ll
总用量 56
-rw-r--r--. 1 root root  2843 4月   8 03:03 httpd-autoindex.conf
-rw-r--r--. 1 root root  1713 4月   8 03:03 httpd-dav.conf
-rw-r--r--. 1 root root  2344 4月   8 03:03 httpd-default.conf
-rw-r--r--. 1 root root  1103 4月   8 03:03 httpd-info.conf
-rw-r--r--. 1 root root  5078 4月   8 03:03 httpd-languages.conf
-rw-r--r--. 1 root root   933 4月   8 03:03 httpd-manual.conf
-rw-r--r--. 1 root root  3789 4月   8 03:03 httpd-mpm.conf
-rw-r--r--. 1 root root  2183 4月   8 03:03 httpd-multilang-errordoc.conf
-rw-r--r--. 1 root root 11378 4月   8 03:03 httpd-ssl.conf
-rw-r--r--. 1 root root   817 4月   8 03:03 httpd-userdir.conf
-rw-r--r--. 1 root root  1491 4月   8 03:03 httpd-vhosts.conf

mpm

--with-mpm=worker \
<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>
# 如果指定了worker就是woker,否则是prefork
<IfModule mpm_worker_module>
    StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

defalut配置文件

$ grep -Ev "#|^$" httpd-default.conf 
# 连接超时
Timeout 300
#保持连接的状态
KeepAlive On
#最大接受多少个永久连接
MaxKeepAliveRequests 100
#在同一个连接上,等待下一个请求的时间
KeepAliveTimeout 5
UseCanonicalName Off
#将伪静态的语法写在这个里面
AccessFileName .htaccess
#隐藏apache版本号,不同意被攻击
ServerTokens Full
ServerSignature On
HostnameLookups Off

虚拟主机

所谓基于 ”x“ 的虚拟主机,就是靠 ”x“ 来区分不同的站点。支持各种混合,N多个虚拟主机

基于域名的虚拟主机★★★★★

建立三个站点

  • www.etiantian.com —— /var/html/www
  • blog.etiantian.com —— /var/html/blog
  • bbs.etiantian.com —— /var/html/bbs

步骤1:在 httpd.conf 中打开 Include conf/extra/httpd-vhosts.conf

步骤2:在 extra 中的 vhost 中添加三个虚拟主机

<VirtualHost *:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/www"
    ServerName www.etiantian.com
    ErrorLog "logs/www_error_log"
    CustomLog "logs/www_access_log" common
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/blog"
    ServerName blog.etiantian.com
    ErrorLog "logs/blog_error_log"
    CustomLog "logs/blog_access_log" common
</VirtualHost>

<VirtualHost *:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/bbs"
    ServerName bbs.etiantian.com
    ErrorLog "logs/bbs_error_log"
    CustomLog "logs/bbs_access_log" common
</VirtualHost>

步骤3:在主配置文件,或在 <VirtualHost> 里配置权限

<Directory "/var/html">
    Options FollowSymLinks
    AllowOverride None
    Order allow,deny
    Allow from all
</Directory>

如果配置为 Options Indexes FollowSymLinks 则显示为下图所示

image-20221202162523234

如果配置为 Options -Indexes FollowSymLinks 则显示为下图所示

img

基于端口的虚拟主机

一般来讲是内部网站

  • 优点:安全一些,别人找不到

步骤1:在 httpd.conf 中增加监听端口

Listen 80
Listen 8000
Listen 9000

步骤1:在 vhost 文件中增加

NameVirtualHost *:80
NameVirtualHost *:8000

<VirtualHost *:8000>

image-20221202162815605

基于IP的虚拟主机

步骤1:配置别名ip

ifconfig eth0:0 192.168.59.140/24

步骤2:1.修改 vhost 文件虚拟主机配置

<VirtualHost 192.168.59.140:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/blog"
    ServerName 192.168.59.140
    ErrorLog "logs/blog_error_log"
    CustomLog "logs/blog_access_log" common
</VirtualHost>

混合虚拟主机

<VirtualHost 192.168.59.140:900>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/blog"
    ServerName 192.168.59.140
    ErrorLog "logs/blog_error_log"
    CustomLog "logs/blog_access_log" common
</VirtualHost>

日志格式

  • 通用日志格式Common Log Format
  • 组合日志格式Combinded Log Format
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common

如何使用combined或common呢?

答:在虚拟主机配置中更改格式

<VirtualHost *:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/www"
    ServerName www.etiantian.com
    ErrorLog "logs/www_error_log"
    CustomLog "logs/www_access_log" common/combind
</VirtualHost>

日志轮询

  • rotatelog
  • cronolog ☆☆☆

安装 cronolog

./configure
make  
make install

$ which cronolog
/usr/local/sbin/cronolog

如果用cronolog轮询的的话最好用全路径

CustomLog "|/usr/local/sbin/cronolog  /app/logs/access_bbs_%Y%m%d.log" combined

$ mkdir /app/logs -p
$ ../bin/apachectl graceful

日志轮询除了可以使用年月日还可以使用周

CustomLog "|/usr/local/sbin/cronolog  /app/logs/access_bbs_%w.log" combined

时间格式串

时间格式串
%H 24小时制小时(00..23)
%I 12小时制小时(01..12)
%p 本地AM/PM指示符
%M 分钟(00..59)
%S 秒(00..61)
%X 本地时间(e.g.:“15:12:47″)
%Z 时区(e.g.GMT),如果不能检测出时区,值为空
日期格式串
%a 本地简短星期名(e.g.: Sun..Sat)
%A 本地完整星期名(e.g.: Sunday .. Saturday)
%b 本地简短月名(e.g.: Jan .. Dec)
%B 本地完整月名(e.g.: January .. December)
%c 本地日期与时间(e.g.: “Sun Dec 15 14:12:47 GMT 1996″)
%d 一月中的第几日(01 .. 31)
%j 一年中的第几天 (001 .. 366)
%m 月名的数字表示 (01 .. 12)
%U 一年中以星期日为每周第一天计算的星期数(00..53, 第一周包括新年的第一个星期日)
%W 一年中以星期一为每周第一天计算的星期数(00..53, 第一周包括新年的第一个星期一)
%w 星期名的数字表示 (0 .. 6, 0为星期日)
%x 本地日期 (e.g. 今天在北京是: “15/12/96″)
%y 不带世纪的年(00 .. 99)
%Y 带世纪的年(1970 .. 2038)

错误写法

提示:cronolog轮询日志的正确写法,被轮询的日志路径要写全路径

按天轮询(生产环境常见用法,推荐使用)

# 错误写法
CustomLog "|usr/local/sbin/cronolog logs/access_www_%w.log" combined
# 正确写法
CustomLog "|usr/local/sbin/cronolog /app/logs/access_www_%Y%m%d.log" combined

提示:这是大多数网站的常规配置方法(按天记录日志,日志不会自动覆盖)

按小时轮询(生产环境较常见用法)

# 按小时轮询(生产环境较常见用法)
CustomLog "|usr/local/sbin/cronolog /app/logs/access_www_%Y%m%d%H.log" combined
# 按天轮询(生产环境较常见用法)
CustomLog "|usr/local/sbin/cronolog /app/logs/access_www_%Y%m%d.log" combined

完整配置如下

<VirtualHost *:80>
    ServerAdmin test.com@gmail.com
    DocumentRoot "/var/html/blog"
    ServerName blog.etiantian.com
    ErrorLog "logs/blog_error_log"
    CustomLog "|/usr/local/sbin/cronolog  /app/logs/access_blog_%w.log" combined
</VirtualHost>

配置定时任务

# 创建脚本目录
mkdir /server/script/web/ -p

# 创建脚本文件
touch /server/script/web/apache_log.sh

# 编辑脚本内容
cd /app/apache/logs
mv www_access_log /app/logs/www_access_$(date +%F -d '-1day').log
www_access_log
>www_access_log
/app/apache/bin/apachectl graceful
# 添加定时任务
00 00 * * * /bin/sh /server/script/web/apache_log.sh >/dev/null 2>&1

# 测试脚本是否可执行成功
# 如果脚本没有执行权限
$ /server/script/web/apache_log.sh         
-bash: /server/script/web/apache_log.sh: 权限不够

$ /bin/sh /server/script/web/apache_log.sh

# 查看执行结果
$ ll
总用量 0
# 将时间设置为0时
$ date -s '2017-04-20 23:59:00'

# 这时候时23:59查看当天日志是有内容的,并且/app/logs/下面没有文件
$ cat /app/apache/logs/www_access_log 
192.168.59.1 - - [20/Apr/2017:23:59:19 +0800] "GET / HTTP/1.1" 304 - "-" "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0"

# 0时这个时候发现目录生成新日志文件了
$ ll
总用量 4
-rw-r--r--. 1 root root 153 4月  20 23:59 www_access_2017-04-21.log

不记录日志

正如下列配置所示

<FilesMatch '\. (css|js|gif|jpg|ico|swf|png)'>
 	SetEnv IMAG 1
</FilesMatch>

实际日志配置

CustomLog "|/usr/local/sbin/cronolog  /app/logs/access_bbs_%w.log" combined evn=!IMAG

查询日志

awk '{print $1}' www-access_2014-09-18log |sort|uniq -c|sort -rn -k1|head -10

隐藏httpd版本号

步骤1:编译前隐藏版本信息

cat /home/tools/httpd-2.2.27/include/ap_release.h 

找到 #define AP_SERVER_BASEPRODUCT "Apache"

#define AP_SERVER_BASEPRODUCT "Apache"
# 修改为
#define AP_SERVER_BASEPRODUCT "Microsoft-IIS/5.0"

#define AP_SERVER_BASEVENDOR "Apache Software Foundation"
#define AP_SERVER_BASEPROJECT "Apache HTTP Server"
#define AP_SERVER_BASEPRODUCT "Apache"

#define AP_SERVER_MAJORVERSION_NUMBER 2
#define AP_SERVER_MINORVERSION_NUMBER 2
#define AP_SERVER_PATCHLEVEL_NUMBER   27
#define AP_SERVER_DEVBUILD_BOOLEAN    0

找到 cat /home/tools/httpd-2.2.27/os/unix/os.h,修改 #define PLATFORM "Unix" 修改为 #define PLATFORM "Win32"

**步骤3:最后修改 /etc/httpd/conf/httpd.conf **

ServerTokens Prod        # Prod 同 ProductOnly
ServerSignature Off

配置前的响应头

$ curl 127.0.0.1 -I
HTTP/1.1 200 OK
Date: Thu, 20 Apr 2017 16:18:24 GMT
Server: Apache/2.2.27 (Unix) DAV/2

配置如下参数

vi /app/apache/conf/extra/httpd-default.conf
ServerTokens Prod
ServerSignature Off

配置后的响应头

$ curl 127.0.0.1 -I                            
HTTP/1.1 200 OK
Date: Thu, 20 Apr 2017 16:22:19 GMT
Server: Apache

附:

  • ServerSignature 三个选项,分别是 On | Off | EMail
  • ServerTokens 的取值如下,其分别隐藏信息依次增加,推荐: ServerTokens ProductOnly

未经修改的请求头如下

$ curl –head 127.0.0.1
HTTP/1.1 200 OK
Date: Thu, 22 Jan 2015 15:39:00 GMT
Server: Apache/2.2.26 (CentOS)
X-Powered-By: PHP/5.5.9
Vary: Cookie,Accept-Encoding,User-Agent
X-Pingback: http://blog.mimvp.com/xmlrpc.php
Cache-Control: max-age=600
Expires: Thu, 22 Jan 2015 15:49:00 GMT
Content-Type: text/html; charset=UTF-8

上面头信息中,会显示服务器类型和版本(Apache/2.2.26),以及操作系统(CentOS)

修改 ServerTokens

修改 ServerTokens OS 为 ServerTokens productonly

再次返回头信息如下:

$ curl –head 127.0.0.1
HTTP/1.1 200 OK
Date: Thu, 22 Jan 2015 15:40:53 GMT
Server: Apache
X-Powered-By: PHP/5.5.9
Vary: Cookie,Accept-Encoding,User-Agent
X-Pingback: http://blog.mimvp.com/xmlrpc.php
Cache-Control: max-age=600
Expires: Thu, 22 Jan 2015 15:50:53 GMT
Content-Type: text/html; charset=UTF-8

隐藏php版本号

php.ini

expose_php On 改成 expose_php Off

HTTP fastcgi模式启动

编译PHP时候不要使用aspx

注释掉以下,fpm安装方式。不用管,例如下面配置

LoadModule php5_module modules/libphp5.so
<FilesMatch \.php$>
    SetHandler application/x-httpd-php
</FilesMatch>

然后去掉 mod_proxy.somod_proxy_fcgi.so 之前的注解,确保他们被apache加载。

如果php-fpm使用的是TCP socket,那么在httpd.conf末尾加上:

<FilesMatch \.php$>   正则匹配文件,如果文件名为.php结尾
         SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

httpd的工作模式

worker/perfor模式

在linux中,我们可以使用 http-l 查看安装的模块是 prefork 模式还是 worker 模式

$ /app/apache/bin/apachectl -l|sed -n '/worker\|prefork/p'
  prefork.c		#<== 默认为prefork(预派生)模式5个进程
482 Include conf/extra/httpd-mpm.conf  	#<==在httpd.conf中打开mpm配置文件.

prefork模式

prefork使用的是多个子进程,而每个子进程只有一个线程,每个进程在某个确定的时间只能维持一个连接.

工作原理

控制进程最初简历若干个子进程,为了不在请求到来时再生成子进程,所以要根据需求不断的创建新的子进程,最大可以达到每秒32个知道满足需求为止.

安装方法:在编译的过程中,加入参数 --with-mpm=prefork 如果不加也可以,因为默认的话,会采用 prefork模式。

  • 优点:效率高,稳定,安全。对于线程调试困难的平台来说,调试更加容易些.
  • 缺点:和work模式比消耗资源多.

image-20221202173701200

prefork配置参数说明

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxRequestWorkers: maximum number of server processes allowed to start
# MaxConnectionsPerChild: maximum number of connections a server process serves
#                         before terminating
<IfModule mpm_prefork_module>
    StartServers           	1 	#<==最初建立的子进程
    MinSpareServers          	1	#<==最小空闲进程数,如果空闲进程小于设定值,apache会自动建立进程,如果服务器并发及负载大的话,可以考虑加大。
    MaxSpareServers          	2	#<==最大空闲进程,如果空闲的进程大于设定值,apache会自动kill掉多余的进程,如果服务器负载大的话,可以考虑加大
    MaxRequestWorkers        	20	#<==设定apache可以同时处理的请求,是对apache性能影响最大的参数,就是apache可以同时处理的请求数,就是说,如果有150个用户在访问,那么第151个用户就要等之前的访问结束后才能访问
    MaxConnectionsPerChild   	0	#<==每个子进程可处理的请求数。每个子进程在处理了[max requests perchild] 个请求后将自动销毁。0意味着无限,即子进程永不销毁,虽然缺省值为0,可以使每个子进程处理更多的请求,但如果设成非0值也有两点重要好处1.可防止意外的内存泄露2.在服务器负载下降的时候会自动减少子进程数
</IfModule>

worker模式

worker模式是 Apache2.X 新引进来的模式,是线程与进程的结合,在worker模式下会有多个子进程,每个进程又会有多个线程。每个线程在某个确定的时间只能维持一个连接。

工作原理

由主控制进程生成若干个子进程,而每个子进程中又包含固定的线程数,各个线程独立处理请求,同样为了不在请求到来时再生成线程,再配置文件中设置了最小和最大的空闲线程数及所有子进程中的线程总数,如果现有子进程中的线程总数不能满足并发及负载,控制进程将派生新的子进程。

在配置编译的过程中,加入参数 --with-mpm-worker,如果不加的话系统会采用默认prefork模式。

  • 优点:内存占用比prefork模式低,适合高并发高流量HTTP服务。
  • 缺点:假如一个线程崩溃,整个进程就会连同其任何线程一起 “死掉”。由于线程贡献内存空间,所以一个程序在运行时必须被系统识别为“每个线程都是安全的”服务稳定性不如prefork模式。

image-20221202174118478

worker 模式配置参数说明

# worker MPM
# StartServers: initial number of server processes to start
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestWorkers: maximum number of worker threads
# MaxConnectionsPerChild: maximum number of connections a server process serves
#                         before terminating
<IfModule mpm_worker_module>
    StartServers             	3	#<==最初建立的子进程
MinSpareThreads         	75	#<==最小空闲线程数,如果空闲的线程小于设定值,apache会自动建立线程,如果服务器负载大的话,可以考虑加大此参数值。
MaxClients #<==所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。
MaxSpareThreads        	250  #<==最大空闲线程数,如果空闲的线程大于设定值,apache会自动kill掉多余的线程,如果服务器负载过大的话,可以考虑加大此参数值。   
ThreadsPerChild         	25	#<==每个进程包含固定的线程数,此参数再worker模式中,是影响最大的参数
MaxRequestWorkers      	400	    
MaxConnectionsPerChild   	0Threads
</IfModule>

worker模式下所能同时处理的请求总数是由子进程总数乘Threadsperchild值决定的,应该大于等于maxcliens。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。

默认最大的子进程总数是16,如需加大时,也需要显式声明serverlimit的值(最大值是20000)

特别说明

如果显式生命了serverLimit,那么它乘 ThreadPreChild 的值必须大于等于MaxClients,而且MaxClients必须是ThreadPerChild的整数倍,否则Apache将会自动调节Apache将会自动调节到一个相应的值(可能是个非常期望值)

通过数学表达

MaxClient <= 总的进程(ServerLimit)* 线程数(ThreadsPerChild)、

MaxClient % ThreadsPerChild = 0

注意:worker MPM也有不完善的地方,如果一个线程崩溃,整个进程就会连同其所有线程一起 “死掉”

配置httpd对站点文件压缩

mod_deflate模块介绍

Apache的 mod_deflate 模块提供了 Deflate 输出过滤器,允许httpd服务器将输出内容在发送到客户端之前根据具体的策略进行压缩,以节约网络带宽,同时提升用户访问体验。

mod_deflate 模块安装方法

检查是否安装了模块 mod_deflate

$ /app/apache/bin/apachectl -l
Compiled in modules:
  core.c
  mod_so.c
  http_core.c
  prefork.c

常规方法安装

--enable-deflate 提供对内容的亚索传输编码支持,一般html js css等内容站点,使用此参数功能会大大提高传输速度,提升访问者访问体验。在生产环境中,这是 httpd 调优的一个重要选项之一。

mod_deflate DSO安装方法

以DSO动态模块加载mod_deflate配置的全部命令为

cd /root/tools/httpd-2.4.18/modules/filters	#<==切换到apache软件目录mod_deflate程序下
/app/apache/bin/apxs  -c -i -a mod_deflate.c #<==以dso的方式编译入到apache中

出现如下错误

httpd: Syntax error on line 103 of /app/apache2.4/conf/httpd.conf: Cannot load modules/mod_deflate.so into server: /app/apache2.4/modules/mod_deflate.so: undefined symbol: inflateEnd

解决方法:

出现这个错误其实时因为 mod_deflate 模块没有找到 zlib 库。解决办法就是找到 apr-config 文件中的LDFLAGS="",把他改成 LDFLAGS="-lz" ,然后在运行 /usr/local/apache2/bin/apxs -i -c -a mod_deflate.c 一般就可以了。

方法1:在apr的主配置文件 apr-1-config(老版本可能是apr-conf)里面将 LDFLAGS="" 修改为 LDFLAGS="-lz",然后用 apxs 从新编译 mod_deflate.c 后,httpd 服务就正常了,并且也可以正常压缩文件了。

方法2:需要在 LoadModule deflate_module modules/mod_deflate.so 的前面加载 zlib.so64 操作系统就在 LoadModule deflate_module modules/mod_deflate.so 这行的上一行添加 LoadFile /usr/lib64/libz.so即可。

上述参数选项说明

参数  说明
-c              需要执行编译操作。他首先会编译C源码程序(.c)files为对应的目标代码文件(.o),然后连接这些目标代码和files中其余的目标代码文件(.o和.a),以生成动态共享对象dsofile。如果没有指定-o选项,则此输出文件名由files中的第一个文件名推测得到,也就是默认为mod_name.so
-i                                           需要执行安装操作,以安装一个或多个共享对象到服务器的modules目录中。
-a 增加一个LoadMoudule行到httpd.conf文件中,以激活此模块

mod_deflate测试

mod_deflate模块可以在主配置文件中配置,也可以在虚拟主机中配置

在主http.conf配置中配置如下:

<ifmodule mod_deflate.c> # <==开始标签标记 判断模块是否开启
    DeflateCompressionLevel 6 # <==压缩级别 1-9
    SetOutputFilter DEFLATE	# <==启用deflate模块对本站点的所有输出进行GZIP压缩
    AddOutputFilterByType Deflate text/html test/pain text/xml text/css 	
    AddOutputFilterByType Deflate application/javascript
</ifmodule> # <==判断结束标记

image-20221202180518764

mod_expires 缓存功能

mod_expires允许通过apache配置文件控制 HTTP “Expires:” 和 “Cache-Control:” 头内容,这个模块控制服务器应答时的Expires头内容和Cache-Control头的max-age指令。有效期可以设置为相对于源文件的最后修改时刻或者客户端的访问时刻。

这些HTTP头向客户端表明了内容的有效性和持久性。如果客户端本地有缓存,则内容就可以从缓存(除非过期)而不是从服务器读取。人后客户端会检查缓存中的副本,看看是否过期或者失效,以决定是否重新从服务器获得内容更新。

常规方法安装

–enable-deflate

提供对内容的亚索传输编码支持,一般html js css等内容站点,使用此参数功能会大大提高传输速度,提升访问者访问体验。在生产环境中,这是Apache调优的一个重要选项之一。

以DSO动态模块加载mod_deflate配置的全部命令为:

cd /root/tools/httpd-2.4.18/modules/metadata#<==切换到apache软件目录mod_expires程序下
/app/apache/bin/apxs  -c -i -a mod_expires.c #<==以dso的方式编译入到apache中

mod_expires在httpd中应用

在主配置文件中配置,所有的虚拟主机都生效,在对应的虚拟主机上配置,只有对应的虚拟主机生效

<ifmodule expires_module>
    ExpiresActive on
    ExpiresDefault "access plus 12 months"
    ExpiresByType test/html "access plus 1 years"
    ExpiresByType test/css "access plus 1 years"
    ExpiresByType test/xml "access plus 1 years"
    ExpiresByType test/php "access plus 1 years"
    ExpiresByType image/gif "access plus 30 days"
    #ExpiresByType image/jpeg "access plus 30 days"
    #ExpiresByType image/jpg "access plus 30 days"
    ExpiresByType image/jpeg A7200000
	ExpiresByType image/png "access plus 30 days"
    ExpiresByType application/javascript "access plus 30 days"
    ExpiresByType application/x-javascript "access plus 30 days"
    ExpiresByType image/png "access plus 30 days"
</ifmodule>

image-20221202180534378

配置httpd防盗链功能

httpd Web服务实现防盗链

利用referer和rewrite实现Apache防盗链调用,在主配置文件 httpd.conf 或者在虚拟主机 httpd-vhosts.conf 中配置如下

RewriteEngine ON	
RewriteCond %{HTTP_REFERER} !^http://www.test.com/.*$ [NC] #<==此处,如果加http://就必须加^,否则直接写servername即可 如下
RewriteCond %{HTTP_REFERER} !http://www.test.com [NC]
RewriteCond %{HTTP_REFERER} !^http://www.test.com$ [NC]
RewriteCond %{SCRIPT_FILENAME} !nolink.png [NC]#<==为防止无限302,文件名如果为nolink.png即不重写
RewriteRule .*\.(gif|jpg|swf|png)$ img/nolink.png [R,NC,L] #<==重写时,必须加R

访问查看结果

image-20221202174359240

用原本的域名访问,可直接访问

image-20221202174426073

httpd常用Rewrite标志

flag 说明
Chain|C 如果当前规则被匹配,则继续处理其后继规则,如果当前规则不被匹配, 则其后继规则将被跳过。
forbidden|F 强制禁止当前URL的响应,并向客户端发送一个403的HTTP响应代码。
gone|G 强制废弃当前URL,向客户端发送一个410的HTTP响应代码,来表明此URL是已被废弃的。
handler|H=Content-handler 为需要处理的目标文件强制指定一个内容处理器。
last|L 停止标志,当mod_rewrite模块处理到此标志时会停止重写搡作,并不再应用其他重写规则。此标志通常用于跳出规则处理。
next|N 循环重写规则,从第一个规则开始再次执行重写规则,但此时处理的URL己经不是原始的URL.它相当于Perl语言中的next命令。
nocase|NC 忽略Pattern中的大小写。
Noescape|NE 使用此标记可以让URL中允许使用一些特殊字符,例如,‘T’、‘%’、‘;’等,如果不使用此标记则是将这些特殊字符转换成等值的16进制编码如‘%25’、‘%24’、‘%3B’等。
nosubreq|NS 不对内部子请求进行处理,使用此标记如果是内部子请求,则跳过当前规则。通常使用CGI脚本的子请求会出现一些问题,因此可以使用些标记来 禁止子请求。
proxy|P 强制重写的URL在内部由代理服务器模块来处理,并中断重写过程。使用这个标记要注意的是需要保证代理模块已经被加载,同时替换的字串是一个能被代理模块处理的有效的URL,否则代理模块将会返回一个错误的信息。
Passthiough|PT 将此URL强制交给下一个处理器来进行处理,而在转交之前, mod_rewrite模块会将内部request_rec结构中的URL字段设置为filename字段的值,这使得RewriteRule指令的输出能够被(从URL转换到文件名的)Alias、 ScriptAlias、Redirect等指令进行后续处理。
Qsappend|QSA 你可以通过此标记在现有的替换字符串中增加一个査询字符串, 注意:是增加而不是替换。
将重写的URL作为一个重定向处理,在使用这个标记时,必须确保该替换字段是一个有效的URL。否则,它会指向一个无效的位置,并且此 标记本身只是对URL加上http://thishost[:thisport]/前缀。如果没有在此标记后面指 定HTTP响应代码则会使用302 (临时性移动)这个响应代码来进行处理。用户可指定的响应代码范围为300〜400,或是使用符号化的名称,例如,temp、seeother 等。
redirect|R[=code] 将重写的URL作为一个重定向处理,在使用这个标记时,必须确保该替换字段是一个有效的URL。否则,它会指向一个无效的位置,并且此 标记本身只是对URL加上 http://thishost[:thisport]/ 前缀。如果没有在此标记后面指 定HTTP响应代码则会使用302 (临时性移动)这个响应代码来进行处理。用户可指定的响应代码范围为300〜400,或是使用符号化的名称,例如,temp、seeother 等。
skip|S=num 与chain|C标记不同,使用此标记将强制跳过后继的规则,用户可以通过此标记来模拟if-then-else结构,最后一个规则是then从句,而被跳过的skip=N 个规则是else从句。
type|T=MIME-type 强制目标文件的MIME类型为MIME-type所指定的类型。

禁止资源目录解析PHP程序

方案1:提示下载不解析

<Directory "/app/apache-2.4.18/htdocs/php">
AllowOverride None
Options None
Require all granted
php_admin_flag engine off #<==禁止解析php文件,此参数必须apex方式安装才存在。反之报错
</Directory>
image-20221202175111862

php_admin_flag engine off 这个语句就是禁止解析 php 的控制语句,但只这样配置还不够,因为这样配置后用户依然可以访问 php 文件,只不过不解析了,但可以下载,用户下载 php 文件也是不合适的,所以有必要再禁止一下。

image-20221202175148577

禁止目录索引浏览功能

默认配置当网站没有首页文件时,httpd会把整个目录结构展示给网站用户,这是非常大的隐患,必须要屏蔽掉。

image-20221202175604755

在主配置文件 httpd.conf 或者虚拟主机的配置文件 httpd-vhost.conf 文件配置如下内容即可

<Directory "/app/apache-2.4.18/htdocs">
    Options FollowSymLinks
    AllowOverride None
    Require all granted
    Allow from all
</Directory>

<Directory "/app/apache-2.4.18/htdocs">
    Options -Indexes FollowSymLinks
    AllowOverride None
    Require all granted
    Allow from all
</Directory>

更改之后出现403权限问题,说明禁止了目录索引功能

关闭无用的CGI功能配置

304 <IfModule alias_module>
305     #
306     # Redirect: Allows you to tell clients about documents that used to 
307     # exist in your server's namespace, but do not anymore. The client 
308     # will make a new request for the document at its new location.
309     # Example:
310     # Redirect permanent /foo http://www.example.com/bar
311 
312     #
313     # Alias: Maps web paths into filesystem paths and is used to
314     # access content that does not live under the DocumentRoot.
315     # Example:
316     # Alias /webpath /full/filesystem/path
317     #
318     # If you include a trailing / on /webpath then the server will
319     # require it to be present in the URL.  You will also likely
320     # need to provide a <Directory> section to allow access to
321     # the filesystem path.
322 
323     #
324     # ScriptAlias: This controls which directories contain server scripts. 
325     # ScriptAliases are essentially the same as Aliases, except that
326     # documents in the target directory are treated as applications and
327     # run by the server when requested rather than as documents sent to the
328     # client.  The same rules about trailing "/" apply to ScriptAlias
329     # directives as to Alias.
330     #
331     ScriptAlias /cgi-bin/ "/app/apache-2.4.18/cgi-bin/"
332 
333 </IfModule>

<Directory "/app/apache-2.4.18/htdocs/bbs">
    Options FollowSymLinks
    AllowOverride None
 	Order allow,deny
    Allow form all
 </Directory>

禁止httpd用户重载功能

<Directory "/app/apache-2.4.18/htdocs">
    Options -Indexes FollowSymLinks
    AllowOverride None		#<==禁止用户重载
    Require all granted
    Allow from all
</Directory>

禁止用户重载会加快服务器响应速度,因为它不在为每个请求寻找每个目录访问控制文件(.htaccess)。也杜绝了开发人员变相修改配置的安全隐患

避免使用.htaccess文件

在Apache中,AllowOvCTride 指令来设置是否启用 .htaccess 文件功能。但是对于一些管理员来说,更简单更精细化的控制目录可以为他们节省很多的时间,于是 .htaccess 文件提供了一个这样的功能,你可以使用默认AllowOverride指令是使用None参数来禁止使用.htaccess文件功能。

可使用参数:

* All:使用所有能在.htaccess文件中使用的指令.
* AuthConfig:使用鉴权指令,例如,AuthName、AuthType 等.
* FileInfo:使用控制文件类型的指令,例如,ErrorDocument、SetOutputFilter等. 
* Indexes:使用目录索引指令.
* Options:使用控制目录功能指令.
* Limit:使用主机访问控制指令.

注意:

.htaccess 文件会导致服务器性能的急速(如果服务器上有很多目录,且每层目录下都有.haccess文件)下降,在使用了AllowOverride指令允许使用 .htaccess 文件后,无论是否使用 .htaccess 文件,httpd都会在每个目录下查找 .htaccess 文件。其次,当每个请求链接到来时,httpd 会查找链接所请求目录下的 .htaccess 文件,并且再査找它的上级目录中的 .htaccess 文件以使 .htaccess 文件内的设置都能生效。这些査找会让httpd 性能降低很多。另外还有安全方面的问题,.htaccess 文件可以修改和覆盖服务器的指令,因此会产生一些未被限制的修改,而这些修改将会导致一些安全问题的出现。

如何对httpd配置优化?

  • 配置软件软件轮训Apache访问日志
  • 优化访问日志记录的信息
  • 配置HTTP错误页面优雅显示
  • 配置 httpd 对站点文件压缩
  • Mod_Expires缓存功能
  • 更改 httpd 默认用户
  • 调整 httpd 的工作模式
  • 屏蔽 httpd 对外显示的版本等敏感信息
  • 屏蔽 httpd 对外显示的版本等敏感信息
  • 最小化 httpd 目录及文件权限设置
  • 最小化 httpd 日志目录权限
  • 加大 httpd 并发连接数
  • 配置 httpd 防盗链功能
  • 禁止 httpd 目录索引浏览功能
  • 禁止 httpd 用户重载功能
  • 避免使用.htaccess文件
  • 关闭无用的CGI功能配置
  • 禁止资源目录解析PHP程序
  • 使用TMPFS文件系统替代频繁访问的目录
  • 尽可能减少HTTP请求
  • 使用CDN左网站加速
  • httpd 程序架构优化
  • httpd 的安全模块
  • 正确途径取得源代码,勤打 httpd 补丁
  • 系统内核参数优化
  • 配置Mod_Pagespeed优化Web性能
  • 防止用户请求跳出Web站点目录

本文发布于Cylon的收藏册,转载请著名原文链接~

链接:https://www.oomkill.com/2016/10/apache-httpd/

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」 许可协议进行许可。