我有一个问题。 我拥有一个 128mb 的 vps 和一个简单的博客,每天只有一百次点击。 我安装了 nginx + php5-fpm。考虑到低访问量和内存,我决定将 fpm 设置为静态并运行 1 个服务器。当我进行随机测试时,例如通过持续 30 多分钟的 http 运行 php 脚本,我尝试在同一台机器上打开博客,并注意到该站点基本上无法访问。所以我去了配置并阅读了这个:
The number of child processes to be created when pm is set to 'static' and the
; maximum number of child processes to be created when pm is set to 'dynamic'.
; **This value sets the limit on the number of simultaneous requests that will be
; served**
最让我震惊的是,我不知道,因为我一直认为 php children 会像 http 服务器一样同时处理数百个请求会做! 做对了吗? 例如,如果我启动 2 个 php-fpm 子级并同时启动 2 个“长脚本”,所有使用相同 php 后端的站点都将无法访问??这怎么用? 你可能会想:-呃!一个 php 脚本(网页)通常在 100 毫秒内处理 - ... 毫无疑问,但是如果你的页面每个可以运行大约 10 秒并且我有 10 个访问者使用 php-fpm 和 5 个服务器会发生什么所以只接受每次同时5个请求?他们都会排队还是会超时?
老实说,我习惯于在 Windows 中使用 Apache 和 mod_php 运行网站,但我从未遇到过这些问题,因为显然这些限制并不适用于另一种使用 PHP 的方式。
这也引出了另一个问题。如果我有带 sleep(20) 的 file_1.php 和带 echo 的 file_2.php,如果我用 fastcgi 机器运行 file_1,然后运行 file_2,第二个文件将请求创建另一个服务器来处理 php 请求,使用更多的 4MB RAM .如果我对 apache/mod_php 做同样的事情,第二个文件将只使用 30KB 以上的 RAM(在 apache 服务器中)。考虑到如果使用的 ram 实际上更少,为什么 mod_php 正在考虑“坏人”......我知道我在这里错过了大局。
最佳答案
你基本上做对了。您配置了一个静态数量的工作人员(这个数字是“一个”)——所以这正是您得到的。
但是您不太了解事情通常是如何运作的,因为您说:
I always assumed that a php children would handle hundreds of requests at the same time like a http server would do!
我不太熟悉 nginx,但考虑一下 apache 中典型的 mod_php 设置。如果您使用的是 mod_php,那么您使用的是用于 apache 的 prefork mpm。因此,每个并发的 http 请求都由一个不同的 httpd 进程(无线程)处理。如果您正在为低内存调整 apache/mod_php 服务器,您将不得不调整 apache 设置以限制它将产生的进程数(特别是 MaxClients)。
没有调整这些东西意味着当你遇到一个大的流量峰值时,apache 开始产生大量繁重的进程(记住,它是 mod_php,所以你在每个 httpd 进程中嵌入了整个 PHP 解释器),然后你运行内存不足,然后一切开始交换,你的服务器开始冒烟。
正确调整(意思是:调整以便您忽略请求而不是为更多进程分配您没有的内存),客户端会超时,但是当流量消退时,一切都会恢复正常。
将其与 fpm 以及更智能的 Web 服务器架构(如 apache-worker 或 nginx)进行比较。现在你有一些更大的线程池(仍然是可配置的!)来处理 http 请求,还有一个单独的 php-fpm 进程池来处理需要 PHP 的请求。基本上是一样的,如果你不限制可以创建多少个进程/线程,你就是在自找麻烦。但是,如果您进行了调优,您就会领先,因为您的请求中只有一小部分使用 PHP。因此,从本质上讲,每个 http 请求所需的平均内存量较低——因此您可以使用相同的内存量处理更多的请求。
但是将数字设置为“1”太极端了。在“1”,选择静态或动态都没有关系,因为无论哪种方式,您都只有一个 php-fpm 进程。
因此,要尝试对特定问题给出明确的答案:
You may think: -duh! a php script (web page) is usually processed in 100ms- ... no doubt about that but what happens if you have pages that could run for about 10 secs each and I have 10 visitors with php-fpm with 5 servers so accepting only 5 requests per time at the same time? They'll all be queued or will experience timeouts?
是的,他们都会排队,并最终超时。不过,您经常拥有需要 10 秒才能运行的脚本这一事实才是真正的罪魁祸首。有很多方法可以解决这个问题(缓存、工作队列等),但正确的解决方案完全取决于您要做什么。
I'm honestly used to run sites in Windows with Apache and mod_php I never experienced these issues because apparently those limits don't apply being a different way of using PHP.
它们确实适用。您可以像使用 nginx/php-fpm 一样设置 apache/mod_php 服务器——只需将 apache 的 MaxClients 设置为 1!
This also raises another question. If I have file_1.php with sleep(20) and file_2.php with just an echo, if I run file_1 and then file_2 with the fastcgi machine the second file will request the creation of another server to handle the php request using 4MB RAM more. If I do the same with apache/mod_php the second file will only use 30KB more of RAM (in the apache server). Considering this why is mod_php is considering the "bad guy" if the ram used is actually less...I know I'm missing the big picture here.
特别是在 linux 上,很多报告内存使用情况的东西可能会产生误导。但是这样想:那 30kb 可以忽略不计。这是因为当某些 httpd 进程启动时,PHP 的大部分内存已经分配完毕。
128MB VPS 相当紧凑,但应该能够处理多个 php 进程。
如果你想优化,做这样的事情:
对于 PHP:
pm = static
pm.max_children=4
对于 nginx,弄清楚如何控制进程和线程数(无论什么相当于 apache 的 MaxClients、StartServers、MinSpareServers、MaxSpareServers)
然后弄清楚如何生成一些实际负载(apachebench、siege、jmeter 等)。使用 vmstat、free 和 top 来观察您的内存使用情况。将 pm.max_children 和 nginx 的东西调整到尽可能高,而不会导致任何重大交换(根据 vmstat)
关于php5-fpm child 和请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10678542/
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)
在我的路线文件中我有:match'graphs/(:id(/:action))'=>'graphs#(:action)'如果是GET请求(工作)或POST请求(不工作),我想匹配它我知道我可以使用以下方法在资源中声明POST请求:post'/'=>:show,:on=>:member但是我怎样才能为比赛做到这一点呢?谢谢。 最佳答案 如果你同时想要POST和GETmatch'graphs/(:id(/:action))'=>'graphs#(:action)',:via=>[:get,:post]编辑默认值可以设置如下match'g
我试图像这样在我的测试用例中执行获取:request.env['CONTENT_TYPE']='application/json'get:index,:application_name=>"Heka"虽然,它失败了:ActionView::MissingTemplate:Missingtemplatealarm_events/indexwith{:handlers=>[:builder,:haml,:erb,:rjs,:rhtml,:rxml],:locale=>[:en,:en],:formats=>[:html]尽管在我的Controller中我有:respond_to:html,
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
如果使用rspec请求花费的时间太长,我该如何测试行为?我正在考虑使用线程来模拟这个:describe"Test"doit"shouldtimeoutiftherequesttakestoolong"dolambda{thread1=Thread.new{#net::httprequesttogoogle.com}thread2=Thread.new{sleep(xxseconds)}thread1.jointhread2.join}.shouldraise_errorendend我想确保在第一次发出请求后,另一个线程“启动”,在这种情况下只是休眠xx秒。然后我应该期望请求超时,因为执
假设我有:get'/'do$random=Random.rand()response.body=$randomend如果我每秒有数千个请求到达/,$random是否会被共享并“泄漏”到上下文之外,或者它会像getblock的“本地”变量一样?我想如果它是在get'/'do的上下文之外定义的,它确实会被共享,但我想知道在ruby中是否有我不知道的$机制。 最佳答案 ThispartoftheSinatraREADMEaboutscopeisalwayshelpfultoread但是,如果您只需要为请求保留变量,那么我认为我建议使用
运行以下命令时:rvminstall1.9.3我得到以下输出:Error:therequestedURLdoesnotexist:ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-.tar.bz2我已将rvm更新到最新版本并输入rvmreload有什么想法吗? 最佳答案 URL应该是这样的:ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p194.tar.bz2尝试更新您的rvmrvmgethead然后安装1.9.3rvminstall1.9.3
我有一个具有“名称”属性和“标签”属性的照片类。我的目标是在Rails中实现一个更新功能,用输入的内容替换照片的标签。例如,如果我尝试PUT一个将“标签”设置为[]的JSON对象,我希望从照片中清除任何标签。但是,当我通过HTTParty提交一个空数组作为主体参数之一时,我相信HTTParty正在将[]翻译成nil。因此,我的Rails后端的photos#update端点没有接收到任何参数“tags”。我正在寻找一种方法让HTTParty不将[]转换为nil,因为我失去了从照片中删除标签的能力。 最佳答案 这是Rails4中的一个错