在高负载站点中使用PHP的策略

时间:2020-03-05 18:42:30  来源:igfitidea点击:

在回答这个问题之前,我还没有开发出足以达到高服务器负载的流行方法。将我当作(叹息)刚刚降落在地球上的外星人,尽管它知道PHP和一些优化技术。

我正在用PHP开发一个工具,如果可以的话,它可以吸引很多用户。但是,尽管我完全有能力开发该程序,但是在制作可以处理大量流量的东西时却一无所知。因此,这里有一些问题(也可以将这个问题转换为资源线程)。

资料库

目前,我计划在PHP5中使用MySQLi功能。但是,我应该如何设置与用户和内容相关的数据库?我实际上需要多个数据库吗?目前,尽管我一直在考虑将用户数据分散到一个数据库,将实际内容分散到另一个数据库,最后将核心站点内容(模板母版等)分散到另一个数据库,但是所有内容都混杂在一个数据库中。我这样做的理由是,将查询发送到不同的数据库将减轻它们的负载,因为一个数据库= 3个负载源。如果它们都在同一服务器上,这仍然会有效吗?

快取

我有一个用于构建页面和换出变量的模板系统。主模板存储在数据库中,并且每次调用模板时,都会调用其缓存副本(HTML文档)。目前,这些模板中有两种类型的变量:静态变量和动态变量。静态变量通常是页面名称之类的东西,站点名称通常不经常更改。动态变量是在每次页面加载时都会更改的内容。

我对此的问题:

说我对不同的文章有意见。这是一个更好的解决方案:每次加载页面时都存储简单的注释模板并呈现注释(来自DB调用),或者每次添加/编辑/删除注释时都将注释页面的缓存副本存储为html页面。页面被重新缓存。

最后

有没有人有任何技巧/指针在PHP上运行高负载站点。我敢肯定,使用Facebook和Yahoo!是一种可行的语言!给它很大的优先级,但是我应该注意什么经验?

解决方案

回答

APC是绝对必要的。它不仅构成了一个出色的缓存系统,而且从自动缓存的PHP文件中获得的收益真是天赐。至于多数据库的想法,我认为我们不会从同一服务器上拥有不同的数据库中受益匪浅。它可能会在查询期间使速度有所提高,但是我怀疑为确保这三个代码同步而部署和维护这三个代码所付出的努力是否值得。

我也强烈建议运行Xdebug来查找程序中的瓶颈。优化使我轻而易举。

回答

首先,正如我认为Knuth所说的那样,"过早的优化是万恶之源"。如果我们现在不必处理这些问题,那么就不必着重于首先提供可以正常工作的东西。话虽如此,如果优化迫不及待。

尝试对数据库查询进行性能分析,找出运行缓慢的情况以及发生的情况,然后从中提出优化策略。

我将研究Memcached,因为它是许多高负载站点用于有效地缓存所有类型的内容的工具,并且与它的PHP对象接口非常好。

在服务器之间拆分数据库并使用某种负载平衡技术(例如在1个冗余数据库和具有必要数据的冗余数据库之间生成一个随机数,并使用该数字来确定要连接到哪个数据库服务器)也是提高效率的绝佳方法。

过去,在某些负载较高的站点上,这些方法都工作得很好。希望这有助于我们入门:-)

回答

我曾在一些网站上获得过PHP和MySQL的支持,这些网站每月获得了数百万次的点击。以下是一些基本知识:

  • 缓存,缓存,缓存。缓存是减少Web服务器和数据库负载的最简单,最有效的方法之一。缓存页面内容,查询,昂贵的计算以及任何受I / O约束的内容。 Memcache非常简单有效。
  • 一旦用尽了,请使用多台服务器。我们可以具有多个Web服务器和多个数据库服务器(带有复制)。
  • 减少对Web服务器的总体请求数。这需要使用expires标头缓存JS,CSS和图像。我们还可以将静态内容移动到CDN,这将加快用户的体验。
  • 衡量和基准。在生产计算机上运行Nagios,并在dev / qa服务器上进行负载测试。我们需要知道服务器何时会着火,以便我们能够防止这种情况发生。

我建议阅读由Flickr的一位工程师撰写的《建立可扩展的网站》,它是一个很好的参考。

也可以查看我关于可伸缩性的博客文章,其中有很多链接可用于有关使用多种语言和平台进行扩展的演示文稿:
http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/

回答

使用Xdebug(建议使用tj9991)对应用程序进行性能分析绝对是必须的。盲目地进行优化是没有任何意义的。 Xdebug将找到代码中的真正瓶颈,因此我们可以明智地花费优化时间并修复实际上导致速度变慢的代码块。

如果我们使用的是Apache,Siege是另一个可以帮助测试的实用程序。通过真正调整速度,它将预期服务器和应用程序将如何应对高负载。

用于PHP的任何类型的操作码缓存(例如APC或者许多其他之一)也将有很大帮助。

回答

没有两个站点是一样的。我们确实需要使用jmeter和基准测试之类的工具来查看问题点在哪里。我们可以花费大量时间进行猜测和改进,但是只有在衡量和比较更改后才能看到真正的结果。

例如,多年来,MySQL查询缓存一直是我们所有性能问题的解决方案。如果网站运行缓慢,MySQL专家建议我们打开查询缓存。事实证明,如果我们有很高的写入负载,则缓存实际上会瘫痪。如果我们在没有测试的情况下将其打开,我们将永远不会知道。

并且不要忘记,我们从未完成过扩展。处理10req / s的站点将需要更改以支持1000req / s。而且,如果我们足够幸运,需要支持10,000req / s,那么架构也可能看起来完全不同。

  • 不要使用MySQLi-PDO是"现代"的OO数据库访问层。要使用的最重要功能是查询中的占位符。它足够聪明,可以为我们使用服务器端准备和其他优化。
  • 我们可能现在不想破坏数据库。如果我们确实发现一个数据库无法满足需求,则有多种技术可以扩展,具体取决于应用程序。如果读取次数多于写入次数,则复制到其他服务器通常效果很好。分片是一种将数据拆分到多台计算机上的技术。
  • 我们可能不想缓存在数据库中。数据库通常是瓶颈,因此添加更多IO通常是一件坏事。有几个PHP缓存可以完成类似APC和Zend的功能。
  • 启用和禁用缓存来衡量系统。我敢打赌,缓存比直接提供页面要重。
  • 如果需要很长时间才能从数据库中构建评论和文章数据,请将内存缓存集成到系统中。我们可以缓存查询结果并将其存储在memcached实例中。重要的是要记住,从内存缓存中检索数据必须比从数据库中汇编数据要快得多,以了解任何好处。
  • 如果文章不是动态的,或者我们在生成文章后进行了简单的动态更改,请考虑将html或者php写出到磁盘上。我们可能有一个index.php页面,该页面在磁盘上查找该文章,如果有的话,会将其流式传输到客户端。如果不是,它将生成文章,将其写入磁盘,然后将其发送给客户端。从磁盘上删除文件将导致页面被重写。如果在文章中添加了评论,请删除缓存的副本-它将重新生成。

回答

@加里

Don't use MySQLi -- PDO is the 'modern' OO database access layer. The most important feature to use is placeholders in your queries. It's smart enough to use server side prepares and other optimizations for you as well.

我现在很喜欢PDO,看来我们是对的,但是我知道MySQL正在为PHP开发MySQLd扩展,我想成功取代MySQL或者MySQLi,我们对此有何看法?

@Ryan,埃里克,tj9991

感谢我们对PHP缓存扩展的建议,我们能否解释一下一个使用另一个的原因?我听说过有关通过IRC进行memcached的很棒的事情,但从未听说过APC,我们对此有何看法?我认为使用多个缓存系统会产生很大的反作用。

我肯定会整理出一些性能测试人员,非常感谢我们对这些性能测试的建议。

回答

当然pdo很好,但是与mysql和mysqli相比,它的性能存在一些争议,尽管它现在似乎已经解决了。

如果我们设想可移植性,则应使用pdo,但如果没有,则应该使用mysqli。它具有一个OO接口,准备好的语句以及pdo提供的大多数功能(当然,可移植性除外)。

另外,如果确实需要性能,请为PHP 5.3中的(本地mysql)MysqLnd驱动程序做准备,该驱动程序将与php紧密集成,从而具有更好的性能和改进的内存使用率(以及用于性能调整的统计信息)。

如果我们拥有群集服务器(和类似YouTube的负载),则Memcache很好,但我也将首先尝试APC。

回答

看来我错了。 MySQLi仍在开发中。但是根据这篇文章,MySQL团队现在正在为PDO_MySQL贡献力量。从文章:

The MySQL Improved Extension - mysqli
  - is the flagship. It supports all features of the MySQL Server including
  Charsets, Prepared Statements and
  Stored Procedures. The driver offers a
  hybrid API: you can use a procedural
  or object-oriented programming style
  based on your preference. mysqli comes
  with PHP 5 and up. Note that the End
  of life for PHP 4 is 2008-08-08.
  
  The PHP Data Objects (PDO) are a
  database access abstraction layer. PDO
  allows you to use the same API calls
  for various databases. PDO does not
  offer any degree of SQL abstraction.
  PDO_MYSQL is a MySQL driver for PDO.
  PDO_MYSQL comes with PHP 5. As of PHP
  5.3 MySQL developers actively contribute to it. The PDO benefit of a
  unified API comes at the price that
  MySQL specific features, for example
  multiple statements, are not fully
  supported through the unified API.
  
  Please stop using the first MySQL
  driver for PHP ever published:
  ext/mysql. Since the introduction of
  the MySQL Improved Extension - mysqli
  - in 2004 with PHP 5 there is no reason to still use the oldest driver
  around. ext/mysql does not support
  Charsets, Prepared Statements and
  Stored Procedures. It is limited to
  the feature set of MySQL 4.0. Note
  that the Extended Support for MySQL
  4.0 ends at 2008-12-31. Don't limit yourself to the feature set of such
  old software! Upgrade to mysqli, see
  also Converting_to_MySQLi. mysql is in
  maintenance only mode from our point
  of view.

在我看来,这篇文章似乎偏向MySQLi。我想我对PDO有偏见。
我真的很喜欢MySQLi上的PDO。对我来说直截了当。该API与我编写的其他语言非常接近。OO数据库接口似乎工作得更好。

我还没有遇到过PDO无法提供的任何特定MySQL功能。如果我做过,我会感到惊讶。

回答

回复:PDO / MySQLi / MySQLND

@加里

我们不能只说"不要使用MySQLi",因为它们有不同的目标。 PDO几乎就像一个抽象层(尽管实际上不是),其设计目的是使使用多个数据库产品变得容易,而MySQLi特定于MySQL连接。在将PDO与MySQLi进行比较的情况下,不能说PDO是现代访问层,因为声明暗示着进展是mysql-> mysqli-> PDO,事实并非如此。

如果我们需要支持多种数据库产品,则可以使用PDO在MySQLi和PDO之间进行选择。如果我们仅使用MySQL,则可以在PDO和MySQLi之间进行选择。

那么,为什么我们会选择MySQLi而不是PDO?见下文...

@罗斯

我们对MySQLnd是最新的MySQL核心语言级别库是正确的,但是它不能替代MySQLi。 MySQLi(与PDO一样)仍然是我们通过PHP代码与MySQL交互的方式。两者都使用libmysql作为PHP代码背后的C客户端。问题是libmysql在核心PHP引擎之外,这就是mysqlnd出现的地方,即它是一个本机驱动程序,它利用核心PHP内部实现最大化效率,特别是在内存使用方面。

MySQLnd由MySQL自己开发,最近已进入正在进行RC测试的PHP 5.3分支,准备在今年晚些时候发布。然后,我们将能够将MySQLnd与MySQLi一起使用,但不能与PDO一起使用。如果我们不需要像PDO这样的抽象功能,这将使MySQLi在很多领域(不是全部)都有性能的提升,并将成为MySQL交互的最佳选择。

就是说,MySQLnd现在在PHP 5.3中可用于PDO,因此我们可以从ND到PDO获得性能增强的优势,但是,PDO仍然是通用数据库层,因此不太可能从中受益。 MySQLi可以在ND中进行增强。

尽管它们来自2006年,但仍可以在此处找到一些有用的基准。我们还需要注意类似此选项的情况。

在确定MySQLi和PDO之间时,需要考虑很多因素。实际上,直到我们获得非常高的请求数量才是无关紧要的,在那种情况下,使用为MySQL专为扩展而不是抽象化并提供MySQL驱动程序的扩展才有意义。 。

哪一个最好,因为每个都有优点和缺点,这并不是一件简单的事情。我们需要阅读我提供的链接并提出自己的决定,然后进行测试并找出答案。我在过去的项目中使用过PDO,它是一个很好的扩展,但是我选择纯粹的性能是编译了新的MySQLND选项的MySQLi(当PHP 5.3发布时)。

回答

我看不到自己很快会从MySQL切换到其他地方,所以我想我不需要PDO的抽象功能。感谢DavidM的那些文章,他们对我有很大帮助。

回答

Thanks for the advice on PHP's caching extensions - could you explain reasons for using one over another? I've heard great things about memcached through IRC but have never heard of APC - what are your opinions on them? I assume using multiple caching systems is pretty counter-effective.

实际上,许多人确实一起使用APC和memcached。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

回答

PDO也非常慢,其API也非常复杂。如果不考虑可移植性,则没有人理智地使用它。让我们面对现实吧,在所有Web应用程序的99%中,事实并非如此。我们只需要坚持使用MySQL或者PostrgreSQL或者其他正在使用的工具即可。

至于PHP问题以及要考虑什么。我认为过早的优化是万恶之源。 ;)首先完成应用程序,在进行编程时尝试使其保持干净,编写一些文档并编写单元测试。有了以上所有内容,我们就可以在任何时候重构代码。但是首先,我们想完成并推出它,以了解人们对此有何反应。

回答

我经营的网站每月有7-8百万的页面浏览量。并不是很多,但足以使我们的服务器感到负担。我们选择的解决方案很简单:数据库级别的内存缓存。如果数据库负载是主要问题,则此解决方案效果很好。

我们开始使用Memcache来缓存整个对象和最常用的数据库结果。它确实起作用了,但是它也引入了错误(如果我们更加小心的话,我们可能会避免其中的一些错误)。

因此,我们改变了方法。我们构建了一个数据库包装器(使用与旧数据库完全相同的方法,因此很容易切换),然后将其子类化以提供内存缓存数据库访问方法。

现在,我们要做的就是确定查询是否可以使用缓存的(可能已过期)结果。用户直接运行的大多数查询现在都可以直接从Memcache中获取。更新和插入是例外,主要网站的更新和插入仅由于日志记录而发生。这个相当简单的措施将我们的服务器负载减少了约80%。

回答

值得一提的是,即使没有像memcached这样的扩展程序/帮助程序包,缓存在PHP中也是DIRT SIMPLE。

我们需要做的就是使用ob_start()创建一个输出缓冲区。

创建一个全局缓存功能。调用ob_start,将函数作为回调传递。在函数中,查找页面的缓存版本。如果存在,则服务并结束。

如果不存在,脚本将继续处理。当到达匹配的ob_end()时,它将调用我们指定的函数。那时,我们仅获得输出缓冲区的内容,将它们放入文件中,保存文件并结束。

添加一些到期/垃圾回收。

很多人没有意识到我们可以嵌套" ob_start()" /" ob_end()"调用。因此,如果我们已经在使用输出缓冲区来解析广告或者进行语法突出显示等操作,则可以嵌套另一个ob_start / ob_end调用。

回答

查看mod_cache,它是Apache Web服务器的输出缓存,与ASP.NET中的输出缓存类似。

是的,我可以看到它仍处于实验阶段,但终有一天会完成。

回答

一般的

  • 在开始查看实际负载之前,请勿尝试进行优化。我们可能猜对了,但是如果我们做不到,那我们就浪费了时间。
  • 使用jmeter,xdebug或者其他工具对站点进行基准测试。
  • 如果开始成为负载问题,则可能会涉及对象或者数据缓存,因此通常请阅读缓存选项(memcached,MySQL缓存选项)

代码

  • 分析代码,以便了解瓶颈在哪里,以及它在代码中还是在数据库中

资料库

  • 如果对其他数据库的可移植性不是很重要,请使用MYSQLi,否则使用PDO
  • 如果基准测试表明数据库存在问题,请在开始缓存之前检查查询。使用EXPLAIN查看查询速度下降的地方。
  • 优化查询并以某种方式缓存数据库后,我们可能要使用多个数据库。复制到多个服务器或者分片(在多个数据库/服务器上拆分数据)可能是合适的,具体取决于数据,查询和读/写行为的类型。

快取

  • 关于缓存代码,对象和数据,已经完成了大量的编写工作。查找有关APC,Zend Optimizer,memcached,QuickCache和JPCache的文章。在我们真正需要执行此操作之前,我们将不必担心从未优化开始。
  • APC和Zend Optimizer是操作码缓存,它们通过避免代码的重新解析和重新编译来加快PHP代码的速度。通常安装简单,值得尽早进行。
  • Memcached是通用缓存,可用于缓存查询,PHP函数或者对象或者整个页面。必须专门编写代码来使用它,如果没有中心点来处理缓存对象的创建,更新和删除,则可能涉及该过程。
  • QuickCache和JPCache是​​文件缓存,否则类似于Memcached。基本概念很简单,但是也需要代码,并且在创建,更新和删除的中心点上更加容易。

各种各样的

  • 考虑使用其他Web服务器以实现高负载。如果我们可以牺牲Apache的功能和灵活性(或者如果我们不需要这些东西,而通常不需要),那么lighthttp和nginx这样的服务器可以用比Apache少得多的内存来处理大量流量。
  • 请记住,这些天硬件的价格出奇的便宜,因此与"让我们购买一台巨型服务器"相比,确保花费大量的精力来优化大量代码。
  • 考虑向此问题添加" MySQL"和" scaling"标签

回答

我不敢相信没有人提到过:模块化和抽象。如果我们认为站点将必须增长到很多机器,则必须对其进行设计,以便能够做到!这意味着诸如不要假定数据库位于本地主机上这样的愚蠢的事情。这也意味着一开始会很麻烦的事情,例如编写数据库抽象层(例如PDO,但要轻得多,因为它只完成我们需要做的事情)。

这意味着像使用框架之类的事情。我们将需要对代码进行分层,以便稍后可以通过重构数据抽象层来提高性能,例如,通过教导它一些对象位于不同的数据库中而无需知道或者关心代码。

最后,请注意占用大量内存的操作,例如不必要的字符串复制。如果我们可以降低PHP的内存使用量,则可以从Web服务器中获得更高的性能,当我们使用负载平衡的解决方案时,这一点将得到扩展。

回答

已经给出了很多很好的答案,但是我想指出一个替代的操作码缓存,称为XCache。它是由一个轻量级的贡献者创建的。

另外,如果将来可能需要对数据库服务器进行负载平衡,则MySQL Proxy可以很好地实现这一目标。

这两个工具都应该很容易地插入到现有应用程序中,因此可以在需要时进行此优化,而不会造成太多麻烦。

回答

我是一个拥有超过1500万用户的网站上的首席开发人员。我们几乎没有扩展问题,因为我们尽早进行了规划并进行了周密的扩展。以下是一些我可以从我的经验中提出的策略。

施玛
首先,对架构进行非规范化。这意味着,与其拥有多个关系表,不如选择拥有一个大表。通常,联接会浪费宝贵的数据库资源,因为进行多次准备和整理会消耗磁盘I / O。尽量避免使用它们。

这里的权衡是我们将要存储/拉冗余数据,但这是可以接受的,因为数据和笼内带宽非常便宜(更大的磁盘),而多个准备I / O则要贵几个数量级(更多的服务器) 。

索引
确保查询使用至少一个索引。但是请注意,如果我们经常编写或者更新索引,则将花费我们大量费用。有一些实验性的技巧可以避免这种情况。

我们可以尝试添加未索引的其他列,这些列与被索引的列并行运行。然后,我们可以具有一个脱机过程,该过程将未索引的列批量写入到已索引的列中。这样,我们可以更好地控制何时需要重新计算索引的mySQL。

避免像瘟疫这样的计算查询。如果必须计算查询,请尝试在写入时执行一次。

训练
我强烈推荐Memcached。它已被PHP堆栈(Facebook)上最大的参与者证明,并且非常灵活。有两种方法可以执行此操作,一种是在数据库层中进行缓存,另一种是在业务逻辑层中进行缓存。

DB层选项将需要缓存从DB检索到的查询结果。我们可以使用md5()对SQL查询进行哈希处理,并在进入数据库之前将其用作查找关键字。这样做的好处是很容易实现。不利的一面(取决于实现方式)是我们失去了灵活性,因为在缓存过期方面,我们对待所有缓存的处理都是一样的。

在我工作的商店中,我们使用业务层缓存,这意味着系统中的每个具体类都控制自己的缓存架构和缓存超时。这对我们来说效果很好,但是请注意,从数据库中检索到的项目可能与从缓存中检索到的项目不同,因此我们必须一起更新缓存和数据库。

数据共享
复制只会使我们受益匪浅。超出预期,写入将成为瓶颈。作为补偿,请确保尽早支持数据分片。如果我们不愿意的话,我们稍后可能会想开枪。

实现起来非常简单。基本上,我们希望将密钥授权与数据存储区分开。使用全局数据库存储主键和集群ID之间的映射。我们查询此映射以获取一个群集,然后查询该群集以获取数据。我们可以从该查找操作中缓存地狱,这将使其可以忽略不计。

不利的一面是可能很难将多个分片中的数据组合在一起。但是,我们也可以设计解决方案。

离线处理
如果不需要,不要让用户等待后端。建立一个作业队列并移动我们可以脱机的所有处理,使其独立于用户的请求。

回答

如果我们正在处理大量数据,并且缓存没有减少数据,请查看Sphinx。使用SphinxSearch不仅可以实现更好的文本搜索,而且在处理较大的表时可以作为MySQL的数据检索替代品,因此取得了很好的效果。如果我们使用SphinxSE(MySQL插件),它会超过我们多次缓存后获得的性能提升,并且应用程序实现是小菜一碟。

回答

有关缓存的要点很明确。它是构建有效应用程序中最简单,最重要的部分。我想补充一点,尽管memcached很棒,但是如果应用程序位于单个服务器上,则APC的速度要快大约五倍。

MySQL性能博客上的"缓存性能比较"一文针对该主题提供了一些有趣的基准http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/。

回答

第一个问题是我们真正希望它有多大?我们计划在基础架构上进行多少投资。由于我们觉得有必要在这里提出问题,因此,我猜测我们希望在有限的预算中从小做起。

如果该站点不可用,则性能无关紧要。为了获得可用性,我们需要水平扩展。我们可以明智地摆脱的最低限度是2台服务器,都运行apache,php和mysql。将一个DBMS设置为另一个DBMS的从属。在主数据库上执行所有写入操作,并在本地数据库上进行所有读取(无论是什么操作),除非出于某种原因需要回读刚读取的数据(使用主数据库)。确保我们已具备自动提升从属并隔离主控的机制。对Web服务器地址使用轮询DNS,以为从属节点提供更多的亲和力。

在此阶段将数据跨不同数据库节点进行分区是一个非常糟糕的主意,但是我们可能要考虑将其拆分到同一服务器上的不同数据库中(这将在我们超过facebook时促进跨节点的分区)。

确保确保已使用监视和数据分析工具来衡量站点性能并确定瓶颈。可以通过编写更好的SQL /修复数据库架构来解决大多数性能问题。

将模板缓存保留在数据库上是一个愚蠢的想法,数据库应该是结构化数据的中央通用存储库。将模板缓存保留在Web服务器的本地文件系统上,它将更快地可用,并且不会减慢数据库访问的速度。

不要使用操作码缓存。

花大量时间研究网站及其日志,以了解其运行如此缓慢的原因。

将尽可能多的缓存推送到客户端。

使用mod_gzip压缩所有内容。

C。

回答

我的第一条建议是考虑这个问题,并在设计站点时牢记这一点,但不要太过分。通常很难预测一个新站点的成功,并且我会花更多的时间尽早完成并稍后对其进行优化,这将是更好的选择。

通常,简单是快速的。
模板会使我们减速。数据库会使我们慢下来。复杂的库会使我们慢下来。将模板彼此分层,从数据库中检索模板并将其解析到复杂的库中->时间延迟彼此成倍增加。

基本站点启动并运行后,请进行测试,以向我们展示在哪里花费精力。很难找到目标。通常,为了加快处理速度,我们将不得不解开代码的复杂性,这使其变得更大,更难维护,因此我们只想在必要时这样做。

以我的经验,建立数据库连接是相对昂贵的。如果可以解决,请不要在访问量最大的页面(如网站首页)上连接一般访问者的数据库。创建多个数据库连接非常疯狂,几乎没有好处。