在 webfarm 上运行 Drupal 应用程序(可扩展性),如何?
我们已经使用 Drupal 创建了一个网站,但问题(好问题)是我们在服务器上获得了太多的点击量,以至于流量使服务器瘫痪。
现在我们想要在负载均衡器后面的 3 台服务器上运行应用程序,其中一台仅服务 mysql,另外 2 台服务器服务 Web 应用程序,我之前已经使用 Symofony 在另一个项目中完成了此操作,并且相对容易。
然而,我似乎无法在 Drupal 上走得太远,此时的主要问题是能够将所有会话变量保存到 mysql 中,因此无论负载均衡器将请求发送到哪台服务器,应用程序都有一个关于会话的单一参考点。
任何帮助将不胜感激,我正在寻找一个好的教程或文档,因为我从一个不再在这里工作的人那里继承了这个项目:/
谢谢
We have created a website using Drupal , but the problem ( good problem ) is that we are getting WAAAAYY too many hits on the server to the point where the traffic is brining the server down to its knees.
now we want to run the application off of 3 servers behind a load balancer, one to just serve mysql and the other 2 to serve the web application , i have accomplished this using Symofony before for a different project and it was relatively easy.
However i don't seem to be able to get far with Drupal, the major problem at this point is to be able to save all session variables into mysql, so indepdent of which server the load balancer sends the request to , the application has a single point of reference in regards to sessions.
Any help would be greatly appreciated, i am looking for a good tutorial or documentation since i have inherited this project off of a guy who no longer works here :/
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
注意:在我的回答中,我假设您正在使用 Apache。即使您使用其他服务器(例如 nginx 等),我的答案也是正确的。
您写道:
会话是在核心 PHP 级别和 Drupal+MySQL 级别处理的东西。本质上,当浏览器访问您的服务器时,PHP 核心会话处理逻辑会分配一个唯一的 PHPSESSID cookie。该浏览器会在每次后续请求时发回此 cookie。
[顺便说一句,使用 PHPSESSID,PHP 核心会话逻辑可能会关联一些其他数据,例如评论首选项、需要在下一页视图上显示的 drupal 消息等。所有这些都是使用 $_SESSION PHP 变量完成的。 PHP 可以非常无缝地完成此操作。请注意,直到此时,MySQL仍然才出现在图中。只有当 Drupal 需要将其他数据(例如用户 ID 等)与 PHPSESSID 关联时,MySQL 才会介入]
长话短说,PHP 通过分配 PHPSESSID cookie 来进行一些会话处理。现在假设负载均衡器将请求发送到 Apache Webserver 1,并且 mod_php(PHP apache 模块)分配一个唯一的 PHPSESSID,例如“563”(现实生活中它是一个较长的字符串)。现在,下次该客户端访问您的网站时,将发送带有值 563 的 cookie PHPSESSID。 现在可能会发生两种不同的情况:
如何解决您的问题:您面临的问题是一个常见问题。您只需告诉负载均衡器,一旦客户端被发送到特定的 Web 服务器,同一 Web 服务器应该继续处理该请求。这通常是通过告诉负载均衡器本身发送一个 cookie 来说明哪个服务器处理初始请求来完成的。将来,客户端将此 cookie 提供给负载均衡器,负载均衡器将请求定向到处理该请求的原始服务器。正如我上面所解释的,这一点很重要,因为只有服务器知道它分配的 PHPSESSID。
所有像样的负载均衡器都能够分配 cookie。查找负载均衡器的配置详细信息。有关会话的参考。
更多令人费解的事情 通过配置负载均衡器来分配 Cookie 解决了会话问题后,您将需要考虑一个更重要的问题。两个服务器的
files
文件夹必须以某种方式共享。这是有道理的。如果图像由一台服务器上的用户上传,则通过另一台服务器访问该站点的其他人应该可以访问同一图像。这是通过NFS(网络文件系统)
安装或 SAN 来完成的。只有然后您才会拥有功能齐全的 Drupal 多服务器安装。正如其他人指出的那样,您可能需要参考网上的一些参考文章。建议进一步优化,例如将会话表存储在 memcache 中而不是 MySQL 中,但这与我上面写的内容无关。确实需要负载均衡器发出 cookie。
我问为什么要经历这么多悲伤?我过去做过多服务器的工作,除非您的网站流量很大,否则它并不值得。你的流量够大吗?如果您的大多数用户都是匿名的,那么在 Drupal 前面放置一个像 Varnish 这样的缓存层,甚至更好,使用
boost
模块应该可以解决您的问题。观看此视频 http ://sf2010.drupal.org/conference/sessions/24-million-page-views-day-60-m-month-one-server。这个家伙只使用一台服务器就提供了大量的页面浏览量。只需一台服务器,一切就变得简单多了。尝试一下!只有最大的网站可能需要多个服务器。
Note: in my answer answer I'm assuming you are using Apache. My answer will be correct even if you are using some other server like nginx etc.
You write:
Sessions are something that are handled at the core PHP level and at the Drupal+MySQL level. Essentially when a browser accesses your server, PHP core session handling logic assigns a unique PHPSESSID cookie. This cookie is sent back by that browser on every subsequent request.
[On a side note, using PHPSESSID, PHP core session logic might associate some other data like comment preferences, drupal messages that need to be shown on next page view etc. All this is done using the $_SESSION PHP variable. PHP does this quite seamlessly. Note that MySQL still does not enter in the picture until this point. MySQL only enters the picture when additional data needs to be associated with a PHPSESSID such as User ID etc. by Drupal]
Long story short, PHP does some session handling by assigning the PHPSESSID cookie. Now lets say the load balancer sends the request to Apache Webserver 1 and mod_php (PHP apache module) assigns a unique PHPSESSID, say, "563" (its a longer string in real life). Now next time this client accesses your website, the cookie PHPSESSID is sent across with value 563. Now two different cases might occur:
How to solve your problem: The problem you're facing is a common issue. You simply need to tell the load balancer that once a client is sent to a particular web server, the same webs server should continue dealing with that request. This is usually done by telling the load balancer itself to send a cookie saying which server deal with the initial request. In the future, the client presents this cookie to the load balancer and the load balancer directs the request to the original server that deal with the request. This as I explained above is important because only that server knows about the PHPSESSID it assigned.
All decent load balancers have the ability to assign cookies. Look up the configuration details for your load balancer.reference in regards to sessions.
More mind bending stuff After you've solved your sessions issue by configuring your load balancer to assign cookies you will need to consider one more important issue. The
files
folder of both your server MUST be shared some how. This makes sense. If an image is uploaded by a user on one server, other people accessing the site through the other server should have access to the same image. This is accomplished by anNFS (Networked File System)
mount or a SAN.Only then you will have a fully functioning multi server installation of Drupal. As other people have pointed out, you might want to refer to some reference articles on the net. Further optimizations are recommended such as storing the sessions table in memcache and not in MySQL but again this has nothing to do with what I wrote above. Load balancer issuing cookies is really required.
Why go through so much grief I ask? I've done multi server stuff in the past and its not really worth it unless your site is getting some serious traffic. Is your traffic huge enough? Putting up a caching layer like Varnish in front of Drupal or even better, using the
boost
module should solve your problems if most of your users are anonymous.Check out this video http://sf2010.drupal.org/conference/sessions/24-million-page-views-day-60-m-month-one-server . The guy is serving out a crazy number of page views using only 1 server. Everything is so much simpler with one server. Try it out! Only the hugest of websites may require multiple servers.
您可以从 Drupal.org 的 服务器调整注意事项 和 用于 Drupal 企业可扩展性的简单决策树。
You may get some ideas from Drupal.org's Server tuning considerations and Simple Decision Tree for Drupal Enterprise Scalability.
将核心更改为Pressflow
http://pressflow.org/
聚合js和css
http://drupal.org/project/css_gzip
http://drupal.org/project/javascript_aggregator
使用缓存
nginx + Authcache + memcache + Easy authcache
http://drupal.org/node/110224
http://drupal.org/project/authcache
http://drupal.org/project/memcache
http://drupal.org/node /916742
或
nginx + Varnish + ESI + memcache
http://drupal. org/node/110224
http://drupal.org/project/varnish
http://drupal.org/project/esi
另请检查
http://getpantheon.com/
Change core to Pressflow
http://pressflow.org/
Agregate js and css
http://drupal.org/project/css_gzip
http://drupal.org/project/javascript_aggregator
Use caching
nginx + Authcache + memcache + Easy authcache
http://drupal.org/node/110224
http://drupal.org/project/authcache
http://drupal.org/project/memcache
http://drupal.org/node/916742
Or
nginx + Varnish + ESI + memcache
http://drupal.org/node/110224
http://drupal.org/project/varnish
http://drupal.org/project/esi
Also check
http://getpantheon.com/
很好的问题。这不是一个简单的答案。
您是否查看过 memecached 来了解可以提供帮助的缓存。
可以在 Drupal 前面使用 varnish 进行某些缓存。
当然,我假设您已经调整了性能设置。如果可以的话,用于正常甚至激进的缓存。
对于会话,您可以将负载均衡器设置为粘性会话,以便用户继续访问同一服务器。您甚至可以使用 Varnish 作为负载均衡器。
Nice problem to have. Not one easy answer.
Have you looked at memecached for the caching that can help.
As can using varnish in front of Drupal for certain caching.
Of course I assume that you already have tweaked your performance settings. For normal or even aggressive caching if you can.
For sessions, you can get your load balancer set to sticky sessions so that users will keep gonig to the same server. You can even use varnish as your load balancer for this.
我不确定我是否理解为什么其他答案不简单地建议将 PHP 会话存储到 MySQL 中。这样,场中的任何服务器都可以无缝响应任何请求。这种情况的限制是应用程序需要是无状态的,或者通过 PHP 会话数据或其他允许由另一台服务器恢复此类状态的替代方案来维护状态(例如由应用程序存储在 MySQL 中,而不是依赖于在会话上,或直接在将重新发布以允许继续的页面数据内 - 所有这些场景都意味着应尽可能避免的开销,但此负载平衡场景是必需的)。
任何在本地存储任何数据(即文件)的 Drupal 模块如果不进行一些修改就无法工作,但在大多数其他情况下它应该可以正常工作。保存的文件应该跨服务器复制,这可以通过将所有 Web 应用程序文件存储在网络文件系统上来实现,只要 IO 级别没有瓶颈,这应该可以很好地工作。替代方法是通过脚本复制动态文件,这很容易变得复杂且容易出错的过程。保持文件系统同步的解决方案确实存在,但需要仔细评估其可靠性,因为不可预测的错误(与网络或文件系统相关)可能会导致停止同步过程或出现必须手动解决的差异。
MySQL 中的 PHP 会话是通过使用此自定义会话处理程序来实现的,例如: PHP-MySQL-Sessions
I am not sure I understand why the other answers did not simply recommend to store the PHP session into MySQL. This way any server from the farm can answer any request seamlessly. The limitation with this scenario is that the application needs to either be stateless, or to maintain state though either PHP session data or some alternative that allows for such states to be recuperated by a another server (for example stored in MySQL by app instead of relying on session, or directly within the page data that will be re-posted to allow for continuation - all those scenarios imply an overhead that should be avoided when possible but is made necessary by this load balancing scenario).
Any Drupal modules that stores any data locally (i.e. files) will not work without some tinkering but in most other cases it should work fine. Saved files should be replicated across servers, this could be achieved by having all the web application files stored on networked file system, this should work well as long there is no bottleneck at the IO level. Alternatives are to replicate dynamic files via scripts, this can easily become a complicated and error prone process. Solutions to keep file systems in sync do exist but their reliability needs to be carefully assessed as unpredictable errors (network or file system related) will probably lead to either stopping the sync process or having discrepancies which will have to be manually addressed.
PHP sessions in MySQL are achieved by using this custom session handler such as : PHP-MySQL-Sessions