Блокировка сессии Битрикс. Хранение сессии на redis
Когда пользователь на поиске, в каталоге или в карточке товара, много раз жмет на кнопке ПЛЮС для добавления в корзину, отправляются аякс запросы подряд. На время выполнения запроса, блокируется сессия. И следующий ajax запрос ждет(пытается получить сессию), пока исполнится предыдущий. Если пользователь подряд нажмет 20 раз, улетит 20 запросов подряд — все ждут пока освободится сессия, забиваются все обработчики php и пока сервер не разгребет, сайт зависает.
Все источники в интернете говорят о хранении сессии на Redis — это самое оптимальное решение т.к. он не блокирует сессии. В Битрикс есть настройка для хранения сессий в redis. Для этого в файле .settings.php необходимо заменить блок session на следующий. Соответственно порт и хост нужно прописать свой. Их может выдать ваш хостер
// bitrix/.settings.php return [ 'session' => [ 'value' => [ 'mode' => 'default', 'handlers' => [ 'general' => [ 'type' => 'redis', 'port' => '6379', 'host' => '127.0.0.1', ], ], ], ]
После установки данной настройки необходимо в файле, куда идет много запросов ajax, добавить константу define(‘BX_SECURITY_SESSION_READONLY’, true); до подключения ядра продукта. Но важно помнить, как видно из названия константы, сессия не будет записана на данном хите, а только будет доступна для чтения, где установлена константа
Ошибка noauth authentication required. (0) Битрикс
Если вы получили ошибку noauth authentication required. (0) , это означает что при подключении к серверу redis необходимо ввести пароль. К сожалению битрикс не добавило в свой функционал установку пароля для подключения к redis. Но можно самим допилить функционал Для этого
1. в файле \bitrix/.settings.php в блоке session допишем параметр ‘auth’ => ‘password’, где password это ваш пароль от redis
'session' => [ 'value' => [ 'mode' => 'default', 'handlers' => [ 'general' => [ 'type' => 'redis', 'port' => '6379', 'host' => '127.0.0.1', 'auth' => 'E34ewei94235235aiYoo34F7z', ], ], ], ],
2. в файле \bitrix\modules\main\lib\session\handlers\redissessionhandler.php в конструкторе класса RedisSessionHandler допишем в параметрах подключения ‘auth’ => $options[‘auth’] ?? null
$connectionPool->setConnectionParameters(self::SESSION_REDIS_CONNECTION, [ 'className' => RedisConnection::class, 'host' => $options['host'] ?? '127.0.0.1', 'port' => (int)($options['port'] ?? 11211), 'servers' => $options['servers'] ?? [], 'serializer' => $options['serializer'] ?? null, 'failover' => $options['failover'] ?? null, 'timeout' => $options['timeout'] ?? null, 'readTimeout' => $options['readTimeout'] ?? null, 'persistent' => $options['persistent'] ?? null, 'auth' => $options['auth'] ?? null, ]);
3. в файле \bitrix\modules\main\lib\data\configurator\redisconnectionconfigurator.php в классе RedisConnectionConfigurator и методе createConnection после соединения $connection->connect($host, $port) добавим строчку $connection->auth($config[‘auth’]);
$result = $connection->connect($host, $port); $connection->auth($config['auth']);
И все, теперь соединение будет использовать пароль для доступа с redis и ошибка больше появляться не будет. Почему битрикс разработчики не позаботились об этом не понятно. Но при обновлении битрикс, вполне вероятно, что эти изменения перетрутся и их нужно будет внести заново.
Ошибка Undefined class constant ‘SERIALIZER_IGBINARY’ (0) Битрикс
Эта ошибка возникает после установки redis. Это означает, что phpredis не был скомпилирован с поддержкой IGBINARY.
Для всех, кто столкнулся с этой проблемой, просто переустановите и скажите «да» поддержке igbinary!
Работа с сессиями
Для включения хранения сессий в memcached необходимо в /bitrix/php_interface/dbconn.php или /local/php_interface/dbconn.php установить следующие константы:
define('BX_SECURITY_SESSION_MEMCACHE_HOST', 'localhost'); define('BX_SECURITY_SESSION_MEMCACHE_PORT', 11211);
либо в случае использования unix-socket:
define('BX_SECURITY_SESSION_MEMCACHE_HOST', 'unix://path/to/memcached.sock'); define('BX_SECURITY_SESSION_MEMCACHE_PORT', 0);
Не блокирующие сессии
Подходит для AJAX. После этого сессия читается из memcached или БД не ожидая получения блокировки:
define('BX_SECURITY_SESSION_READONLY', true);
Виртуальные сессии
Подходит для REST: сессия создается в памяти, не ждет блокировок и не сохраняется.
define('BX_SECURITY_SESSION_VIRTUAL', true);
Что такое сессии в битрикс
Граф наследования:Session:
Открытые члены
Защищенные члены
Защищенные данные
Подробное описание
См. определение в файле session.php строка 11
Конструктор(ы)
◆ __construct()
__construct | ( | \SessionHandlerInterface | $sessionHandler = null | ) |
См. определение в файле session.php строка 33
Хранение сессий Битрикс в memcached
Данный способ хранения сессий дает следующие преимущества:
- нет необходимости следить за количеством старых сессий на нагруженном проекте;
- возможность разделять сессии между серверами в кластере;
- возможность использовать не ожидающую получения блокировки сессию;
- возможность использовать виртуальные сессии.
define('BX_SECURITY_SESSION_MEMCACHE_HOST', 'localhost'); define('BX_SECURITY_SESSION_MEMCACHE_PORT', 11211);
Либо, в случае использования unix-socket:
define('BX_SECURITY_SESSION_MEMCACHE_HOST', 'unix:///path/to/memcached.sock'); define('BX_SECURITY_SESSION_MEMCACHE_PORT', 0);
После этого, включить в модуле проактивной защиты, хранение сессий в базе данных. В результате получаем хранение сессий в memcached средствами ядра.