一,集群和分布式的区别

在进入今天的正题之前,对服务器集群和分布式服务器这两个概念进行简要说明。

服务器集群:服务器集群就是指将很多服务器集中起来一起进行同一种服务,在客户端看来就像是只有一个服务器。集群可以利用多个计算机进行并行计算,从而获得很高的计算速度,也可以用多个计算机做备份,,从而使得任何一个机器坏了整个系统还是能正常运行。

根据上述的信息简单来说:服务器集中对外提供同一种服务,解决了大量用户访问同一服务存在的高并发问题;多台服务器备份,解决了服务器的高可用问题;不至于说一台服务器宕机, 这个服务就瘫痪了!

上文中提到的多台服务器备份,备份的不就是会话信息session吗?也就是今天我们要说的服务器集群环境下session的共享问题。

分布式服务器:随着B/S架构系统的发展,开发一个互联网项目的业务需求也越来越多。如果把这些业务模块都放在一台服务器上来提供服务,这肯定是不现实的,毕竟一台服务器的性能各方面都是有限的。企业普遍会把这些业务模块分别放到不同的服务上来提供服务,来满足大量用户访问不同服务时存在的高并发问题

简单来说服务器集群和分布式服务器的区别:
分布式:项目的不同业务模块(例如:用户模块,购物车模块,支付模块),部署在不同的服务器上
集群:同一个业务(例如:用户模块),部署在多个服务器上

二,会话技术Cookie,Session

估计你们会在想:这个标题党,真正的问题不解决,怎么又扯出个会话技术。难道这就是传说中的程序员修复Bug,真正的问题没有解决,又冒出了另一个问题。

哈哈,不扯皮了。这里主要是为了说明Cookie,Session的联系和区别。

1.什么是会话?

用户开一个浏览器访问页面,访问了很多网站,直到用户关闭浏览器,这整个过程我们称作一次会话。

2.会话过程中的信息存储问题

HTTP是无状态协议:每次都是单独连接,不能保存用户的信息,通俗来说,就是它区分不了到底是哪一个用户在访问网络资源。而Cookie和Session就很好地解决了这个问题,

Cookie:
Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问web资源时,浏览器就会带着用户的信息过去。这样,web资源处理的就是用户各自的数据了。

注意:Cookie是存放在浏览器端,分为会话Cookie和持久性Cookie,默认情况下,Cookie是会话级别的,关闭浏览器就会消失。可以通过设置Cookie的有效时间来实现持久性Cookie存储

Session:
虽然Cookie可以存放用户信息,但cookie存储在浏览器端是以明文方式存放,因此安全性较低。而Session是存放在服务器端的,我们把用户的信息保存在服务器端Session中相对安全,然后把服务器创建的Session对象的Id存在中Cookie中,这样用户在访问服务器资源时,Cookie就会带着SessionId过来,服务器端就会根据这个SessionId来找到对应的Session,从而找到存储在Session中的用户信息。

注意:在访问同一个服务器下的Web资源时,Session只会被创建一次,Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session

三,服务器集群环境下session的共享问题

1.反向代理服务器Nginx

Nginx多在高并发情况下需要使用。其原理就是将用户请求分摊到多个服务器执行,减轻每台服务器的压力,多台服务器(集群)共同完成工作任务,从而提高了数据的吞吐量。

正向代理:用户想在某个指定的服务器上获取资源
反向代理:用户只要访问Nginx就可以获取到资源,而不用去关心具体访问的是哪个服务器

Nginx的使用

Nginx的安装过程跳过,主要演示Nginx的一些配置。

打开Nginx的nginx.conf文件,配置如下

#下面这个配置需要自己添加upstream xiaogui_server{server localhost:8080;server 127.0.0.1:8888;}#修改配置文件,添加  proxy_pass http://xiaogui_server;location / {root   html;proxy_pass http://xiaogui_server;index  index.html index.htm;}

在服务器tomcat1下的测试页面:

<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>服务器1111111111111</title>
<style type="text/css">
</style>
</head>
<body><h1>服务器1的页面</h1>服务器1创建Session的Id:<%=session.getId() %><%session.setAttribute("username", "xiaogui");%>
</body>
</html>

服务器tomcat2下的测试页面

<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>服务器2222222222222</title>
<style type="text/css">
</style>
</head>
<body><h1>服务器2的页面</h1>服务器2创建Session的Id:<%=session.getId() %><br/>服务器1创建的Session中的存入的username:<%session.getAttribute("username");%>
</body>
</html>

启动tomcat1,tomcat2,nginx测试

当访问tomcat1页面时,

刷新页面,访问tomcat2页面:

****得出结论:使用Nginx访问服务器,由于访问的网址不会发生,所以Cookie中的信息在集群的服务器之间是共享的

根据得出结论,当用户第一次访问服务时,服务器创建Session,这时服务器把Session存放到Redis当中,交由Redis管理。以SessionID作为key,Session对象作为值。当用户再次访问时,不管访问的哪一个服务器,Cookie都会带着这个SessionID过来,根据这个SessionID就可以在Redis中找到对应的Session,这样就实现了Session共享。也就是下面我们要说到的这个方案。

使用nginx+tomcat+redis完成session共享(推荐方式)

redis安装:https://blog.csdn.net/qq_41258204/article/details/83715582

下载tomcat-redis-session-manager相应的jar包,主要有三个:

commons-pool-1.6.jar :主要是来用管理redis
jedis-2.1.0.jar :用来操作redis的客户端
tomcat-redis-session-manager:主要使用redis来管理服务器创建的Session

这三个jar包,网上不太容易找到,好多下载都要收费。而且下载之后还要考虑三个jar之间的兼容性。我把测试成功的这三个jar包放在文章末尾的示例项目中!

把这三个jar复制到tomcat的lib目录下,

修改tomcat/conf目录下的context.xml,在这个文件中,加入下面配置

 <Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />
<Manager className="com.radiadesign.catalina.session.RedisSessionManager"host="localhost"port="6379"database="0"maxInactiveInterval="60" />

注意:所有集群的tomcat都要进行上述的配置。

启动Redis,tomcat1,tomcat2,Nginx服务,进行测试

用户再一次刷新页面,

我们还可以通过redis的客户端查看:

由于使用redis的客户端查看,对数据进行了转码,所以会显示成上面的结果。

tomcat的广播机制,完成session共享(不推荐)

修改tomcat/conf下的server.xml文件

把这个注释的部分去掉

 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

在项目的web.xml中配置

<distributable/>

在集群的tomcat上配置好以后,重启tomcat即可。

根据用户的IP进行hash计算,让用户访问指定的tomcat

修改Nginx/conf目录下的nginx.conf文件

 #下面这个配置需要自己添加upstream xiaogui_server{server localhost:8080;server 127.0.0.1:8888;ip_hash;}

在上面这个配置中加入ip_hash;即可。

缺点:1.由于局域网对外的IP都是一样的,如果该局域网中的用户都对服务进行访问,根据这个配置会造成局域网内所有的用户都会访问该服务器,这时服务器的访问压力会很大。2.当这个服务器宕机之后,可能被分配到这个服务器上的用户就没有办法进行访问了。

Nginx第三方模块upstream_hash解决session共享

为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享:

假如前端是squid,他会将ip加入x_forwarded_for这个http_header里,用upstream_hash可以用这个头做因子,将请求定向到指定的后端:

hash $http_x_forwarded_for;

在nginx新版本中可支持读取cookie值,所以也可以改成:

hash $cookie_jsessionid;

最后这种没有做过测试,有兴趣的话,自己可以测试一下。

分享示例项目在码云上的地址:https://gitee.com/xiaoguixiaogege/ClusterShareSession

服务器集群环境下session的共享问题相关推荐

  1. 【基于唯品会MP平台】集群环境下session共享技术方案及分布式单点登录

    背景 传统的B/S架构的系统中,一般为单点部署,并不存在集群,所以也不存在session丢失的问题.那么,由于单点部署一旦宕机,无法保证系统可用性,那我们就想到把它扩展为多台服务器部署,这样既保证了系 ...

  2. 分布式集群环境下,如何实现session共享三(环境搭建)

    这是分布式集群环境下,如何实现session共享系列的第三篇.在上一篇:分布式集群环境下,如何实现session共享二(项目开发)中,准备好了一个通过原生态的servlet操作session的案例.本 ...

  3. weblogic 12C集群环境下的session复制

    做过weblogic集群环境的人应该都清楚,要想实现session同步,必须满足两个条件:第一,在weblogic.xml里面增加session同步相关的代码:第二,所有放入session的类都要序列 ...

  4. 集群环境下,你不得不注意的ASP.NET Core Data Protection 机制

    引言 最近线上环境遇到一个问题,就是ASP.NET Core Web应用在单个容器使用正常,扩展多个容器无法访问的问题.查看容器日志,发现以下异常: System.Security.Cryptogra ...

  5. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  6. 在非容器(集群)环境下运行dapr

    作者:李俱顺 原文:https://www.4async.com/2021/03/2021-03-11-running-dapr-without-container/ 前一段时间一直关注的dapr正式 ...

  7. Hadoop集群环境下网络架构的设计与优化

    2019独角兽企业重金招聘Python工程师标准>>> 大数据时代,研究大数据的IT 厂商把研究重心放在优化大数据系统软件架构.优化业务逻辑.优化数据分析算法.优化节点性能等方向,而 ...

  8. MEMCACHED在集群环境下对并发更新是否保持数据一致

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 今天在和 ...

  9. Java技术分享:集群环境下的定时任务

    定时任务的实现方式有多种,例如JDK自带的Timer+TimerTask方式,Spring 3.0以后的调度任务(Scheduled Task),Quartz框架等. Timer+TimerTask是 ...

最新文章

  1. Mysql数据库 sql 语句调优
  2. android生命周期_Android开发 View的生命周期结合代码详解
  3. polycom安卓手机客户端_安卓 emoji 表情:全变了
  4. 计算机视觉中常见图像扰动方法的Pytorch实现
  5. 关于如何在Listener中注入service和ServletContextListener源码分析
  6. 解决IDEA创建多模块项目找不到创建class类的问题
  7. php数组实例,PHP数组实例总结及说明
  8. Liunx/Unix scp命令详解(转)
  9. axure通用元件库 Pc、Web端原型图组件库高保真UI rp源文件
  10. 利用ExcelJS读取Excel文件
  11. vs2010格式化html,VS中的快捷键快速格式化代码,使好看,整齐
  12. 常识:如何从大陆拨打国际长途电话到境外的方法
  13. 吉盟珠宝:300家门店异地沟通 效率居然远超“面对面”
  14. python读不出图片文件
  15. 微信小程序项目开发---第一章 制作首页
  16. mtk无线网卡 linux,模块编译问题 给MTK芯片的wifi网卡编译linux驱动 系统是mint
  17. 3.28~~3.29
  18. 【零基础】极星量化入门十一:远程遥控的简单办法
  19. oracle分页改写为mysql_mysql和oracle分页
  20. 视通助力中国航天某院多媒体会议室建设

热门文章

  1. 【学习方法】如何才能高效学习
  2. 使用xcode上传ipa到app store
  3. 第3章 栈和队列 练习题
  4. Wu反走样算法介绍(简单易懂) -Xiaolin Wu’s Algorithm
  5. 不做教书匠,要做研究型教师
  6. 【SAP】进项税的配置与传输
  7. Android开源项目以及开源库集合(持续更新中)
  8. 显示控件——图标类之图标旋转
  9. 【新知实验室】腾讯云TRTC服务体验
  10. oldwain随便写