I've encountered http 504 gateway timeout error for several times when I was trying to call a GET API that was programmed by PHP.
Here is my server and AWS environment.
An ec2 instance with Amazon Linux that is running php code (5.4.40) with apache server (2.4.12) to serve api calling from client.
An AWS elastic load balancer to balance traffic to one of my instances. (for now, I only have one instance, just set ELB for the future if I need more instances to handle traffic.)
An AWS RDS database (MySQL 5.6.21) for saving data.
From some articles about 504 gateway timeout, I've already tried to modify these settings:
# ELB
idle timeout => 300
# php.ini
max_execution_time => 301
max_input_time => 301
# httpd conf
MaxKeepAliveRequests => 100
KeepAliveTimeout => 30
But all of them are not helpful for me, it's still get 504 gateway timeout sometimes.
My php script is not a long script, it just get data from mysql database (AWS RDS) from 3 tables and return data to client, no uploading file or generateing big file, so I think the execution time is not the problem.
The strange thing is that 504 gateway timeout error is not always happened, most of time it is normal, just happened SOMETIMES, for now, I still don't understand when 504 error will happen, it's really strange, if anyone can give me some suggestions about how to resolve this problem, it's really a big favor for me.
=== New Update ===
I've just found a problem in my php code, I thought that's namespace with autoload problem.
I have 2 php files in the same folder, it means 2 classes with the same namespace
files:
My/Namespace
- Class1.php
- Class2.php
Class and namespace:
Class1
// Class1
namespace My\Namespace;
class Class1 {
public static function getInstance() {
//return...
}
}
Class2
// Class2
namespace My\Namespace;
class Class2 {
public static function getInstance() {
//return...
}
public function getClass1Instance() {
$class1 = Class1::getInstance();
return $class1;
}
}
In Class2.php I try to call Class1's static function, but I didn't add "use namespace", so I add the following line to Class2.php
use My\Namespace\Class1;
Problem was solved! But I still not really sure why I should add "use namespace" to Class2.php, Class1 and Class2 are both in the same namespace, should I add "use namespace" even through they are in the same namespace?
p.s. I found this namespace problem because when 504 gateway error happened, I tried to call the API many times in a short period, and the php error message show up and tell me
"Class1 is not found in Class2.php"
but sometimes php error message show
"Cannot call a overloaded function in Class2.php, getClass1Instance()"
Wish I provide enough message about this question, and thanks for everyone who left comment or answered my question, m(_ _)m
I suggest you take a look at the Health Check of ELB.
Health Check is a source of seemingly-random 504 errors when it is not properly configured. When the ELB thinks your server is not 'healthy' then ELB answers 504 to the end user, and that 504 error is not logged anywhere in your PHP environment because it was generated in the ELB.
See http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/ts-elb-healthcheck.html
Related
In my Symfony project, there is a queue message handler, and I have an error that randomly appears during the execution:
[2022-10-12T07:31:40.060119+00:00] console.CRITICAL: Error thrown while running command "messenger:consume async --limit=10". Message: "Library error: a socket error occurred" {"exception":"[object] (Symfony\\Component\\Messenger\\Exception
TransportException(code: 0): Library error: a socket error occurred at /var/www/app/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:62)
[previous exception] [object] (AMQPException(code: 0): Library error: a socket error occurred at /var/www/app/vendor/symfony/amqp-messenger/Transport/Connection.php:439)","command":"messenger:consume async --limit=10","message":"Library error: a socket error occurred"} []
The handler executes HTTP requests that could last some seconds and the whole process of a single message could even take more than one minute if APIs are slow. The strange thing is that the problem disappears for hours but then it randomly appears again. The more messages are sent to the queue, the easier it's to see the exception.
config\packages\messenger.yaml
framework:
messenger:
transports:
# https://symfony.com/doc/current/messenger.html#transport-configuration
async:
dsn: "%env(MESSENGER_TRANSPORT_DSN)%"
options:
exchange:
name: async_exchange
queues:
async: ~
heartbeat: 45
write_timeout: 90
read_timeout: 90
retry_strategy:
max_retries: 0
routing:
# Route your messages to the transports
'App\Message\MessageUpdateRequest': async
App\MessageHandler\MessageUpdateRequestHandler.php
<?php
declare(strict_types=1);
namespace App\MessageHandler;
use App\Message\MessageUpdateRequest;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
class MessageUpdateRequestHandler implements MessageHandlerInterface
{
public function __invoke(MessageUpdateRequest $message)
{
// Logic executing API requests...
return 0;
}
}
Environment
Symfony Messenger: 5.4.17
PHP: 8.1
RabbitMQ: 3.11.5
Things that I tried
upgrading Symfony Messenger to 5.4.17, using the fix available here;
adding the following options: heartbeat, write_timeout and read_timeout in the messenger.yaml file.
Related issues/links
https://github.com/php-amqp/php-amqp/issues/258
https://github.com/symfony/symfony/issues/32357
https://github.com/symfony/symfony/pull/47831
How can I fix this issue?
Regarding a socket error that occurs in Symfony Messenger, I always suggest following the step-wise approach and checking if you are missing anything. It should fix this type of error almost every time. Please follow these guidelines:
Verify that the RabbitMQ service is active and accessible.
Verify that the hostname, port, username, and password are listed in the messenger.yaml file are accurate.
In the messenger.yaml file, increase the heartbeat, write timeout, and read timeout settings.
Verify your use case to determine whether the max retries number in messenger.yaml is appropriate.
Look for any network problems that could be causing the socket error.
Make sure your PHP version is compatible with RabbitMQ and Symfony Messenger.
Verify that the server's resources (CPU, Memory, and Disk) are not used up.
Look for any relevant error messages in the PHP error log.
Determine whether there is a problem with the MessageUpdateRequestHandler class's logic.
Tip: Still stuck? Try to reproduce the error with a smaller message set and in a controlled environment to isolate the root cause that we may be missing.
Hope it helps. Happy debugging and good luck.
I host my web application on Debian 10 using symfony 5.4.
Users must authenticate to access my application.
I would like to know if it is possible to generate a 403 error in the Debian logs (/var/log/apache/access.log or elsewhere) in case of bad credentials ?
For the moment, the logs show a 'POST 302' error which does not suit me.
For symfony experts, I use loginFormAuthenticator extends AbstractLoginFormAuthenticator.
I don't know where I should do this. If it's on the server or in my application?
here is what i tried
namespace Symfony\Component\Security\Http\Authenticator;
abstract class AbstractLoginFormAuthenticator extends AbstractAuthenticator implements AuthenticationEntryPointInterface, InteractiveAuthenticatorInterface{
...
public function onAuthenticationFailure(Request $request, AuthenticationException $exception): Response{
...
return new RedirectResponse($url, 403, ['HTTP/1.0 403 Forbidden']);
Thanks for your feedback.
You cannot redirect with a code, the code is ignored because the redirection itself relies on a code in the 300 range (302 in this case).
If you want to give an error response, you can just throw $exception;, but there will be no redirect.
However, the application log should already contain the authentication failure. It's located in /path/to/app/var/log/prod.log or whatever environment you happen to be running instead of prod.
If you do want to log to the system logs, you can use php error_log function.
I've finished a web site that runs on my computer and on the old server. The problem is that the old server is dying and my employer wanted to move it to a new server.
When he moved it, one web page shows me an error:
The autoloader expected class "Equips\FrontendBundle\Helper\LDAPHelper" to be defined in file "/var/www/sinfratic_dev/src//Equips/FrontendBundle/Helper/LDAPHelper.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
and it's like "what?" because I haven't done anything of that part (I just worked with another part of the web). And I've checked that file and inside there is the class "LDAPHelper".
I know what a server LDAP is, but I don't know if that problem is because the new server cannot communicate with out LDAP server or it doesn't have all things installed (I've installed ldap-auth-client, ldap-auth-config, libaprutil1-ldap, libldap-2.4-2, libldap2-dev, libnss-ldap, libpam-ldap and php5-ldap; things that were on the old server but not in the new, but it still doesn't work).
Any idea?
Thanks you so much.
EDIT
Thanks for the comment. Here is the header of the file:
<?
namespace Equips\FrontendBundle\Helper;
class LDAPHelper {
Ok, it was PHP and something unexpected.
By default, short_open_tag is off, so this .php could not be readed properly.
Just needed to put it on in php.ini.
I moved the installation to a different server. I updated the configfile in the var/ directory and the banners are served, but the admin interface is not working.
i get the error:
A fatal error occurred OpenX can't connect to the database. Because of
this it isn't possible to use the administrator interface
i cleaned the cache directory in var but then i get
PHP Fatal error: Call to undefined method MDB2_Error::quoteIdentifier() in /[path]/opx/lib/OA/Upgrade/VersionController.php on line 50
I dont know which version this is, but it looks like its at least 2 years old.
Is there any special cache in place im not aware of?
Any help on this would be much appreciated.
Mental note,.. if you have the db on a different server then openx it does not matter if you set the host to the ip of the db server and the port.. as long if you not set protocol=protocol !!!
this is by far the most stupidest thing i have ever seen, there is no need for a protocol config, as php always uses the socket if you set "localhost".
It's not easy to tell exactly what's wrong here, but one can make a good guess:
As we can see from the error message, there is an object in your code that doesn't implement the method quoteIdentifier().
There are mainly two possible reasons for this: Either we're calling an older or newer version of the same Class instance which doesn't implement the method. Maybe because it's deprecated or who knows. Or the object simply isn't of the expected type.
Lo and behold, if we look for an MDB2 related class that DOES implement this method, it's the class MDB2. Not MDB2_Error! So now we know the reason for the error, it's time to speculate about the root cause.
Connecting to a database with MDB2 works roughly like this:
$mdb2 =& MDB2::connect('pgsql://usr:pw#localhost/dbnam');
if (PEAR::isError($mdb2)) {
die($mdb2->getMessage());
}
There it is. We can see that $mdb2 can actually be of type MDB2_Error, in case connecting goes wrong for some reason. So that is the cause: Your code cannot connect to the DB for some reason. So the next obvious step should be checking if your db user has the correct rights and is using the correct password. I am 100% sure your admin backend doesn't use the right credentials.
I recently got a job in a web newspaper. In the website, we have a very old and important Symfony Application, written for an older developer, long time gone.
That application is sacred: is the blood of the newspapers revenues. The problem is we have no backup, no developer installation, nothing, only the production installation
When I came here, I was very surprise for this risky decision. I week ago, the apps started to fail. I have zero experience in Symfony (i'm a rails developer), and that old apps was the "old and loyal dog who nothing will fail", but started to fail, and everyone is freaking out!
So, I need the help of the symfony developers of this site to find a "quick" solution meanwhile I try to convince my bosses that we need a more professional aproach (and the times and resources to do it)
The problem is this
Every time the people use the app, this message appear
fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 17106016 bytes) in /path/to/symfony/config_core_compile.yml.php on line 3366
The lines is in the middle of this function
public function shutdown()
{
if (!is_null($this->cache) && $this->cacheChanged)
{
$this->cacheChanged = false;
$this->cache->set('symfony.routing.data', serialize($this->cacheData));
}
}
I looked at google but only found people with the same problem, no solution... Please, anyone who could help me, Help me please!
I would try to first clear the cache in the app as the cache may just be massive.
in the symfony root folder run this command
php symfony clear:cache
If that does not solve the problem, I would up the memory limit until the root of the problem is fixed
So inside the index.php file add this before any symfony loading occurs
ini_set('memory_limit', '256M');
The best way to debug the app is to use the built-in dev environment. Add a file to the symfony web root that has the following:
// this check prevents access to debug front controllers that are deployed by accident to production servers.
// feel free to remove this, extend it or make something more sophisticated.
if (!in_array(#$_SERVER['REMOTE_ADDR'], array('127.0.0.1', '::1', 'YOUR IP ADDRESS HERE')))
{
die('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.<!-- ' . $_SERVER['REMOTE_ADDR'] . ' -->');
}
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
$configuration = ProjectConfiguration::getApplicationConfiguration('[app name]', 'dev', true);
sfContext::createInstance($configuration)->dispatch();
Don't forget to add your IP address in the third line so that you have access to view the dev environment data.
The app name is the name of the application that is in your %symfony root%/apps folder
I think the problems is the size of the cache of PHP, not symfony. The fastest way to overcome this issue is giving more memory to php. For your description you have 128MB of memory size, try giving 256 (for example). If you're on linux check this to change de memory size.
Know this is a patch, not a base solution.
And maybe it's working on debug mode. Check in the front controller /index.php the line
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', true);
It should be
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);