Как стать автором
Обновить

Комментарии 21

По-умолчанию сессии хранятся в файлах, и вроде он также блокирует файл в начале сессии и разблокирует когда скрипт завершится. Можно попробовать сессии хранить в memcache, если доступ позволяет и нет других подводных камней. Или закрывать сессию, а потом выполнять «тяжелый» код
php-memcached тоже блокирует сессии
php-memcache нет
Уже давно стало традицией использовать БД для работы с сессиями. Помниться с подобной проблемой столкнулся 5 лет назад.
В качестве БД для сессий мне по нраву Mongo.
Использование другого хранилища не должно повлиять на саму работу сессий.
Верно сказано — "не должно", но увы — либо смирись, либо переделывай сам.
А как решаете вопрос консистентности данных в сессии?
Я не использую сессию для хранения подобных данных, там только данные по авторизации пользователя и текущей сесиии. Если нужна статистика — использую модуль статистики, для работы с временными данными — memcache или тот же mongo.
Хорошие такие грабельки…
Андрей привет
На сколько я помню, с подобным мы ещё в РИА сталкивались. Но, тогда особого значения этому не придали.
Да, привет) вот и у меня что-то смутное в голове шевельнулось, решил написать.

Мы не могли столкнуться с этим в РИА, т.к. там использовался Drupal 6. который хранит сессии в БД.

Может ты столкнулся с этим, во время работы в РИА, но в другом проекте? :)
Повторюсь — место хранения сессии не должно влиять на саму работу механизма. Иначе нарушается целостность.
Надо пробовать конечно, но мы с Денисом в скайпе пришли к выводу, что хранилище не влияет.
Какая целостность?

Если два процесса считали данные сессии и изменили разные части, то из-за простоты реализации сессий запишет изменения только один. Тут выбор: либо не давать читать, либо затереть другие данные (как с базой данных).
Этот нюанс работы с сессией в ПХП уже давно всем известен, но с периодичностью 1-2 года эта тема снова всплывает…
«Изменение хандлеров сессии не поможет.»
Прекрасно помогает изменение или переписывание хэндлеров на те, которые используют неблокируемые ресурсы для хранения сессионных данных.
Имеет также смысл подумать, а нужна ли вам именно PHP-сессия, и для чего? Есть и другие инструменты.
А где можно хранить сессию, чтобы она не блокировалась?
Я так понимаю, в этом случае консистентностью придется пожертвовать?

По поводу сессий. Используется ZF 1. Там есть авторизация для админки, плюс флеш сообщения. От сессии конечно отказаться можно, но проще хранить сессию в неблокирующих хранилищах, либо использовать другие механизмы. Пока что решил вопрос session_write_close

Я проектом почти не занимаюсь, времени нету, поэтому приходится искать самые не затратные по времени пути для решения.
Сначала надо определиться — нужна ли блокировка сессии. Это зависит от того, какие данные хранятся в сессии и как они используются.
В своё время я для своего проекта пришёл к выводу, что от блокировки можно отказаться.
Далее пользовал встроенные механизмы memcache(d), но в итоге остановился на использовании очень простых собственных хэндлеров. Получив при этом прозрачный для меня механизм сессии, вместо «чёрного ящика». Это оказалось плюсом, т.к. проект был нагружен (более миллиона pageview в сутки).
Вот код:

function my_session_open($save_path, $session_name) {
  return true;
}
function my_session_read($id) {
  $GLOBALS['session_read_return'] = Cache_Proxy::get($id);
  return $GLOBALS['session_read_return'];
}
function my_session_write($id, $data) {
  if ($GLOBALS['session_read_return'] == $data) return true;  // Если в пределах этого запроса данные не менялись - не записываем их обратно
  return Cache_Proxy::set($id, $data, 0, 36000);
}
function my_session_destroy($id) {
  Cache_Proxy::delete($id);
  return true;
}
function my_session_gc($maxlifetime) {
  return true;
}
function my_session_close() {
  return true;
}
session_set_save_handler('my_session_open', 'my_session_close', 'my_session_read', 'my_session_write', 'my_session_destroy', 'my_session_gc');
register_shutdown_function('session_write_close');

В качестве кэша используется APC (apc_fetch и apc_store). Работает очень быстро при любых нагрузках. Сбором мусора занимается АРС.

PS: если бы завтра нужно было писать новый проект с нуля, я бы вообще не стал бы использовать такой механизм как сессии. По сути вся «сессия» — это уникальная кука на клиенте + данные на стороне сервера, однозначно связанные со значением этой куки. Так зачем всё усложнять и вносить в систему такой чёрный ящик, как стандартные сессии? (прошу воспринимать это не как совет, а как личное мнение, которое вполне может быть ошибочным)
Вы не стали бы использовать такой механизм как «сессии» или такой механизм как «стандартные сессии»?
Речь, конечно, о встроенных в PHP сессиях. Ведь для авторизации в любом случае надо хранить где то на сервере соответствие «авторизационная кука»-«userid». Однако, сегодня я бы сделал это без использования $SESSION. Сегодня я бы хранил авторизационные сессии в кэше (быстро) и дублировал в БД — на случай обнуления кэша.
А хранить в сессии какие-то другие данные? Сходу и не придумаю сценария, какие это могут быть данные и почему они должны быть именно в сессии.
Здесь ( goo.gl/72s8iX ) конкретный рабочий пример (кусок кода) для реализации и предотвращения подобного.
Нуда, последний абзац как раз об этом.
Там REST full-stack описание. (а не только про сессии)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории