PHP 10000 одновременных вызовов и запросов MYSQL время ожидания и медленно

У меня есть очень простой запрос, который вставляет каждый вызов API в таблицу messageRequest. это может идти максимум 1000 запросов или больше в секунду.

например, http://myapplication.com/sendMessage.php?phone=123&GSM = Mobitel&сообщение = HelloWorld

Предположим, любой, у кого есть мобильное приложение, будет называть этот URL и когда я делаю как 1000 звонков через

ab -n 1000 -c 10 «http://myapplication.com/sendMessage.php?phone=123&GSM = Mobitel&сообщение = HelloWorld«

Запрос insert into messageRequest values(null, phone, gsm, message);

он работает нормально, но проблема в том, что при наличии такого количества одновременных звонков я пытаюсь использовать страницу журнала активности в этом URL http://myapplication.com/apiLogs.php чтобы увидеть, сколько SMS-вызовов API получено за последние 30 минут.

Это просто запросы SELECT count(*) from messageRequest where created_at > '2016-10-01 12:01:00'

для возврата результата требуется около 100 секунд. и когда я перестал делать параллельные звонки через ab -n command работает нормально. поэтому я предположил, что когда происходит 1000 одновременных вызовов и запись вставляется для каждого вызова, MYSQL таблица messageRequest блокируется.

чтобы избежать этой проблемы,

я изменил это на несколько сеансов, например, на sendMessage.php я сделал это с user1, и для apiLogs.php я сделал это с user2. таким образом, две сессии diff могут обращаться к одной и той же таблице для одновременного чтения и записи, но это тоже не помогло.

sendMessage.php

define('DB_HOST', 'localhost');
define('DB_USER', 'user1');
define('DB_PASS', '');

apiLogs.php

define('DB_HOST', 'localhost');
define('DB_USER', 'user2');
define('DB_PASS', '');

я запутался, как заставить это работать без всякого времени ожидания, когда столько одновременных звонков?

Обновить

код sendMessage.php

define('DB_HOST', 'localhost');
define('DB_USER', 'user1');
define('DB_PASS', 'user1');

mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_select_db('smsApp');mysql_query(
"insert into messageRequest values (
NULL,
'{$_REQUEST['phone']}',
'{$_REQUEST['gsm']}',
'{$_REQUEST['message']}',
'{$_REQUEST['text']}',
now()
);
");

И я делаю параллельный запрос с этой командой

ab -n 1000 -c 10 "http://myapplication.com/sendMessage.php?phone=123&gsm=mobitel&message=helloworld&text=123"

И пока работает, я пытаюсь просмотреть эту страницу apiLogs.php (исходный код ниже)

  define('DB_HOST', 'localhost');
define('DB_USER', 'user2');
define('DB_PASS', 'user2');

mysql_connect(DB_HOST, DB_USER, DB_PASS);
mysql_select_db('smsApp');

$30m_ago = new DateTime("30 minutes ago");
$s = $30m_ago->format("Y-m-d H:i:s");
$result = mysql_query("SELECT count(*) from messageRequest where created_at > '$s'");

$response['last_30_min_sms_count'] = current(mysql_fetch_row($result));

echo json_encode($response)."\n";

2

Решение

Используйте InnoDB, а не MyISAM. Таким образом, стол не будет заблокирован.

Не используйте устаревший mysql_* API, использовать mysqli_* или же PDO,

«Не ставь в очередь, просто сделай это». То есть может быть значительно быстрее просто выполнить задачу, чем проходить через очередь.

Фрагмент кода подвержен «SQL-инъекции».

Иметь INDEX(created_at), Тот SELECT может работать полностью в индексе.

Вместо DateTime пакет, вы могли бы просто сказать, SELECT ... WHERE created_at > NOW() - INTERVAL 30 MINUTE,

Больше

С InnoDB я предлагаю innodb_flush_log_at_trx_commit = 2 значительно сократить ввод-вывод, вызванный 1000 отдельных INSERTs в секунду.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]