一般来说,我们在java中都通过如下代码进行用户登录后的服务端注册,并且在用户下次请求时无需再登陆一遍,这就是Servlet的Session。使用了这种Session策略,那么Web容器比如tomcat就为当前用户生成一个SessionID,并且以这个SessionID为索引,存储这个用户相关的键值对,比如用户名,登陆时间一类的。存储在服务器的内存中。同时再response里向用户浏览器中设置一个cookie,这个cookie的名字为jsessionid,内容为服务器生成的随机数SessionID。在用户第二次请求时,将这个cookie发给服务器,服务器根据这个SessionID到内存中寻找相关数据,把用户名什么的提取出来,服务器就可以在本来无状态的HTTP连接中识别出这是哪个客户发出的请求,然后绘制相关页面。
        这中Session机制使用简单方便,被使用了很长时间。但是一旦做成集群,这种方式就不灵了。以NGINX默认的轮询方式为例,用户在A服务器上登陆成功,SessionID和用户名等相关信息写入了A服务器的内存中,该用户第二次请求时被NGINX分发到了B服务器,而B服务器没用该用户的SessionID和用户名等相关信息,于是要求用户再登陆一遍。用户第二次登陆之后发送第三次请求,被NGINX分配到了A或者C服务器,于是用户又必须登陆一遍,总之这个用户一直没法登陆成功。

基于以上现象,有几种存储session 的方法,如下:

1. 数据库存储session

2.使用 memcached,redis等存储session

3. 使用nginx 内置模块,ip_hash

4. 使用cookie的HASH来区分同一个用户的不同链接

前面我们已经知道了如果使用Servlet Session的话,Web容器会自动的在用户浏览器上建立名为jsessionid的cookie,并且值就是服务器端的SessionID。另一方面,新版的NGINX不光可以通过IP的hash来分发流量,也可以通过url的hash,cookie的hash,header的hash等等进行链接的固定分配。由于用户登陆成功以后名为jsessionid的cookie就有了一个短期固定的值,而且每个用户都不一样,那么我们就可以根据这个sessionid的hash值为它分配一个服务器。在当前sessionID起作用的时候那么分配的服务器也是同一个,并且不需要安装第三方的插件。

本次使用第4种方法,使用cookie 是用户分配的服务器是同一个。nginx 配置如下:

[root@www vhosts]# cat load.conf

upstream tomcat_server {    

hash        $cookie_jsessionid;   

# hash   $request_uri;    

server      172.16.31.16:8080;    

server      172.16.31.17:8080;

}

#error_page配置备份:    

upstream backup {    

server 11.11.11.14:80; }

error_page 404 500 502 503 504 =200 @fetch;     #注意:=200里的等号,左边有空格,右边没空格

server {  

     listen 80;  

     server_name www.load.com;  

     root /data/wwwroot/www.load.com;  

     index index.html index.htm index.php;

     access_log /usr/local/nginx/logs/www.load.com-access.log gufan;  

     error_log /usr/local/nginx/logs/www.load.com-error.log;

  location /stat {        

          proxy_pass            

         http://tomcat_server;        

         proxy_set_header      

         Host $http_host;        

         proxy_set_header       X-Real-IP $remote_addr;        

         proxy_set_header       X-Forwarded-For $proxy_add_x_forwarded_for;         

         proxy_intercept_errors on;        

         proxy_next_upstream off;  

   }

    location @fetch {     

         proxy_pass        http://backup;     

         proxy_set_header   Host             $host;     

        proxy_set_header   X-Real-IP        $remote_addr;     

       proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

}

nginx 在浏览器端保持cookie 一致的更多相关文章

  1. [javascript]在浏览器端应用cookie记住用户名

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 获取浏览器端的cookie方法

    代码如下: function getCookie(key){ var cookies=document.cookie; if(cookies.length>0){ var start=cooki ...

  3. nginx优化:使用expires在浏览器端缓存静态文件

    一,nginx中expires指令的作用 网站的图片等静态文件一旦发布,通常很少改动, 为了减小对服务器请求的压力,提高用户浏览速度, 我们可以设置nginx中的expires, 使用户访问一次后,将 ...

  4. 常见的浏览器端的存储技术:cookie

    工作原理: cookie是存在用户硬盘中,用户每次访问站点时,Web应用程序都可以读取Cookie包含的信息.当用户再次访问这个站点时,浏览器就会在本地硬盘上查找与该 URL 相关联的 Cookie. ...

  5. 使用nginx实现浏览器跨域请求

    跨域访问问题, 相信很多人都遇到过, 并且都用不同的办法去解决过. 方法有很多种, 不一一叙述了. 这里主要使用nginx反向代理来解决跨域问题. 啥是跨域? 假如你是百度开发人员, 在百度页面去请求 ...

  6. html5 浏览器端数据库

    为什么使用浏览器端数据库:随着浏览器的处理能力不断增强,越来越多的网站开始考虑,将大量数据储存在客户端,这样可以减少用户等待从服务器获取数据的时间. 一.localStorage  — 本地存储  可 ...

  7. FingerprintJS - 在浏览器端实现指纹识别

    FingerprintJS 是一个快速的浏览器指纹库,纯 JavaScript 实现,没有依赖关系.默认情况下,使用 Murmur Hash 算法返回一个32位整数.Hash 函数可以很容易地更换. ...

  8. 检测浏览器是否支持cookie方法

    cookie 摘自: http://www.cnblogs.com/fish-li/archive/2011/07/03/2096903.html Cookie是什么? Cookie 是一小段文本信息 ...

  9. ele.me在IOS浏览器端启动APP的技巧分析

    ele.me在IOS浏览器端启动APP的技巧分析 巧妙利用后台重定向,在schemes启动时提示用户打开,启动不了APP时能够及时跳转至下载页面. 避免报错页面的出现以及用户还没来的及选择就跳转到下载 ...

随机推荐

  1. docker入门——管理容器

    除了交互式的容器(interactive container),我们也可以创建长期运行的容器.守护式容器(daemonized container)没有交互式会话,非常适合运行应用程序和服务.大多数时 ...

  2. django迁移model到别的app中

    举例: 移动 users.AccessKey 到 authentication.AccessKey中 1. 移动models到新的app中 $ mv users/models/access_key.p ...

  3. [转]2年SQL Server DBA调优方面总结

      2年SQL Server DBA调优方面总结 当2年dba 我觉得,有些东西需要和大家分享探讨,先书单. 书单 1.<深入解析SQL Server 2008 系列> 这个就是mssql ...

  4. CentOS6.5下docker的安装及遇到的问题和简单使用(已实践)

    转载自 CentOS6下docker的安装和使用 Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.利用Linux的LXC.AUFS. Go语言.c ...

  5. Android Serialization序列化

    Android Serialization 目的: 为了方便測试传感器数据处理算法,Android程序的採集数据.序列化保存为文件.pc程序再通过反序列化读入对象,在PC上測试算法. Java 序列化 ...

  6. Scikit-learn的kmeans聚类

    1. 生成随机的二维数据: import numpy as np x1 = np.array([1, 2, 3, 1, 5, 6, 5, 5, 6, 7, 8, 9, 9]) x2 = np.arra ...

  7. activiti自己定义流程之整合(三):整合自己定义表单创建模型

    本来在创建了表单之后应该是表单列表和预览功能.可是我看了看整合的代码,和之前没实用angularjs的基本没有什么变化,一些极小的变动也仅仅是基于angularjs的语法,因此全然能够參考之前说些的表 ...

  8. 680. Valid Palindrome II【easy】

    680. Valid Palindrome II[easy] Given a non-empty string s, you may delete at most one character. Jud ...

  9. DataUml Design 教程6-DataUML Design 1.1版本正式发布(支持PD数据模型)

    从DataUML Design正式发布到现在有两个月了,由于最近比较忙,到现在才发布1.1版本.以后本人会一直坚持不断完善DataUML Design软件,希望广大程序猿们多多支持. 一.1.1版本新 ...

  10. linux下1号进程的前世(kthread_init)今生(init)

    参考: 1.  Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六) 2. linux挂载根文件系统过程 3. BusyBox init工作 ...