为 EC2 微实例优化 Apache

1 performance-tuning apache-2.2

我在具有 ~600 mb RAM 的 EC2 微型实例上运行 apache2。该实例运行了将近一年没有问题,但在最后几周它只是不断崩溃,因为服务器达到了 MaxClients。

服务器基本上运行几个网站,一个wordpress博客(不经常使用),公司网站(最常用)和2个小网站,这些都是内部的。

博客的数据库运行在 RDS 上,因此该 Web 服务器上没有运行 Mysql。

当我来到公司时,服务器已经设置好并且正在运行 apache + mod_php + prefork。我们希望将来将其迁移到 nginx + php-fpm,但它仍然需要进一步测试。所以现在我必须坚持使用旧设置。

我还在服务器前面使用了 CloudFlare DDOS 保护,因为它在过去几周中受到了几次攻击。

我的公司此时不想花钱购买更好的 Web 服务器,所以我也必须坚持使用微型实例。此外,我们运行的网站代码非常糟糕且缓慢,有时单个页面加载可能需要长达 15 秒。整个网站是动态的并且是用 PHP 编写的,所以缓存在这里并不是一个真正的选择。这是为用户定制的搜索。

我已经关闭了 KeepAlive,这稍微提高了性能。

我的 prefork 配置如下所示:

 启动服务器 2
 最小备用服务器 2
 最大备用服务器 5
 服务器限制 10
 最大客户 10
 MaxRequestsPerChild 100

服务器在运行一段时间后变得没有响应,我运行了以下命令来查看有多少连接:netstat | grep http | wc -l 75

尝试重新启动 apache 暂时会有所帮助,但过了一段时间后 apache 进程再次变得无响应。

我启用了以下模块(apache2ctl -M 的输出)

加载模块:
 core_module(静态)
 log_config_module(静态)
 logio_module(静态)
 version_module(静态)
 mpm_prefork_module(静态)
 http_module(静态)
 so_module(静态)
 alias_module(共享)
 authz_host_module(共享)
 deflate_module(共享)
 dir_module(共享)
 expires_module(共享)
 mime_module(共享)
 协商模块(共享)
 php5_module(共享)
 rewrite_module(共享)
 setenvif_module(共享)
 ssl_module(共享)
 status_module(共享)
语法确定

配置文件

# Security
ServerTokens OS
ServerSignature On
TraceEnable On
ServerName "web.example.com"
ServerRoot "/etc/apache2"
PidFile ${APACHE_PID_FILE}
Timeout 30
KeepAlive off
User www-data
Group www-data

AccessFileName .htaccess
<Files ~ "^\.ht">
  Order allow,deny
  Deny from all
  Satisfy all
</Files>

<Directory />
  Options FollowSymLinks
  AllowOverride None
</Directory>

DefaultType none
HostnameLookups Off
ErrorLog /var/log/apache2/error.log
LogLevel warn
EnableSendfile On

#Listen 80


Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/ports.conf

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
Include /etc/apache2/conf.d/*.conf
Include /etc/apache2/sites-enabled/*.conf
Run Code Online (Sandbox Code Playgroud)

主站虚拟主机

<VirtualHost *:80>
  ServerName www.example.com
  ## Vhost docroot
   DocumentRoot /srv/www/jenkins/Web
  ## Directories, there should at least be a declaration for /srv/www/jenkins/Web

  <Directory /srv/www/jenkins/Web>
    AllowOverride All
    Order allow,deny
    Allow from all
  </Directory>

  ## Load additional static includes

  ## Logging
  ErrorLog /var/log/apache2/www.example.com.error.log
  LogLevel warn
  ServerSignature Off
  CustomLog /var/log/apache2/www.example.com.access.log combined

  ## Rewrite rules
  RewriteEngine On
  RewriteCond %{HTTP_HOST} !^www.example.com$
  RewriteRule ^.*$ http://www.example.com%{REQUEST_URI} [R=301,L]

  ## Server aliases
  ServerAlias www.example.invalid
  ServerAlias example.com

  ## Custom fragment
<Location /srv/www/jenkins/Web/library>
 Order Deny,Allow
 Deny from all
</Location>
<Files ~ "^\.(.+)">
  Order deny,allow
  deny from all
</Files>

</VirtualHost>
Run Code Online (Sandbox Code Playgroud)

Dre*_*ury 6

升级您的服务器

我知道你不想听。我知道你的客户不想听。但这是你需要听到的!如果客户运行 4 个网站(生产不少于),他们应该支付一些现金购买更好的服务器。

但为什么?

微型实例不是为生产使用而设计的(AWS 自己是这么说的),它们会发生争用,不要指望 CPU、网络或磁盘 I/O 有什么好的或可预测的。

如果必须使用 mirco,请考虑使用 t2 而不是 t1

T1 = http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts_micro_instances.html

t1.micro 是上一代实例,它已被 t2.micro 取代,后者具有更好的性能配置文件。我们建议使用 t2.micro 实例类型而不是 t1.micro。有关更多信息,请参阅 T2 实例。

T2 = http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html

它们适用于不经常或持续使用完整 CPU,但偶尔需要爆发的工作负载。T2 实例非常适合通用工作负载,例如 Web 服务器、开发人员环境和小型数据库。

快速破解

有时,您可以通过停止 EC2 并重新启动来解决主机的争用问题(CPU 窃取、坏邻居综合症等)。这将导致您的 EC2 所在的底层主机发生更改。

回答您的其他一些问题...

该实例运行了将近一年没有问题,但在最后几周它只是不断崩溃,因为服务器达到了 MaxClients。

为什么你认为服务器已经达到了 MaxClients?更多流量?您可以增加这个数字,但是我怀疑一个微型实例无法处理太多的并发连接。

博客的数据库运行在 RDS 上,因此该 Web 服务器上没有运行 Mysql。

我喜欢 RDS,并推荐人们使用它。但是为什么贵公司为 RDS 支付现金却不愿意升级他们的 EC2 实例?为什么不直接放弃 RDS 并升级 EC2?(在理想的世界中,我会说保留 RDS 并升级 EC2)。

整个网站是动态的并且是用 PHP 编写的,所以缓存在这里并不是一个真正的选择。

您确定 APC 在这种情况下不会提供帮助吗?在您尝试之前,很难准确确定 APC 可以提供多少帮助。http://php.net/manual/en/intro.apc.php

尝试重新启动 apache 暂时会有所帮助,但过了一段时间后 apache 进程再次变得无响应。

这听起来像你(也许)获得了太多的流量?