针对 EC2 微型实例优化 Apache

针对 EC2 微型实例优化 Apache

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

该服务器主要运行几个网站,一个 wordpress 博客(不常用)、公司网站(最常用)和 2 个小型网站,仅供内部使用。

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

我刚到公司的时候,服务器已经设置好了,运行的是 apache + mod_php + prefork。我们想在将来将其迁移到 nginx + php-fpm,但仍需要进一步测试。所以现在我必须坚持使用旧设置。

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

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

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

我的 prefork 配置如下所示:

启动服务器 2
 最小备用服务器数 2
 最大备用服务器数 5
 服务器限制 10
 最大客户数 10
 每个子项的最大请求数 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(共享)
 negotiation_module(共享)
 php5_module(共享)
 rewrite_module(共享)
 setenvif_module(共享)
 ssl_module(共享)
 status_module(共享)
语法正确

apache2.conf

# 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

主站的 Vhost

<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>

答案1

升级服务器

我知道你不想听。我知道你的客户也不想听。但这是你需要听到的!如果客户正在运行 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 进程再次变得没有响应。

这听起来好像您(可能)遇到了太多流量?

答案2

虽然已经很晚了,但另一个解决方案是减少您的 ec2 上的工作负载。在此实例前面使用 cloudfront 分发。如果缓存策略正确,将减少您服务器上的负载,并且据我所知,使用正确的缓存策略,您的服务器可以扩展到数千名读者(不是编辑者、管理员等)

使用 wordpress 设置 CDN 的教程

相关内容