优化基于 Kohana 的网站的速度和可扩展性
-
12-09-2019 - |
题
我用 Kohana 构建的一个网站昨天遭遇了巨大的流量冲击,导致我退后一步并评估了一些设计。我很好奇优化基于 Kohana 的应用程序有哪些标准技术?
我对基准测试也很感兴趣。我需要设置吗 Benchmark::start()
和 Benchmark::stop()
对于每个控制器方法,以便查看所有页面的执行时间,或者我是否能够在全局范围内快速应用基准测试?
我将在未来更多地使用缓存库,但我愿意接受更多建议,因为我确信我可以做很多我目前还没有意识到的事情。
解决方案
我在这个答案中所说的并不是 Kohana 特有的,并且可能适用于很多 PHP 项目。
以下是在谈论性能、可扩展性、PHP 时我想到的一些要点……
我在处理几个项目时使用了其中的许多想法——它们很有帮助;所以他们也可能在这里提供帮助。
首先,从表演的角度来看, 需要考虑的许多方面/问题:
- 服务器的配置 (Apache、PHP、MySQL、其他可能的守护进程和系统);您可能会在以下位置获得更多帮助 服务器故障, , 我想,
- PHP代码,
- 数据库查询,
- 使用或不使用您的网络服务器?
- 您可以使用任何类型的缓存机制吗?或者您是否总是需要网站上的最新数据?
使用反向代理
真正有用的第一件事是使用 反向代理, , 喜欢 漆, ,在您的网络服务器前面:让它 缓存尽可能多的东西, ,所以只有真正需要PHP/MySQL计算的请求 (当然,还有一些其他请求,当它们不在代理的缓存中时) 使其成为 Apache/PHP/MySQL。
- 首先,你的CSS/Javascript/图像 ——好吧,一切都是静态的—— 可能不需要始终由 Apache 提供服务
- 因此,您可以拥有所有这些反向代理缓存。
- 对于 Apache 来说,提供这些静态文件并不是什么大问题,但处理这些静态文件的工作越少,它使用 PHP 就能完成的工作就越多。
- 记住:Apache 一次只能处理有限数量的请求。
- 然后,让反向代理从缓存中提供尽可能多的 PHP 页面:可能有 一些不经常更改的页面, ,并且可以从缓存中提供服务。与其使用一些基于 PHP 的缓存,为什么不让另一个更轻的服务器来提供这些服务呢? (并且不时从 PHP 服务器获取它们,因此它们总是几乎是最新的)?
- 例如,如果您有一些 RSS 提要 (当我们尝试优化性能时,我们通常会忘记这些) 所要求的 常常, ,将它们放在缓存中几分钟可以节省数百/数千对 Apache+PHP+MySQL 的请求!
- 对于您网站上访问量最大的页面,如果它们至少在几分钟内没有发生变化,情况也是如此 (例子:主页?), ,那么,每次用户请求它们时,就不需要浪费 CPU 重新生成它们。
- 也许为匿名用户提供的页面之间存在差异 (所有匿名用户的同一页面) 以及为已识别用户提供的页面 (例如,“X 先生您好,您有新消息”)?
- 如果是这样,您可以配置反向代理来缓存为匿名用户提供的页面 (通常基于 cookie,如会话 cookie)
- 这意味着 Apache+PHP 需要处理的事情更少:仅识别用户——这可能只是您用户的一小部分。
关于 使用反向代理作为缓存, ,对于 PHP 应用程序,您可以例如查看 基准测试结果显示,APC 和 Squid 缓存的服务器功能提高了 400%-700%.
(是的,他们正在使用 Squid,而我正在谈论 varnish——这只是另一种可能性 ^^ Varnish 更新,但更致力于缓存)
如果你做得足够好,并且设法停止一次又一次地重新生成太多页面,也许你甚至不需要优化任何代码;-)
至少,也许不着急……当您没有承受太大压力时,执行优化总是更好......
作为旁注:你在OP中说:
我与Kohana建造的一个网站昨天被大量交通撞了
这是一种 反向代理可以拯救世界的突发情况, ,如果您的网站可以处理没有及时更新的情况:
- 安装它,配置它,让它永远存在 ——每个平常的日子—— 跑步:
- 配置它不将 PHP 页面保留在缓存中;或仅持续很短的时间;这样,您始终可以显示最新的数据
- 并且,在您使用斜线或挖掘效果的那天:
- 配置反向代理以将 PHP 页面保留在缓存中;或更长的一段时间;也许您的页面不会每秒更新,但这将使您的网站能够在挖掘效应中生存下来!
关于那个, 我怎样才能发现并生存被“Slashdotted”? 可能会是一本有趣的读物。
在 PHP 方面:
首先:你用的是 PHP 的最新版本?随着新版本的出现,速度会定期提高;-)
例如,看一下 PHP 分支 3.0 到 5.3-CVS 的基准测试.
请注意,性能是使用 PHP 5.3 的一个很好的理由 (我做了一些基准(法语), ,结果很棒)...
当然,另一个很好的理由是 PHP 5.2 已经达到生命周期的终点,并且不再维护!
您是否使用任何操作码缓存?
- 我在想 APC - 替代 PHP 缓存, , 例如 (佩克, 手动的), ,这是我见过最常用的解决方案 - 并且在我工作过的所有服务器上都使用。
- 在某些情况下,它确实可以大大降低服务器的 CPU 负载 (我发现某些服务器上的 CPU 负载从 80% 上升到 40%,只需安装 APC 并激活它的操作码缓存功能!)
- 基本上,PHP 脚本的执行分为两个步骤:
- 将 PHP 源代码编译为操作码 (相当于JAVA的字节码)
- 这些操作码的执行
- APC 将这些内容保留在内存中,因此每次执行 PHP 脚本/文件时需要完成的工作较少:只从 RAM 中获取操作码并执行它们。
- 您可能需要看一下 APC的 配置选项, , 顺便一提
- 其中有很多,有些会对速度/CPU 负载/易用性产生很大影响
- 例如,禁用
[apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)
有利于系统负载;但这意味着对 PHP 文件所做的修改将不会被考虑,除非您刷新整个操作码缓存;关于这一点,有关更多详细信息,请参阅例如 到 stat() 还是不到 stat()?
使用数据缓存
尽可能地,最好是 避免一遍又一遍地做同样的事情.
当然,我主要考虑的是 SQL 查询:您的许多页面可能会执行相同的查询,并且其中一些页面的结果可能几乎总是相同的......这意味着很多 “无用” 对数据库进行查询,数据库必须花时间一遍又一遍地提供相同的数据。
当然,这对于其他事情也是如此,比如 Web 服务调用、从其他网站获取信息、繁重的计算……
您可能会很感兴趣地确定:
- 哪些查询运行了很多次,总是返回相同的数据
- 还有哪一个 (重的) 计算进行了很多时间,总是返回相同的结果
并将这些数据/结果存储在某种缓存中,这样它们就更容易获取—— 快点 ——而且您不必为了“无事”而访问您的 SQL 服务器。
例如,优秀的缓存机制有:
- APC: :除了我之前提到的操作码缓存之外,它还允许您将数据存储在内存中,
- 和/或 内存缓存 (也可以看看), ,如果你真的有的话,这非常有用 地段 数据和/或是 使用多个服务器, ,因为它是分布式的。
- 当然,你可以考虑文件;可能还有许多其他想法。
我很确定你的框架附带了一些与缓存相关的东西;正如你所说,你可能已经知道了 “我将在未来更多地使用缓存库” 在OP中;-)
分析
现在,一件好事就是使用 调试工具 延伸至 介绍您的应用程序: :它通常可以很容易地找到一些弱点——至少,如果有任何函数需要花费大量时间的话。
配置正确, ,它将生成可以使用一些图形工具进行分析的分析文件,例如:
- K缓存研磨: :我最喜欢的,但仅适用于 Linux/KDE
- Wincachegrind 用于窗户;不幸的是,它比 KCacheGrind 做的事情要少一些——它通常不显示调用图。
- 网络研磨 它运行在 PHP 网络服务器上,因此可以在任何地方工作——但功能可能较少。
例如,以下是 KCacheGrind 的几个屏幕截图:
(来源: 帕斯卡·马丁.fr)
(来源: 帕斯卡·马丁.fr)
(顺便说一句,如果我没记错的话,第二个屏幕截图中显示的调用图通常是 WinCacheGrind 和 Webgrind 都无法做到的事情 ^^ )
(感谢@Mikushi 的评论) 我没有太多使用的另一种可能性是 教授 扩大 :它还有助于分析,可以生成调用图——但比 Xdebug 更轻,这意味着您应该能够将它安装在生产服务器上。
你应该能够单独使用它 新华桂, ,这将有助于数据的可视化。
在 SQL 方面:
现在我们已经谈论了一些关于 PHP 的内容,请注意它是 你的瓶颈很可能不是 PHP 方面, ,但是数据库一...
这里至少有两三件事:
- 您应该确定:
- 您的应用程序最常执行的查询是什么
- 这些是否优化 (使用 正确的索引, ,主要是?), , 使用
EXPLAIN
指令,如果您使用 MySQL- 也可以看看: 优化 SELECT 和其他语句
- 例如,您可以激活
log_slow_queries
获取所采取的请求的列表 “太多了” 时间,然后开始你的优化。
- 是否可以缓存其中一些查询 (看我之前说的)
- 你的MySQL配置好了吗?我对此了解不多,但有一些配置选项可能会产生一些影响。
- 优化 MySQL 服务器 可能会为您提供一些有趣的信息。
尽管如此,最重要的两件事是:
- 如果不需要,请不要访问数据库: 尽可能多地缓存!
- 当您必须访问数据库时,请使用高效的查询:使用索引;和个人资料!
现在怎么办?
如果您仍在阅读,还有哪些可以优化的地方?
嗯,还有改进的空间……一些面向架构的想法可能是:
- 切换到n层架构:
- 使用比 Apache “更高效”的东西?
- 我越来越频繁地听到 nginx, ,这对于 PHP 和大容量网站来说应该是很棒的;我自己从未使用过它,但您可能会在网上找到一些关于它的有趣文章;
- 例如, PHP性能三——运行nginx.
- 也可以看看: PHP-FPM - FastCGI 进程管理器, ,它与 PHP >= 5.3.3 捆绑在一起,并且与 nginx 一起创造了奇迹。
- 我越来越频繁地听到 nginx, ,这对于 PHP 和大容量网站来说应该是很棒的;我自己从未使用过它,但您可能会在网上找到一些关于它的有趣文章;
好吧,也许其中一些想法在你的情况下有点矫枉过正^^
但是,还是……为什么不研究一下它们,以防万一呢?;-)
那么科哈纳呢?
您最初的问题是关于优化使用 Kohana 的应用程序......嗯,我已经发了一些 适用于任何 PHP 应用程序的想法...这意味着它们也适用于 Kohana ;-)
(即使没有具体说明^^)
我说:使用缓存;Kohana似乎支持一些 缓存东西 (你自己也说过了,所以这里没什么新意......)
如果有什么可以快速完成的事情,请尝试一下;-)
我还说,没有必要的事情不要做,不要做。Kohana 中是否有默认启用但您不需要的功能?
浏览网络,似乎至少有一些关于XSS过滤的内容;你需要那个吗?
不过,这里有几个可能有用的链接:
结论?
最后,一个简单的想法:
- 贵公司支付你 5 天的工资需要多少钱? -- 考虑到进行一些重大优化是合理的时间
- 贵公司购买要花多少钱 (付费?) 第二台服务器及其维护?
- 如果你必须扩大规模怎么办?
- 花10天要花多少钱?更多的?优化应用程序的每一个可能的部分?
- 如果再加几个服务器要多少钱?
我并不是说你不应该优化:你绝对应该!
但 进行“快速”优化,这将为您带来丰厚的回报 第一的:使用一些操作码缓存可能会帮助您降低服务器 10% 到 50% 的 CPU 负载...设置只需要几分钟;-) 另一方面,花费 3 天的时间才能获得 2% 的费用......
哦,还有,顺便说一句:在做任何事情之前: 放置一些监控东西, ,这样您就知道进行了哪些改进以及如何改进!
如果没有监控,你将不知道你所做的事情的效果......即使它是不是真正的优化也不是!
例如,你可以使用类似的东西 RRD工具 + 仙人掌.
向你的老板展示一些漂亮的图形并且 CPU 负载下降了 40% 总是很棒;-)
无论如何,真正的结论是: 玩得开心!
(是的,优化很有趣!)
(呃,没想到会写这么多……希望至少其中的某些部分是有用的......我应该记住这个答案:其他时候可能会有用...)
其他提示
使用 X调试 和 WinCacheGrind 或者 Web缓存研磨 分析和分析缓慢的代码执行。
(来源: jokke.dk)
与的XDebug 。
资料代码使用很多缓存。如果您的网页是相对静态的,那么反向代理可能是做到这一点的最好办法。
Kohana的是开箱非常非常快,只是使用的数据库对象。引述Zombor“你可以确保你正在使用的数据库结果对象,而不是结果阵列减少内存的使用。”这使得对正在抨击一个网站HUGEE性能差异。它不仅使用更多的存储器,它减慢脚本的执行。
此外 - 你必须使用缓存。我喜欢的memcache,并用它在我的模型是这样的:
public function get($e_id)
{
$event_data = $this->cache->get('event_get_'.$e_id.Kohana::config('config.site_domain'));
if ($event_data === NULL)
{
$this->db_slave
->select('e_id,e_name')
->from('Events')
->where('e_id', $e_id);
$result = $this->db_slave->get();
$event_data = ($result->count() ==1)? $result->current() : FALSE;
$this->cache->set('event_get_'.$e_id.Kohana::config('config.site_domain'), $event_data, NULL, 300); // 5 minutes
}
return $event_data;
}
这也将显着提高性能。上述两种技术由80%提高了网站的性能。
如果你给什么地方你认为瓶颈是一些更多的信息,我敢肯定,我们可以提供一些更好的想法。
还检查了YSlow的(谷歌它),用于其它一些性能的提示。
与 Kohana 密切相关(您可能已经这样做过,也可能没有):
在生产模式下:
- 启用内部缓存(这只会缓存 Kohana::find_file 结果,但这实际上有很大帮助。
- 禁用分析器
只是我的 2 美分:)
我完全的XDebug和缓存的答案一致。不要直视Kohana的层进行优化,直到你确定你的最大速度和规模的瓶颈。
XDebug的会告诉你,是你花大部分的时间在你的代码识别“热点”。保持这个分析信息,以便您可以基线和衡量性能的提升。
实施例和问题的解决方案: 如果你发现你建立了每次从数据库昂贵的对象,没有真正改变的时候,那么你可以看看用的memcached或其他机制缓存他们。所有这些性能的修复需要时间和复杂性添加到您的系统,所以要确保您的系统瓶颈的你开始修复之前。