У меня есть комбо PHP / Apache, на котором запущено приложение. Внутри приложения я хочу сделать некоторые блокировки. В частности, если определенный запрос приходит несколько раз в быстрой последовательности, я хочу, чтобы только ОДИН PHP процесс обрабатывал его; остальные должны вернуть ошибку. Следовательно, мне нужен какой-нибудь мьютекс.
В настоящее время у меня есть мьютекс, основанный на apcu:
if (apcu_add('MY_MUTEX', true, 15)) {
try {
execute_command();
} finally {
apcu_delete('MY_MUTEX');
}
} else {
throw new Exception("Duplicate request!");
}
Однако я подозреваю, что он не работает, хотя у меня нет никаких доказательств, кроме каких-то странных поведение, которое может или не может быть результатом того, что этот мьютекс не работает.
Я также подозрительно, потому что APCU - это сначала кеш, а второй механизм блокировки, поэтому было бы разумно, если бы он кешировал данные в памяти , Однако при запуске Apache я вижу несколько (около 20) httpd
процессов. Разве каждый из этих процессов не получит отдельный кэш APCU?
Я также знаю, что PHP и Apache могут быть встроены в несколько потоковых разновидностей, которые должны совпадать. В моем случае выполнение httpd -V
показывает:
Server version: Apache/2.2.15 (Unix)
Server built: Jan 12 2017 17:09:39
Server's Module Magic Number: 20051115:25
Server loaded: APR 1.3.9, APR-Util 1.3.9
Compiled using: APR 1.3.9, APR-Util 1.3.9
Architecture: 64-bit
Server MPM: Prefork
threaded: no
forked: yes (variable process count)
Server compiled with....
-D APACHE_MPM_DIR="server/mpm/prefork"
-D APR_HAS_SENDFILE
-D APR_HAS_MMAP
-D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
-D APR_USE_SYSVSEM_SERIALIZE
-D APR_USE_PTHREAD_SERIALIZE
-D APR_HAS_OTHER_CHILD
-D AP_HAVE_RELIABLE_PIPED_LOGS
-D DYNAMIC_MODULE_LIMIT=128
-D HTTPD_ROOT="/etc/httpd"
-D SUEXEC_BIN="/usr/sbin/suexec"
-D DEFAULT_PIDLOG="run/httpd.pid"
-D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
-D DEFAULT_LOCKFILE="logs/accept.lock"
-D DEFAULT_ERRORLOG="logs/error_log"
-D AP_TYPES_CONFIG_FILE="conf/mime.types"
-D SERVER_CONFIG_FILE="conf/httpd.conf"
Итак, должен ли работать вышеуказанный код блокировки или нет?