分布式服务集群下实现session共享解决方案

随着互联网的日益壮大,网站的pv和uv成线性或者指数倍的增加.单服务器单数据库早已经不能满足实际需求。目前大多数大型网站的服务器都采用了分布式服务集群的部署方式。

所谓集群,就是让一组计算机服务器协同工作,解决大并发,大数据量瓶颈问题。但是在服务集群中,session共享往往是一个比较头疼的问题。因为session是在服务器端保存的,如果用户跳转到其他服务器的话,session就会丢失,一般情况下,session不可跨服务器而存在。于是就有了分布式系统的session共享问题。

再说方案之前,老规矩,走一波概念:

session:

当新客户端发现一个HTTP请求时服务端会创建一个session.并分配一个sessionID作为服务端来客户端的识别,session对象会保存在服务端.此时session对象处天NEW STATE状态,如果调用 session.isNew()则返回true.

当服务器处理完后,会将sessionID同response 一起传回客户端,并将其存到cookie中;当客户端再发送请求的时候.会将sessionID连同request一起发送给服务端;服务端再根据传过来的sessionID将这次request与保存在服务端的session对象联系起来.此时的session对象已不是NEWSTATE状态.这样循环多次.直到超时或销毁.

注:当禁用cookie时也是不能使用session的;

cookie:

cookie是在客户端保存的方案.而session是在服务端保存的方案.如果cookie不设定时间的话就表视它的生命周期为浏览器会话的期间,只要关闭IE,cookie就消失了,这种cookie被称为会话cookie.其一般不保存在硬盘上.而是保存在内存中,如果设置了过期时间.那么浏览器会把cookie保存到硬盘中,再次打IE时会依然有效.直到它的有效期超时;

注:存储在硬盘中的cookie可以在不同IE间共享;

如何实现session共享呢?有以下几种方案,亲们可以根据自己的业务场景,访问情况等具体选择其中一个解决方案即可。

  1. 客户端cookie加密

这是我以前采用的方式,简单,高效。比较好的方法是自己采用cookie机制来实现一个session,在应用中使用此session实现。

问题:session中数据不能太多,最好只有个用户id。

  1. application server的session复制

可能大部分应用服务器都提供了session复制的功能来实现集群,tomcat,jboss,was都提供了这样的功能。

问题:性能随着服务器增加急剧下降,而且容易引起广播风暴;session数据需要序列化,影响性能。

  1. 使用数据库保存session 使用数据库来保存session,就算服务器宕机了也没事,session照样在。 问题:每次请求都进行数据库读写开销不小(使用内存数据库可以提高性能,宕机就会丢失数据。可供选择的内存数据库有BerkeleyDB,Mysql的内存表);
  2. 使用 filter 方法存储 这种方法比较广泛,因为它的服务器使用范围比较多,不仅限于 tomcat ,而且实现的原理比较简单容易控制。
  3. 使用 terracotta 服务器共享 这种方式配置有点复杂,大家到网上搜索一下吧
  4. 使用memcached来保存

这种方式跟数据库类似,不过因为是内存存取的,性能自然要比数据库好多了。

问题:程序需要定制,增加了工作量;存入memcached中的数据都需要序列化,效率较低;memcached服务器一死,所有session全丢。

  1. 使用redis保存session 配置简单,不易丢失,性能较高

那么今天,我们以tomcat+nginx+redis架构模式讲解下,如实使用redis保存session,从而实现集群环境下的session共享问题。

环境准备:

1:redis配置(192.168.1.31:16300)

2:tomcat配置

tomcat-8081(192.168.1.30:8081)

tomcat-8082(192.168.1.30:8082)

3:nginx配置(192.168.1.32)

不会配置负载的可以参考 (nginx+tomcat负载均衡

首先,是配置tomcat,使其将session保存到redis上。有两种方法,也是在server.xml或context.xml中配置,不同的是memcached只需要添加一个manager标签,而redis需要增加的内容如下:(注意:valve标签一定要在manager前面。)

<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />

<Manager className="com.radiadesign.catalina.session.RedisSessionManager"

host="192.168.159.31"

port="16300"

database="0"

maxInactiveInterval="60"/>

其次,配置nginx,用于测试session保持共享。

upstream redis.test.com {

server 192.168.1.30:8081;

server 192.168.1.30:8082;

}

log_format www_xy_com '$remote_addr - $remote_user [$time_local] $request '

'"$status" $body_bytes_sent "$http_referer"'

'"$http_user_agent" "$http_x_forwarded_for"';

server{

listen 80;

server_name redis.test.com;

location / {

proxy_pass http://redis.test.com;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

access_log /data/base_files/logs/redis.xxy.log www_xy_com;

}

最后,将你的应用放到两个tomcat中,并依次启动redis、tomcat、nginx。访问你的nginx,可以发现两个tomcat中的session可以保持共享了。

原文发布于微信公众号 - 码神联盟(lkchatspace)

原文发表时间:2017-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏mini188

MongoDB安装与使用体验

1、获取并安装 具体的安装包可以到官方网站下载:http://www.mongodb.org/downloads 我看着教程就下载了linux版本吧,也不是很...

2476
来自专栏分享达人秀

你升级Android Studio 3.0正式版了吗?来看看这些坑!

盼望已久的Android Studio 3.0正式版终于在25日悄悄上线了,有很多地方都有较大升级,新功能也不少了,赶紧和我一起来体验吧。 如果对...

3246
来自专栏程序员宝库

Linux 下各文件夹的结构说明及用途介绍

linux下各文件夹的结构说明及用途介绍: /bin:二进制可执行命令。 /dev:设备特殊文件。 /etc:系统管理和配置文件。 /etc/rc.d:启动的配...

45912
来自专栏『不羁阁』 | 行走少年郎专栏

Hexo 博客部署到腾讯云教程

7256
来自专栏幸山的专栏

精通yum配置以及问题解决

yum基于RPM包管理,能够从指定的服务器自动下载RPM包并且安装,可以自动处理依赖性关系,提供了查找、安装、删除某一个、一组甚至全部软件包的命令,而且命令简洁...

1K0
来自专栏晨星先生的自留地

linux软件包管理工具

2803
来自专栏破晓之歌

15款Django开发常用软件包 原

1. Python social auth 一款社交账号认证/注册机制,支持Django、Flask、Webpy等在内的多个开发框架,提供了约50多个服...

742
来自专栏王小雷

Firefox离线安装扩展教程

Firefox离线安装扩展教程 解决问题博文:解决stackoverflow打开慢不能注册登录 应网友求助在上传了需要的扩展资源后,顺便写个离线安装方法,其实...

2436
来自专栏difcareer的技术笔记

Android boot.img的解包/修改/重打包

最近研究对了Android的boot.img的操作,将一些繁琐的东西整理了一下,发到了github:https://github.com/difcareer/B...

4245
来自专栏java思维导图

架构师详解:Nginx 架构

原文链接:https://my.oschina.net/u/3770281/blog/1802493

1572

扫码关注云+社区

领取腾讯云代金券