Buscar

www_eduardopires_net_br_2015_04_pense_duas_vezes_antes_de_ut

Prévia do material em texto

Pense duas vezes antes de utilizar Sessions
Postado em 2 DE ABRIL DE 2015
Session é um recurso utilizado em inúmeras situações no ASP.NET, porém já faz algum tempo que seu uso não é
mais recomendado, conheça os principais motivos e como você pode substituir as sessions em seu projeto.
Session é um assunto muito abordado em inúmeros fóruns de discussões em todo mundo. Foi introduzido no ASP
clássico e sua utilização está presente até os dias de hoje no ASP.NET.
Armazenar informações de usuário logado no sistema, itens do carrinho de compras, resultado de uma pesquisa em
banco de dados e demais cenários geralmente são resolvidos através do armazenamento em sessions. Por que isso não
é recomendado?
O conceito de Web é Stateless
Uma aplicação web não deve manter estado, uma aplicação web deve usar sempre que possível recursos assíncronos
no client-side e server-side, isso proporcionará performance pois não satura o pipeline da aplicação e escalabilidade pois
não depende de recursos disponíveis em um determinado servidor.
Sessions utilizam a memória do pool do IIS
Por padrão as sessions são armazenadas no pool do IIS e isso é uma péssima opção para armazenar dados de
usuários, pois o pool do IIS recicla constantemente e isto está fora do controle do desenvolvedor, por diversos motivos o
pool pode ser reciclado e todos os usuários perderão as informações armazenadas, isso é muito frustrante para o
usuário da aplicação e nunca deveria acontecer.
Uma solução para isso seria utilizar sessions out-of-proc (armazenando as sessions em um SQL Server ou outro State
Server), mas não significa que que é uma boa alternativa, existem alguns problemas nessa abordagem:
1. Irá custar 2 requisições extras de rede, uma para carregar a session antes do request ser processado e outra para
armazenar novamente o estado da session após o request. E isso irá ocorrer a cada request mesmo que não esteja
utilizando a session em determinada página.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
https://www.eduardopires.net.br/2015/04/pense-duas-vezes-antes-de-utilizar-sessions/
http://blogs.msdn.com/b/johan/archive/2007/05/16/common-reasons-why-your-application-pool-may-unexpectedly-recycle.aspx
https://msdn.microsoft.com/en-us/library/ms178586.aspx
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
2. Não é performático, a cada request a session precisa ser serializada e deserializada, isso irá custar mais recursos
de CPU e memória.
3. Bancos de dados relacionais não são mais rápidos que o acesso de memória, não é performático realizar 2 hits no
banco a cada request de cada usuário.
4. Poderá saturar o pipeline da aplicação, uma vez que um request depende da leitura de um banco de dados para
finalizar seu ciclo de vida.
Sessions são de acesso exclusivo
Sessions irão prejudicar a performance de requests concorrentes. Suponha que uma página via AJAX dispare 2 requests
para o mesmo usuário, o acesso de leitura da session é exclusivo, logo o ASP.NET irá forçar que o segundo request
aguarde enquanto o primeiro faz a leitura da session, isso implica na escalabilidade da aplicação.
Recursos do HTML 5 permitem conexões permanentes (Server Sent Events, WebSockets) isso significa que problemas
podem ocorrer no caso de requests concorrentes.
Sessions não são escaláveis
Sessions trabalhando no modo in-proc (habilitado por padrão) irão prejudicar a escalabilidade da aplicação, uma vez que
a memória utilizada pela session é de um servidor específico. Suponha que existam N servidores da mesma aplicação
que estejam sendo suportados por um load balancing, uma vez que a session foi criada no servidorX a aplicação só
funcionará se todos os requests forem redirecionados para o servidorX, existem meios de realizar isto, porém essa
abordagem desconfigura o conceito de escalabilidade.
Sessions degradam a performance da aplicação
Em muitas aplicações é possível notar o IIS batendo o topo de utilização de memória, muitas vezes a utilização da
memória não é causada pelos recursos do IIS e sim de alocação de dados via sessions. Desenvolvedores realizam uma
pesquisa no banco e guardam o resultado numa session para poder reaproveitar a pesquisa, porém quase sempre
esquecem de destruir aquela sessão. Essa facilidade que as sessions proveem acaba sendo uma armadilha para boa
performance da aplicação uma vez que a memória disponível para rodar a aplicação é dividida e consumida pelas
sessions.
Sessions não são necessárias? Como posso substituí-las? Quais recursos utilizar?
Com certeza as sessions não são necessárias e obviamente não devem ser utilizadas pelos motivos apresentados
acima. Porém a abordagem para substituir as sessions depende do cenário. Apresentarei algumas possibilidades.
Controle de usuários logados, armazenamento de informações de usuários.
A utilização de Cookies é uma excelente alternativa para persistência de usuários logados, a informação fica no
client-side e permite escalabilidade e ao mesmo tempo segurança. Grandes sites como Facebook utilizam Cookies
para persistência de usuários.
Caso queira armazenar informações de usuários no Cookie é possível porém existe uma limitação de tamanho
(4K), talvez seja interessante armazenar uma chave no Cookie onde através dela seja possível localizar mais
informações em outro recurso de armazenamento.
O ASP.NET Identity é uma ótima alternativa para esse cenário, ele trabalha com Cookies para persistência do
usuário e também com Claims para armazenamento de dados (nome, e-mail, permissões e etc…).
Controle de carrinho de compras.
Carrinho de compras requerem um tratamento especial, pois não importa se a compra foi concluída ou não é
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://www.w3.org/TR/2011/WD-eventsource-20110208/
http://www.w3.org/TR/2011/WD-websockets-20110929/
https://msdn.microsoft.com/en-us/library/ms178586(v=vs.140).aspx
http://pt.wikipedia.org/wiki/Cookie_HTTP
https://www.eduardopires.net.br/category/asp-net-identity/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
sempre importante obter informações sobre carrinhos abandonados para trabalhar na analise dessas informações.
Minha recomendação é armazenar no banco, em uma tabela destinada para esse tipo de controle, uma vez que o
usuário logado retorna ao site é possível oferecer que ele restaure o carrinho abandonado, entre outras
possibilidades.
É possível também controlar o carrinho de usuários não logados através do recurso Anonymous Identification
Module do ASP.NET onde é criado um Cookie com um ID único e pode ser recuperado através
do Request.AnonymousID.
Armazenamento de objetos complexos.
A solução para isto é cache. Existem diversas soluções para trabalhar com Cache (ASP.NET Data Cache, NCache,
Memcached, Redis Cache), um destaque especial para o Redis Cache que se demonstrou uma solução muito
eficiente, performática e fácil de implementar, inclusive existe recursos no Azure e AWS para utilização desta
ferramenta para cache distribuído e etc.
O recurso de Cache sempre esteve presente no ASP.NET, sua utilização requer um pouco mais de esforço de
implementação do que no uso das sessions, porém convenhamos, programar é um exercício intelectual, pratique
isto!
Outras soluções para considerar
Existem outras soluções a serem consideradas, algumas muito simples como Hidden Fields e QueryStrings, onde muitas
vezes são o suficiente para resolver o problema.
Outra ótima alternativa no ASP.NET MVC é utilizar ViewData, ViewBag e TempData
Existe uma espécie de armazenamento local (muito maior que um Cookie) chamado WebStorage onde é possível
trabalhar com sessionStorage e localStorage, é muito interessante conhecer esse recurso, recomendo a todos que
pesquisem sobre o assunto.
Para finalizar…
Elimine a possibilidade de utilizar sessions em sua aplicação, a Web está cada vez mais moderna, escalável eresponsiva e é importante tomar decisões que não nos façam andar na contra-mão da Web.
Eu me reuni com outros colegas para bater um papo sobre esse assunto, confira como foi o bate papo.
* Assine meu canal no Youtube 
Vamos continuar com a troca de conhecimentos, utilize o formulário abaixo para postar sua opinião, crítica e lógico seu
feedback (adoramos feedback ).
Referência
http://brockallen.com/2012/04/07/think-twice-about-using-session-state/
Publicado em ASP.NET, SESSIONS por EDUARDO PIRES. Marque LINK PERMANENTE.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
https://msdn.microsoft.com/en-us/library/fsykd036.aspx
https://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx
https://www.eduardopires.net.br/2013/06/asp-net-mvc-viewdata-viewbag-tempdata/
http://dev.w3.org/html5/webstorage/
http://brockallen.com/2012/04/07/think-twice-about-using-session-state/
https://www.eduardopires.net.br/#facebook
https://www.eduardopires.net.br/#twitter
https://www.eduardopires.net.br/#linkedin
https://www.eduardopires.net.br/#whatsapp
https://www.eduardopires.net.br/#google_gmail
https://www.eduardopires.net.br/#pinterest
https://www.eduardopires.net.br/category/asp-net/
https://www.eduardopires.net.br/category/sessions/
https://www.eduardopires.net.br/author/eduardopiresbrwp/
https://www.eduardopires.net.br/2015/04/pense-duas-vezes-antes-de-utilizar-sessions/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
20 IDEIAS SOBRE “PENSE DUAS VEZES ANTES DE UTILIZAR SESSIONS”
André Miranda em 2 de abril de 2015 às 10:52 disse:
Olá Eduardo!
Parabéns pelo post!
Vejo que vc sempre bate na tecla de não se utilizar Sessions e eu mesmo as utilizou em um cenário específico e
gostaria de debatermos sobre ele até mesmo para vc me dar uma luz sobre uma melhor alternativa, pode ser? 
Um cenário real na qual participei foi o seguinte:
– Tenho um cadastro de clientes
– 1 cliente pode ter N endereços
– 1 cliente pode ter N contatos
– 1 cliente pode ter N qualquer coisa…
Então, pensando já na tela em si, eu tinha várias abas e cada aba era uma função, então eu tinha a aba para
adicionar os endereços, tinha a aba para adicionar os contatos etc.
Tomando a adição de endereço, como exemplo, tudo bem? Então, tenho minha aba para adicionar N endereços
para aquele cliente. E, cada vez que eu adicionava um cliente, ele ia sendo mostrado num grid temporariamente
e onde essa lista de endereços era armazenada temporariamente? Em Session! E, isso era feito em todas as
abas (contatos, etc). E, nesta tela de cliente, eu tenho um botão “Salvar” geral que pegava todos os dados
principais do cliente e mais todas essas listas temporárias das Sessions e gravava no banco.
Neste tipo de cenário, onde eu tenho uma adição 1-N e que eu não posso já adicionar no BD direto, como não
utilizar Session? Eu acho que vc meio que deu a resposta ao falar sobre Cache, porém nunca utilizei. Seria a
melhor alternativa? A aplicação “sofre” menos se utilizarmos Cache ao invés da Session neste caso?
Abs!
E
Rodrigo
em 20 de abril de 2015 às 21:37 disse:
Não querendo responder pelo Eduardo..rsrss
Mas você pode utilizar um helper chamado BeginCollectionItem para fazer essa adição de inúmeros
campos e então sim, fazer o post
É o que eu utilizo, =) rs
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Também há a opção de utilizar knockoutjs porexemplo, também faz a mesma coisa, procure por crud
master details
Carlo Astoni
em 23 de fevereiro de 2017 às 09:40 disse:
Rapaz, esta é uma das coisas que gostaria de ver como se faz no MVC. Gravar tabelas master/detail
numa única transação, inclusive utilizando o Entity Framework. Você conseguiu fazer utilizando Cache?
Teria um exemplo?
Obrigado.
Fabiano Nalin em 2 de abril de 2015 às 13:14 disse:
Excelente post.
Abs
Legolas em 2 de abril de 2015 às 14:26 disse:
Como sempre um ótimo artigo Eduardo Pires, sei que esse assunto é algo que você sempre menciona nos seus
cursos e no AspNetCast.
Obrigado por compartilha conosco esse conhecimento.
André Luis Marmo em 2 de abril de 2015 às 16:03 disse:
Fala Eduardo! Muito bom o post e o vídeo também foi uma discussão bem bacana.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://fabianonalin.net.br/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Mas acho que o grande desafio que o desenvolvedor tem é saber “dosar” o que colocar no client e o que colocar
no servidor, e com a quantidade de opções que se tem hoje em dia as vezes se torna uma tarefa difícil.
Já vi discussões justamente sobre sobrecarregar o client com diversos scripts e processamentos, sendo um
problema principalmente para aplicações mobile.
Abraço
Adriano em 2 de abril de 2015 às 20:30 disse:
Nossa estavamos discultindo exatamente isso uns dias atrás, esse artigo irá me ajudar a exemplificar meu ponto
com mais detalhes. Aliás, o usu do Redis, está sendo sensacional. Parabéns e obrigado =)
Guilherme Gomes do Braz em 3 de abril de 2015 às 14:34 disse:
Muito bom o artigo. Vc tem exemplos usando as alternativas? Exemplos de códigos?
Charles em 9 de abril de 2015 às 17:24 disse:
Ótimo post Eduardo, parabéns.
Utilizo o WebStorage é muito bom realmente, bem interessante.
Valeu!!
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://www.rakuten.com.br/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Roberto Cesar Rodrigues em 18 de abril de 2015 às 23:30 disse:
Olá Eduardo.
Cara meus parabéns, eis o post que estava procurando já a algum tempo. Já tive muitos problemas relacionados
a reciclagem de sessões, principalmente quando se trata de ambientes compartilhado (ex: esses planos baratos
de hospedagens), era algo muito irritante, creio que grande parte disso seria o fato de utilizar o nhibernate nas
aplicações pois sabemos que o mesmo consome “um pouco” de memória ao cachear os mapeamentos. Devido a
todos esses problemas, resolvi não mais utilizar sessões em momento algum, e esse post veio a cair muito bem.
Obrigado cara.
Rodrigo em 20 de abril de 2015 às 21:41 disse:
Eduardo, ótimo post, muito bom mesmo.
Estou em uma aplicação multi tenant que precisavamos particinar o tenantId, eu escolhi utilizar o próprio cookie
do identity, rs
E quanto ao RedisSessionStateProvider ? Que utiliza session e redis? O que você acha? PS: Não tenho
conheicmento quanto ao RedisSessionStateProvider, li um pouco e me pareceu uma alternativa.
Abraço
João Neto em 20 de maio de 2015 às 20:48 disse:
Sou Arquiteto de Software e sempre dei foco para o não uso da session. Inclusive uma forma volátil de uso é a
serialização de objetos usando JSON e armazenando em um hiddenField. Em testes de performance se mostrou
extremamente rápido e simples de usar.
Ricardo em 21 de maio de 2015 às 19:10 disse:
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://deploygames.com.br/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Mto bom o post.
No meu caso utilizo sessions para guardar valores inseridos pelo usuário na página X que serão salvos no BD ao
clicar em um botão da página Y.
Teria alguma idéia pra esse cenário?
Obrigado
Adriana Carvalho em 25 de maio de 2015 às 13:47 disse:
Eu tenho uma aplicação hospedada na nuvem (Azure). Configurei a SessionState para o Cache do Azure. Como
consigo testar se uma aplicação com várias instâncias realmente não perde a Sessão do usuário logado ao existir
sobrecarga de um Servidor?
Obrigada
–Adriana
Paulo Diogo em 16 de junho de 2015 às 18:07 disse:
Esse ano conseguir fazer uma aplicaçãocom ZERO uso de Session ahahaha
Eny Gos em 1 de outubro de 2015 às 13:38 disse:
Olá.
Estou iniciando no desenvolvimento de um “mini erp online” em .net, queria uma dica de como estruturar o
projeto, por exemplo, é indicado que cada usuario tenha seu próprio banco de dados? Porém quando ele for
realizar login no sistema, como posso conectar no banco de dados dele que estará na nuvem?
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://paulodiogo.com/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Roberto Novakosky em 22 de julho de 2016 às 11:30 disse:
Penso que a opção com cookies não é viável, pois depende de estarem habilitados na máquina do usuário e são
uma brecha de segurança, dá para roubar os cookies dos usuários e pelo menos ‘presumir’ onde as pessoas
estão navegando, fazer um tipo de bisbilhotagem alheia, embora também seja possível roubar outros objetos
armazenados do browser. O meu problema é alcançar uma autenticação satisfatória de segurança. Não cheguei
ainda a uma conclusão sobre qual tecnologia seria a melhor, mas talzez os websockts sejam uma alternativa para
reconhecer a autenticação do usuário, estou estudando se é viável fazer um tipo de conexão SOAP através do
browser ao invés de usar somente REST. Ainda estou estudando uma melhor forma de autenticar com segurança
com menos programação possível, é uma boa discussão de ideias.
Roberto em 22 de julho de 2016 às 11:59 disse:
Olá pessoal, outra coisa que vocês poderiam compartilhar, seria como vocês fazem para autenticar usuários,
independente de plataforma, algo que funcione cross platform. O ASP.NET Identity pode ser muito bom para
autenticação, mas não tenho como usar já que o server precisa ser Microsoft e tenho server linux, logo uso
APACHE entre opções. Já pensei também em outras situações, em usar o MONO (http://www.mono-project.com)
ligado ao APACHE, já fiz alguns testes em C# com MONO para rodar no APACHE em linux, algumas coisas
funcionam e outras não, alguém aí já tem alguma experiência de manter algum site desta forma ?
Carlo Astoni em 23 de fevereiro de 2017 às 09:38 disse:
Bom dia, a melhor forma de controlar usuários logados no ASP .NET MVC então é a utilização de Cookies?
Existem casos em que o Cookie não está habilitado? Alguém teria um exemplo em MVC de controle de acesso?
Alexandre Gonçalves Xavier em 31 de maio de 2019 às 09:05 disse:
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
http://www.mono-project.com/
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf
Os comentários estão fechados.
Estou engatinhando em Dot Net. Estou me deparando com o problema de Cluster de Servidor Web, logo,
Session que sempre usei passou a ser um problema.
Sei que a discussão existe há um tempo e que este vídeo também.
Alguns detalhes, o tempo do vídeo impede que seja completamente visto, eu já usava cookie bem antes de 2000,
como falado no vídeo.
https://en.wikipedia.org/wiki/HTTP_cookie#History
Espero conseguir assistir mais dele.
Agradeço o esforço que faz em prol da troca de conhecimento.
Convert web pages and HTML files to PDF in your applications with the Pdfcrowd HTML to PDF API Printed with Pdfcrowd.com
https://en.wikipedia.org/wiki/HTTP_cookie#History
https://pdfcrowd.com/api/?ref=pdf
https://pdfcrowd.com/html-to-pdf/?ref=pdf

Outros materiais