Coldfusion: лучше оставить в сеансе только user_id или весь объект пользователя? - PullRequest
3 голосов
/ 24 марта 2011

У меня есть CFC для обработки объекта пользователя.Мой вопрос: лучше ли хранить только идентификатор_пользователя в сеансе и заново создавать объект пользователя с каждым запросом?Или лучше хранить весь пользовательский объект в сеансе?

Вот мои мысли в любом случае:

  • Если я сохраню весь объект в сеансе:

    • Потенциально меньше ресурсов процессора
    • Потенциально больше памяти -
    • все методы / функции сохраняются в реальном объекте, а новые функциито, что я обновляю в cfc, будет недоступно, пока пользователи не выйдут из системы и не войдут обратно, или если я придумаю какой-то способ заставить его обновиться сам.
    • Могут быть проблемы с мьютексом или блокировкой, если я возиться собъект через параллельные вызовы ajax
  • Если я сохраню только user_id в сеансе:

    • Мне придется создавать объект пользователя с каждымзапрос страницы (возможно, больше нагрузки на процессор)
    • Потенциально меньше будет памяти,
    • Не будет шансов для условий мьютекс / блокировка / гонка, поскольку каждый запрос будет иметь свой собственныйкопия пользовательского объекта
    • Обновления самой модели CFC будут немедленно распознаны во всей системе, и пользователям не придется выходить из системы и обратно

Есть ли нормальная практика для такого рода вещей?Я слишком обдумываю это?

Ответы [ 4 ]

5 голосов
/ 24 марта 2011

Все написанные мной CF-приложения были нацелены на высокий уровень трафика и высокую доступность, поэтому у нас никогда не было роскоши думать о практике работы с одним сервером.

Итак, по моему опыту, мне всегда приходилось: а) учитывать несколько серверов с балансировкой нагрузки и б) избегать липких сессий на балансировщике нагрузки по ряду причин. Поэтому нам нужно было, по крайней мере, сделать так, чтобы сервер стал частью кластера на лету и собирал трафик в середине сеанса.

Таким образом, мы всегда извлекаем данные «сеанса» из общего хранилища данных при каждом запросе.

Мое предложение заключается в реализации фасада сеанса .

Это дает вам возможность изменить способ сохранения данных сеанса (например, записи пользователя) без изменения остальной части вашего приложения.

Вы можете выбрать, негласно, хранить все в области сеанса, загружать его для каждого запроса, делать гибрид, использовать хранилище значений ключей, что угодно.

Вы можете выбрать, загружать ли данные с большой нагрузкой, лениво загружать данные или что-то среднее между ними, и остальная часть приложения не должна знать, что вы сделали.

В условиях гонки

Если вас беспокоит состояние гонки, я бы предложил использовать именованные блокировки для фиксации и доступа к данным. Это еще один бонус использования фасада - код вашего приложения не должен знать об этом, и вы можете установить блокировку вокруг определенных объектов, а не блокировать весь сеанс.

2 голосов
/ 24 марта 2011

Это частичное дублирование ответа Кена Редлера, но у меня недостаточно репутации, чтобы комментировать.

То, как мы это делаем, и то, как я предпочитаю, это хранить пользовательские данные в сеансекак структура.Затем при запуске запроса наша Auth Model создает объект пользователя в области запроса и переопределяет любые значения по умолчанию данными сеанса.В этом есть несколько преимуществ:

  • Меньше обращений к базе данных, меньше ЦП
  • Всегда запускайте новейший код без сложной настраиваемой системы, гарантируя, что
  • Кластерная средадружественный (сложные объекты в Session не могут быть кластеризованы)
  • Может добавлять или удалять свойства без повреждения (при условии, что ваш объект User обновляет только грязные столбцы)

Также, если выИспользуя CF9, одна из функций, которыми они действительно гордились, - насколько они оптимизировали создание объектов.Если нет, проверьте сами!

2 голосов
/ 24 марта 2011

Вы не указали, используете ли вы ORM, так что это общий ответ.

Для типичных приложений я рекомендую создавать экземпляр объекта пользователя в области сеанса. Есть большой недостаток в создании объекта заново с каждым запросом, который вы не включили в свой список: изменения свойств и состояния объекта пользователя не будут сохраняться в разных запросах, если вы не намереваетесь сбросить состояние объекта пользователя на свой уровень персистентности (например, база данных) на каждый удар. Скорее всего, это будет гораздо более дорогая операция, чем создание объекта, и она не обязательно изолирует вас от тех проблем, о которых вы думаете в отношении вызовов ajax, условий гонки и т. Д. - она ​​просто передает проявление эти проблемы на уровне персистентности, где данные вашего объекта могут быть в непредсказуемом состоянии.

Поскольку каждый новый запрос был бы «неявным сохранением», вам также нужно было бы спроектировать свой «эфемерный» объект так, чтобы он сохранялся независимо от того, находится ли он в допустимом состоянии (представьте себе случай многостраничной формы который изменяет некоторые аспекты объекта пользователя).

Для объектов, хранимых в сеансе, ваши опасения по поводу памяти могут быть смягчены тщательными методами проектирования. Например, если у вашего пользователя много задач, а у каждой задачи много элементов, может быть плохой идеей создать экземпляр всех этих объектов и объединить их в свой пользовательский объект (т. Е. Ленивая загрузка была бы лучшим подходом, чем стремительная загрузка).

Если вам действительно необходимо иметь возможность изменять свои CFC на лету, вы можете достичь этой цели даже с сохраненными в сеансе объектами. Одним из способов является сохранение флага версии как в приложении, так и в сеансе. С каждым запросом ваше приложение будет сравнивать эти флаги. Если они различаются, приложение запускает процедуру перезагрузки сеанса, которая снимает текущие свойства, перестраивает сохраненные в сеансе объекты и, наконец, обновляет флаг сеанса, чтобы соответствовать флагу приложения.

1 голос
/ 24 марта 2011

Это зависит .

Если у вас много трафика - в диапазоне тысяч уникальных посетителей в минуту - накладные расходы на хранение вашего User.cfc в сеансе со временем будутутяжелить тебяЭтого можно легко преодолеть, добавив к нему аппаратное обеспечение (на какое-то время больше памяти, в конечном итоге - больше серверов и аппаратный балансировщик нагрузки).Конечно, популярность - это хорошая проблема.

Если вам кажется, что в вашем пространстве базы данных есть ЦП, сеть или другое узкое место, вы можете захотеть поместить объект в кэш в памяти сеанса, чтобы у вас было меньше обращенийв базу данных.

Почему я упоминаю эти сценарии?Возможно, вы преждевременно оптимизируете - не решайте проблему, которой у вас нет.Не оптимизируйте вашу память, ЦП и доступ к базе данных до тех пор, пока не возникнут или не возникнут проблемы.

Теперь, исходя из наилучшей архитектурной практики, а не оптимизированного «что лучше для моего процессора» - ну, ямогу только сказать: Это зависит .

По правде говоря, ни один из способов не является неправильным.Если вам нужно проверять учетные данные в вашей базе данных при каждом запросе, не кэшируйте их.Если вам нравится ощущение объекта в сеансе, кешируйте его.Поскольку вы знаете свой собственный домен, вы, вероятно, можете целый день возвращаться и назад, почему вы должны или не должны кэшировать объект пользователя в сеансе.Если это будет облегчать, сделай это.Если это будет усложнять, не надо.

Я бы просто предостерег вас от того, чтобы делать что-то невероятно запутанное или что-то, что не сразу бросается в глаза разработчику, смотрящему на ваше приложение - чем больше вы пишете, тем большевы должны поддерживать вечность, тем больше ваши коллеги будут ассоциировать ваше имя со злом.

Наконец, последнее замечание: если это голосование, я говорю, что вы его кешируете.Это имеет смысл и всегда приятно вызывать session.user.hasRole ("xyz") или тому подобное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...