缓存是一种通过允许更快访问的方式临时存储共同请求的内容来提高服务器性能的方法。通过减少一些资源密集型操作来加速处理和交付。
通过创建有效的缓存规则,存储适合缓存的内容,以缩短响应时间,节省资源并最大限度地减少负载。Apache提供了各种适用于加速不同类型操作的缓存。在本教程中,我们将讨论如何使用各种缓存模块在CentOS 7上配置Apache 2.4。
Apache可以缓存具有不同复杂程度和可伸缩性的内容。项目根据缓存内容的方法将这些分为三组。一般细分是:
快速浏览上述描述可能会发现上述方法有一些重复,但同时使用多个策略会有所帮助。例如,为SSL会话使用键值存储并为标准HTTP缓存响应启用可以让您减少数据源负载并加快客户端许多内容的交付操作。
既然您已经对Apache的每个缓存机制有了广泛的了解,那么让我们更详细地看一下这些系统。
该mod_file_cache模块主要用于加速文件系统较慢的服务器上的文件访问。它提供了两种配置指令的选择,这两种配置指令旨在通过在启动服务器时执行某些工作而不是在请求文件时加速提供静态文件的过程。
该CacheFile指令用于指定您希望加速访问的磁盘上文件的路径。当Apache启动时,Apache将打开指定的静态文件并缓存文件处理,从而无需在请求时打开文件。以这种方式可以打开的文件数受操作系统设置的限制。
该MMapFile指令还会在首次启动Apache时打开文件。但是,MMapFile将文件的内容缓存在内存中而不仅仅是文件处理程序中。这样可以提高这些页面的性能,但它有一些严重的局限性。它没有记录它使用的内存量,因此可能会耗尽内存。另请注意,子进程将复制任何已分配的内存,这可能导致比您最初预期的更快的耗尽资源。需要谨慎使用这个指令。
仅在Apache启动时才会评估这些指令。这意味着您不能依赖Apache来获取启动后所做的更改。仅在静态文件上使用这些文件,这些文件在Apache会话的生命周期内不会更改。根据文件的修改方式,可能会向服务器通知更改,但这不是预期的行为,并且不会始终正常工作。如果必须对传递给这些指令的文件进行更改,请在完成更改后重新启动Apache。
文件缓存由mod_file_cache模块提供。要使用此功能,您需要启用该模块。
运行CentOS 7时,将在安装Apache时安装该模块,但默认配置不会加载模块。要加载模块,我们将在/etc/httpd/conf.modules.d目录中创建一个简单文件来加载模块。我们称之为00-cache.conf:
- sudo nano /etc/httpd/conf.modules.d/00-cache.conf
在内部,我们需要使用该LoadModule指令来启用我们需要的功能。将以下行添加到文件中:
- LoadModule file_cache_module modules/mod_file_cache.so
完成后保存并关闭文件。
之后,您应编辑主配置文件以设置文件缓存指令。输入以下命令打开文件:
- sudo nano /etc/httpd/conf/httpd.conf
要设置文件处理缓存,请使用该CacheFile指令。该指令后跟文件路径列表,用空格分隔,如下所示:
- CacheFile /var/www/html/index.html /var/www/html/somefile.index
重新启动服务器后,Apache将打开列出的文件并将其文件处理存储在缓存中,以便更快地访问。
相反,如果您希望将几个文件直接映射到内存中,则可以使用该MMapFile指令。它的语法与最后一个指令基本相同,因为它只需要一个文件路径列表:
- MMapFile /var/www/html/index.html /var/www/html/somefile.index
在实践中,就没有必要配置CacheFile和MMapFile同组的文件,但你可以同时使用不同的文件集。
完成后,您可以保存并关闭文件。输入以下命令检查配置文件语法:
- sudo apachectl configtest
如果最后一行读取Syntax OK,您可以安全地重新启动Apache实例:
- sudo systemctl restart httpd
Apache将重新启动,根据您使用的指令缓存文件内容或处理程序。
键值缓存比文件缓存更复杂,并且具有更多的重要优势。Apache的键值缓存也称为共享对象缓存,主要用于避免重复设置客户端对内容的访问所涉及的复杂操作,而不是内容本身。具体来说,它可用于缓存身份验证详细信息,SSL会话以及提供SSL装订。
注意
目前,每个共享对象缓存提供程序都存在一些问题。下面将概述对这些问题的参考。在评估是否启用此功能时,请考虑这些因素。
实际的缓存是通过使用其中一个共享对象缓存提供程序模块来完成的。这些是:
根据要缓存的对象,结合上述提供程序模块,还需要其他模块。例如,要启用SSL会话或配置SSL装订,必须启用mod_ssl,它们将分别提供SSLSessionCache和SSLStaplingCache指令。同样,要设置身份验证缓存,必须启用该mod_authn_socache模块,以便AuthnCacheSOCache可以设置该指令。
考虑到上述错误和警告,如果您仍希望在Apache中配置此类缓存,请按照下面的说明进行操作。
用于设置键值缓存的方法取决于它将用于什么以及提供给您使用的程序。我们将在下面介绍身份验证缓存和SSL会话缓存的基础知识。
目前,身份验证缓存存在一个错误,该错误会阻止将参数传递给缓存提供程序。因此,任何不提供默认设置的提供商都会遇到问题。
如果使用昂贵的身份验证方法(如LDAP或数据库身份验证),则身份验证缓存很有用。如果每次发出身份验证请求时都必须命中后端,则这些类型的操作会对性能产生重大影响。
设置缓存涉及修改现有的身份验证配置(我们不会在本教程中介绍如何设置身份验证)。无论后端身份验证方法如何,修改本身都将大致相同。我们将mod_socache_shmcb用于演示。该模块已在我们的/etc/httpd/conf.modules.d/00-base.conf文件中启用。
打开主Apache配置文件,以便指定此共享缓存后端以用于身份验证:
- sudo nano /etc/httpd/conf/httpd.conf
在内部,在文件顶部添加AuthnCacheSOCache指令。指定shmcb应该用作提供者。如果之前讨论的阻止选项传递的错误在您阅读本文时已得到修复,则可以指定缓存的位置和大小。该数字以字节为单位,因此注释示例将产生512 KB的缓存:
- AuthnCacheSOCache shmcb
-
- # If the bug preventing passed arguments to the provider gets fixed,
- # you can customize the location and size like this
- #AuthnCacheSOCache shmcb:${APACHE_RUN_DIR}/auth_cache(512000)
完成后保存并关闭文件。
接下来,打开已配置身份验证的虚拟主机配置页面。我们假设您正在使用位于/etc/httpd/conf.d目录中的虚拟主机配置site.conf,但您应该对其进行修改以映射您的环境:
- sudo nano /etc/httpd/conf.d/site.conf
使用身份验证设置的基本虚拟主机应该如下所示:
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- <Directory /var/www/html/private>
- AuthType Basic
- AuthName "Restricted Files"
- AuthUserFile /etc/httpd/.htpasswd
- AuthBasicProvider file
- Require valid-user
- </Directory>
- </VirtualHost>
在您配置身份验证的位置,修改块以添加缓存。具体来说,您需要添加AuthnCacheProvideFor以告知它要缓存哪些身份验证源,添加缓存超时AuthnCacheTimeout,并在传统身份验证方法之前添加socache到AuthBasicProvider列表中。结果将如下所示:
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- <Directory /var/www/html/private>
- AuthType Basic
- AuthName "Restricted Files"
- AuthUserFile /etc/apache/.htpasswd
- AuthBasicProvider socache file
- AuthnCacheProvideFor file
- AuthnCacheTimeout 300
- Require valid-user
- </Directory>
- </VirtualHost>
上面的示例用于文件身份验证,这可能不会从缓存中受益。但是,使用其他身份验证方法时,设置应该非常相似。唯一的实质区别在于上面示例中的“文件”规范,而是使用其他身份验证方法。
保存并关闭文件。输入以下内容检查更改是否存在语法错误
- sudo apachectl configtest
如果未找到语法错误,请重新启动Apache以实现缓存更改:
- sudo systemctl restart httpd
必须执行以建立SSL连接的握手会带来很大的开销。因此,缓存会话数据以避免针对进一步请求的该初始化步骤可以避免这种弊端。共享对象缓存是一个完美的地方。
如果已为Apache服务器配置了SSL,mod_ssl则将启用(如果没有,则用于yum安装mod_ssl模块)。在CentOS 7上,这意味着/etc/httpd/conf.d目录中将有一个ssl.conf可用文件。这实际上已经设置了缓存。在里面,你会看到一些像这样的行:
- . . .
-
- SSLSessionCache shmcb:/run/httpd/sslcache(512000)
- SSLSessionCacheTimeout 300
-
- . . .
这实际上足以设置会话缓存。要测试它,您可以使用OpenSSL的连接客户端。类型:
- openssl s_client -connect 127.0.0.1:443 -reconnect -no_ticket | grep Session-ID
如果所有结果中的会话ID相同,则会话缓存正常运行。按CTRL-C退出到终端。
HTTP协议鼓励并提供用于在内容传递路径上缓存响应的机制。任何触摸内容的计算机都可能会在一定时间内缓存每个项目,具体取决于内容来源和计算机自己的缓存规则中规定的缓存策略。
Apache HTTP缓存机制根据它看到的HTTP缓存策略缓存响应。这是一个通用的缓存系统,遵循与任何中间服务器遵循的交付相同的规则。这使得该系统非常灵活和强大,并允许您利用您应该已经在内容上设置的标题(我们将在下面介绍如何执行此操作)。
Apache的HTTP缓存也称为“三态”缓存。这是因为它存储的内容可以处于三种状态之一。它可以是最新的,这意味着它可以被提供给客户端而无需进一步检查,它可能是陈旧的,这意味着内容上的TTL已过期,或者如果在缓存中找不到内容则它可能不存在。
如果内容变得陈旧,则在下一个请求时,缓存可以通过检查原点的内容来重新验证它。如果它没有改变,它可以重置新鲜度日期并提供当前内容。否则,它将获取已更改的内容并将其存储在其缓存策略允许的时间长度内。
HTTP缓存逻辑可通过该mod_cache模块获得。实际的缓存是由一个缓存提供程序完成的。通常,缓存使用mod_cache_disk模块存储在磁盘上,但共享对象缓存也可通过mod_cache_socache模块获得。
该mod_cache_disk模块在磁盘上进行缓存,因此,如果您从远程位置代理内容,从动态进程生成内容,或者只是通过在比内容通常驻留的速度更快的磁盘上缓存来加速速度,这将非常有用。这是经过最充分测试的提供商,在大多数情况下应该是您的首选。缓存不会自动清理,因此必须偶尔运行一个名为htcacheclean的缓存工具。这可以手动运行,设置为常规cron作业或作为守护程序运行。
该mod_cache_socache模块缓存到其中一个共享对象提供程序(与上一节中讨论的相同)。这可能具有比mod_cache_disk(选择哪个共享缓存提供程序)更好的性能。但是,它更新并且依赖于共享对象提供程序,它们具有前面讨论的错误。在实施该mod_cache_socache选项之前,建议进行全面测试。
Apache的HTTP缓存可以根据您的需要部署在两种不同的配置中。
如果将CacheQuickHandler设置为“on”,则将在请求处理过程中尽早检查缓存。如果找到了内容,它将直接提供,无需进一步处理。这意味着它非常快,但也意味着它不允许对内容进行身份验证等过程。如果缓存中的内容通常需要身份验证或访问控制,则任何未经身份验证的人都可以访问该内容CacheQuickHandler(如果设置为“on”)。
基本上,这会在Web服务器前模拟单独的缓存。如果您的Web服务器需要进行任何类型的条件检查,身份验证或授权,则不会发生这种情况。Apache甚至不会评估其中的指令<Location>或<Directory>块。请注意,默认情况下CacheQuickHandler设置为“on” !
如果将CacheQuickHandler其设置为“off”,则将在请求处理序列中稍后检查高速缓存。可以将此配置视为将缓存放在Apache处理逻辑和实际内容之间。这将允许在从高速缓存检索内容之前运行传统处理指令。将此设置为“off”会以更快的速度进行交易,以便更深入地处理请求。
为了启用缓存,您需要启用mod_cache模块以及其中一个缓存提供程序。如上所述,mod_cache_disk经过充分测试,所以我们依赖于此。
在CentOS 7系统上,该htcacheclean实用程序在httpd安装过程中安装,用于在缓存增长时削减缓存。默认情况下包含一个被systemd调用的单元文件htcacheclean.service。
如果您计划设置缓存,最好将此服务配置为自动运行。服务文件实际上是守护服务,以可配置的间隔运行清理操作。但是,默认情况下,Apache启动时没有启动它的机制。
要使用此功能,我们将在/etc/systemd/system目录下创建一个名为httpd.service.requires的目录。这可以用于指定httpd.service启动Apache 的单元文件的依赖关系:
- sudo mkdir -p /etc/systemd/system/httpd.service.requires
之后,我们可以将htcacheclean.service单元文件链接到此目录中。这将导致htcacheclean服务在Apache启动时启动和定期清理缓存:
- sudo ln -s /usr/lib/systemd/system/htcacheclean.service /etc/systemd/system/httpd.service.requires
您可以通过编辑目录/etc/sysconfig中的htcacheclean文件来配置htcacheclean选项,包括清除间隔:
- sudo nano /etc/sysconfig/htcacheclean
在这里,您可以修改清理间隔,缓存根目录,最大缓存大小以及该实用程序的其他任意选项:
- INTERVAL=15
- CACHE_ROOT=/var/cache/httpd/proxy
- LIMIT=100M
- OPTIONS=
注意
如果更改了CACHE_ROOT值,则需要调整我们将在Apache配置中设置的CacheRoot指令的值。
完成后,保存并关闭文件。
重启Apache以启动htcacheclean自动清理缓存:
- sudo systemctl restart httpd
大多数缓存配置将在单个虚拟主机定义或位置块中进行。但是,还有一些全局配置项应该用于设置一些常规属性。打开主Apache配置文件以配置以下项目:
- sudo nano /etc/httpd/conf/httpd.conf
我们需要添加CacheRoot目录以指向应该用于存储缓存项的路径。这应始终与/etc/sysconfig/htcacheclean文件中CACHE_ROOT找到的值匹配,以便可以正确管理缓存。我们还将设置CacheDirLevels和CacheDirLength指令,它们都有助于定义如何构建缓存目录结构:
- CacheRoot /var/cache/httpd/proxy
- CacheDirLevels 2
- CacheDirLength 1
CacheDirLevels和CacheDirLength都致力于限定缓存目录结构将如何构建。将创建正在提供的URL 的md5哈希值作为用于存储数据的密钥。数据将被组织成从每个哈希的起始字符派生的目录。CacheDirLevels指定要创建的子目录的数量,并指定要用作每个目录的名称的字符数。因此,具有上面显示的默认值的b1946ac92492d2347c6235b4d2611184散列将被归档到b/1/946ac92492d2347c6235b4d2611184目录结构中。通常,您不需要修改这些值,但最好知道它们的用途。
你可以在这个文件中设置一些其他值,例如CacheMaxFileSize和CacheMinFileSize,设定在Apache将提交到高速缓存的文件大小的范围,CacheReadSize和CacheReadTime也同样,它允许你等待并发送到客户端之前缓冲区的内容。如果内容位于此服务器以外的其他位置,则此选项非常有用。
大多数缓存配置将在更精细的级别上进行,无论是在虚拟主机定义中还是在特定位置块中。
打开一个要跟随的虚拟主机文件。我们假设你正在使用本教程目录/etc/httpd/conf.d中的一个名为site.conf的文件:
- sudo nano /etc/httpd/conf.d/site.conf
在虚拟主机块中,在任何位置块之外,我们可以开始配置一些缓存属性。在本教程中,我们假设我们要关闭CacheQuickHandler ,以便完成更多处理。这使我们可以获得更完整的缓存规则。
我们还将借此机会配置缓存锁定。这是一个文件锁系统,Apache在使用内容源检入时将使用该系统来查看内容是否仍然有效。在满足此查询的时间内,如果对相同内容的其他请求进入,则会导致对后端资源的其他请求,这可能导致负载高峰。
在验证期间为资源设置缓存锁定会告知Apache当前正在刷新资源。在此期间,可以使用指示其状态的警告标头来提供过时资源。我们将在/tmp文件夹中设置缓存锁定目录。我们将允许锁定最多5秒钟才能被视为有效。这些示例直接来自Apache的文档,因此它们应该适用于我们的目的。
我们还将告诉Apache忽略Set-Cookie标头而不将它们存储在缓存中。这样做可以防止Apache意外地将用户特定的cookie泄露给其他方。该Set-Cookie标头被缓存之前将被剥离。
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- CacheQuickHandler off
-
- CacheLock on
- CacheLockPath /tmp/mod_cache-lock
- CacheLockMaxAge 5
-
- CacheIgnoreHeaders Set-Cookie
- </VirtualHost>
我们仍然需要为这个虚拟主机实际启用缓存。我们可以使用该CacheEnable指令执行此操作。如果在虚拟主机块中设置了这个,我们需要提供缓存方法(disk或socache)以及应缓存的请求URI。例如,要缓存所有响应,可以将其设置为CacheEnable disk /,但如果您只想在/publicURI 下缓存响应,则可以将其设置为CacheEnable disk /public。
我们将通过在特定位置块中启用缓存来采用不同的方法。这样做意味着我们不必提供CacheEnable命令的URI路径。将缓存从该位置提供的任何URI。我们还将打开该CacheHeader指令,以便我们的响应标头将指示缓存是否用于提供请求。
我们设置的另一个指令是CacheDefaultExpire,如果内容上既没有设置Expires头文件也没有设置Last-Modified头文件,我们可以设置一个到期时间(以秒为单位)。同样,我们将设置CacheMaxExpire限制项目的保存时间。我们将设置为CacheLastModifiedFactor ,如果Apache具有Last-Modified日期但没有到期,则可以创建到期日期。该因子乘以自修改后的时间以设置合理的到期时间。
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- CacheQuickHandler off
-
- CacheLock on
- CacheLockPath /tmp/mod_cache-lock
- CacheLockMaxAge 5
-
- CacheIgnoreHeaders Set-Cookie
-
- <Location />
- CacheEnable disk
- CacheHeader on
-
- CacheDefaultExpire 600
- CacheMaxExpire 86400
- CacheLastModifiedFactor 0.5
- </Location>
- </VirtualHost>
在配置了所需的所有内容后,保存并关闭文件。
输入以下内容检查整个配置是否存在语法错误
- sudo apachectl configtest
如果未报告任何错误,请输入以下命令重新启动服务:
- sudo systemctl restart httpd
在上面的配置中,我们配置了HTTP缓存,它依赖于HTTP标头。但是,我们所服务的内容实际上并不具备进行智能缓存决策所需的Expires或Cache-Control标头。要设置这些标头,我们需要利用更多的模块。
该mod_expires模块可以在Cache-Control标题中设置Expires标题和max-age选项。该mod_headers模块可用于添加更多特定Cache-Control选项以进一步调整缓存策略。默认情况下,这两个模块都在CentOS 7 Apache软件包中启用。
我们可以直接再次修改我们的虚拟主机文件以开始配置这些项目:
- sudo nano /etc/httpd/conf.d/site.conf
该mod_expires模块仅提供三个指令。通过将ExpiresActive设置为“开”,在特定上下文到期处理。另外两个指令彼此非常相似。该ExpiresDefault指令设置默认的到期时间,并根据内容的MIME类型设置ExpiresByType到期时间。这两个都将Expires和Cache-Control“max-age”设置为正确的值。
这两个设置可以采用两种不同的语法。第一个是简单的“A”或“M”,后跟几秒钟。这设置了相对于上次“访问”或“修改”内容的最后时间的到期。例如,这两者都会在访问内容后30秒到期。
- ExpiresDefault A30
- ExpireByType text/html A30
另一种语法允许更详细的配置。它允许您使用更容易人类计算的秒数以外的单位。它还使用完整的“访问”或“修改”一词。整个过期配置应保留在引号中,如下所示:
- ExpiresDefault "modification plus 2 weeks 3 days 1 hour"
- ExpiresByType text/html "modification plus 2 weeks 3 days 1 hour"
出于我们的目的,我们只设置默认过期时间。我们将从设置为5分钟开始,这样如果我们在熟悉时犯了错误,它将不会存储在我们客户的计算机上很长时间。当我们对选择适合我们内容的政策的能力更有信心时,我们可以将其调整为更积极的方式:
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- CacheQuickHandler off
-
- CacheLock on
- CacheLockPath /tmp/mod_cache-lock
- CacheLockMaxAge 5
-
- CacheIgnoreHeaders Set-Cookie
-
- <Location />
- CacheEnable disk
- CacheHeader on
-
- CacheDefaultExpire 600
- CacheMaxExpire 86400
- CacheLastModifiedFactor 0.5
-
- ExpiresActive on
- ExpiresDefault "access plus 5 minutes"
- </Location>
- </VirtualHost>
把我们的Expires标题设置为五分钟并设置Cache-Control max-age=300。为了进一步完善缓存策略,我们可以使用该Header指令。我们可以使用该merge选项添加其他Cache-Control选项。您可以多次调用此选项并添加您想要的其他策略。对于我们的示例,我们只需设置“public”,以便其他缓存可以确保允许它们存储副本。
要在我们的站点上设置静态内容ETags(用于验证),我们可以使用该FileETag指令。这适用于静态内容。对于动态生成的内容,您的应用程序将负责正确生成ETags。
我们可以使用该指令设置Apache将用于计算的属性Etag。这可以是INode,MTime,Size,或All取决于如果每当文件的inode修改时。我们都要修改ETag,其修改时间的变化,其大小的变化,或者上述所有。您可以提供多个值,并且可以通过在新设置前加上+或来修改子上下文中的继承设置-。出于我们的目的,我们将只使用“all”以便所有更改都已注册:
- <VirtualHost *:80>
- ServerName server_domain_or_IP
- DocumentRoot /var/www/html
-
- CacheQuickHandler off
-
- CacheLock on
- CacheLockPath /tmp/mod_cache-lock
- CacheLockMaxAge 5
-
- CacheIgnoreHeaders Set-Cookie
-
- <Location />
- CacheEnable disk
- CacheHeader on
-
- CacheDefaultExpire 600
- CacheMaxExpire 86400
- CacheLastModifiedFactor 0.5
-
- ExpiresActive on
- ExpiresDefault "access plus 5 minutes"
-
- Header merge Cache-Control public
- FileETag All
- </Location>
- </VirtualHost>
这会将“public”(用逗号分隔)添加到Cache-Control已有的任何值中,并包含ETag静态内容。
完成后,保存并关闭文件。输入以下命令检查更改的语法:
- sudo apachectl configtest
如果未找到任何错误,请重新启动服务以实施缓存策略:
- sudo systemctl restart httpd
使用Apache配置缓存看起来像是一项艰巨的任务因为由于有太多选项要配置。幸运的是,它开始相对简单,然后随着您需要更多的复杂性而增长。大多数管理员不需要每种缓存类型。
配置缓存时,请记住您尝试解决的特定问题,以避免在不同的实现选择中迷失。大多数用户将至少从设置标头中受益。如果您要代理或生成内容,那设置HTTP缓存可能会有所帮助。如果您使用后端提供程序,则共享对象缓存对于存储SSL会话或身份验证详细信息等特定任务非常有用。文件缓存可能仅限于系统速度较慢的文件。