Google App Engine PHP55随机服务器崩溃(500's),错误代码为204

问题描述:

我们的团队一直在使用Slim PHP作为路由器和Propel ORM与MySQL一起开发此RESTful API,并将其作为Google App Engine中的服务在此应用中部署.yaml配置Google App Engine PHP55随机服务器崩溃(500's),错误代码为204

service: api 
runtime: php55 
api_version: 1 
threadsafe: yes 

instance_class: F1 
automatic_scaling: 
    min_idle_instances: automatic 
    max_idle_instances: automatic 
    min_pending_latency: automatic 
    max_pending_latency: automatic 

skip_files: 
- ^vendor/(.*/)+[Tt]ests/.*$ 
- ^\.(.*) 

handlers: 
- url: .* 
script: app.php 

由一个Ember.js web应用程序被消耗掉,通过所有的发展,我们已经收到奇怪的无图案服务器崩溃500S,更确切地说:

500 Server Error Error: Server Error The server encountered an error and could not complete your request. Please try again in 30 seconds.

与App Engine日志。

A problem was encountered with the process that handled this request, causing it to exit. This is likely to cause a new process to be used for the next request to your application. (Error code 204)

随机端点

,否则工作时细99%,我们当然不喜欢进入生产这些随机崩溃。

我们曾尝试:

  1. 检查是否正在达到了MySQL的max_connections因为我们打开和关闭连接的每个请求。
  2. 将我们的实例从F1升级到F4_1G以解决可能会耗尽内存的问题。与dev_appserver.py本地主机
  3. 压力测试,(我们没有得到任何在这里崩溃)
  4. 尝试赶上整个修身应用进行调试(这所以导致我们认为它实际上它实际上从未捕捉异常与Google App Engine有关)

以下是正常请求流程的一些代码。

app.php

/* 
* Create SLIM application 
*/ 
$app = new \Slim\App([ 
    "settings" => [ 
     "determineRouteBeforeAppMiddleware" => true, 
    ] 
]); 

//Custom Authentication middleware 
    $app->add(new \OAuth2Server\SlimAuthenticationMiddleware()); 

//CORS and Headers Middleware 
    $app->add(function($request, $response, $next) { 

     $response = $next($request, $response); 

     $response = $response->withHeader("Access-Control-Allow-Origin", "*"); 
     $response = $response->withHeader("Access-Control-Allow-Headers", "Content-Type, authorization"); 
     $response = $response->withHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, OPTIONS"); 
     $response = $response->withHeader("content-type", "application/json; charset=utf8"); 

     return $response; 

    }); 


    require_once("router.php"); 

    $app->run(); 

router.php

$app->get($apiVersionPath.'/visits/{id}','\Controllers\Visits:get') 
    ->add(new \OAuth2Server\ValidateRequestUser(array("doctor", "nurse","superuser","admin"))); 

访问控制器GET/ID相关的代码。

/** 
    * @param Request $request 
    * @param Response $response 
    * @param []$args 
    * @return Response 
    */ 
    public function get($request, $response, $args) { 

     $id = $request->getAttribute("route")->getArgument("id"); 

     $serializer = new Serializer(); 

     if(!is_numeric($id) || $id == 0){ 
        throw new InvalidArgumentException("Invalid Argument"); 
     } 

     $visit = \VisitQuery::create() 
        ->useUserQuery() 
        ->filterByClientId($request->getAttribute("user")->getClientId()) 
        ->endUse(); 

     $visit = $visit->findPk($id); 

     if(!isset($visit) || !($visit instanceof \Visit)){ 
        throw new EntityNotFoundException("Visit not found"); 
     } 

     $resource = $visit->toResource(false); 

     $serializer->addResource($resource); 

     $body = $response->getBody(); 
     $body->write($serializer->serialize()); 
     return $response; 

} 
+1

根据[此问题](https://issuetracker.google.com/issues/35900014)204通常意味着内存问题。由于颠倒实例类型没有帮助,也没有观察到任何模式,所以我只能建议添加您的应用程序代码,以防有人发现可疑或可能的解释。 –

+0

谢谢@DanCornilescu,我刚刚添加了请求流程的一些代码 –

我们在PHP Flex引擎上运行API服务,并在使用自动缩放时注意到类似的问题。为了解决这个问题,我们不得不碰到实例类(尝试去F2)并且总是通过将min_idle_instances设置为2来运行至少两个实例。

我们也遇到了同样的问题, App Engine在使用任务队列和基本缩放时使用。它看起来并不像你正在做的还没有,但如果是这样,我们发现的唯一的解决办法是启用queue.yaml中试和设置添加任务推送队列时,“快速失败”标题:

$pushTask = new PushTask($handler, 
    array('message_data' => json_encode($message)), 
    array('header'=> 'X-AppEngine-FailFast:true')); 

否则,任务组将失败并显示204错误。

有一件我感兴趣的事情是关于你的问题,它看起来像你试图做一个HTTP请求。在我们所有的测试中,为数不多的途径之一,我们能够通过在一个队列下降数以百计的任务和由每个他们的运行下面的代码重现错误:

$memCache = new Memcache; 
$memCache->set($_SERVER['HTTP_X_APPENGINE_TASKNAME'] . '_1', 'Test 1'); 
ch = curl_init(); 
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); 
curl_setopt($ch, CURLOPT_POSTFIELDS, 'hi'); 
curl_setopt($ch, CURLOPT_URL, 'https://www.google.com'); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
set($_SERVER['HTTP_X_APPENGINE_TASKNAME'] . '_' . $index, $message); 
$response = curl_exec($ch); 
$memCache->set($_SERVER['HTTP_X_APPENGINE_TASKNAME'] . '_2', 'Test 2'); 

任何时候我们得到了错误,我们能够通过在Memcache中的密钥{TASK_NAME}_1找到第一条消息,但我们无法找到第二条目{TASK_NAME}_2。就像你说的那样,没有任何异常会被捕捉,因为整个脚本都会死掉。

这种行为让我们相信有可能是与谷歌的实现卷曲的,因为我们使用的是全功能的版本问题:

extension = php_curl.dll 

但是我们并没有一个明确的答案。对我们来说唯一的解决方案是增加我们的实例计数并依靠重试来完成我们的代码。

希望上述解决方案之一能够为您服务,如果您有机会,您能向我们展示PHP.ini文件中的内容吗?

+0

说实话,我们只是尝试了一下php.ini,这个apc.cache_by_default =“0”(我们发现这个方法在google搜索时),其余的与GAE中php55的默认php.ini 相同。你有没有关于queue.yaml的任何参考? –