datastore_使用Spring Session和JDBC DataStore进行会话管理

datastore

在Web应用程序中,用户会话管理对于管理用户状态至关重要。 在本文中,我们将学习在集群环境中管理用户会话所采用的方法,以及如何使用Spring Session以更简单和可扩展的方式实现该方法。

通常在生产环境中,我们将有多个服务器节点,并在它们前面有一个负载平衡器,并且所有客户端流量都将通过负载平衡器到达其中一个服务器节点。 因此,我们需要某种机制来使用户会话数据可用于集群环境中的每个客户端。
传统上,我们一直使用以下技术来管理会话:

  1. 单节点服务器
  2. 具有负载均衡器和粘性会话的多节点服务器
  3. 具有负载均衡器和会话复制的多节点服务器
  4. 持久性数据存储中具有负载均衡器和会话数据的多节点服务器

让我们简要地看一下这些方法。

1.单节点服务器

如果您的应用程序不是对您的业务至关重要的服务,那么并发用户不会太多,并且可以接受一些停机时间,那么我们可以进行单节点服务器部署,如下所示:


在此模型中,对于每个浏览器客户端,将在服务器上创建会话对象(对于Java,则为HttpSession ),并且SESSION_ID将被设置为浏览器上的cookie,以标识会话对象。 但是对于大多数应用程序来说,这种单服务器节点部署是不可接受的,因为如果服务器关闭,服务将完全关闭。

2.具有粘性会话的多节点服务器

为了使我们的应用程序高度可用并满足更多用户,我们可以在负载均衡器后面有多个服务器节点。 在“粘性会话”方法中,我们将负载均衡器配置为将所有请求从同一客户端路由到同一节点。

在此模型中,将在服务器节点中的任何一个上创建用户会话,并且来自该客户端的所有其他请求将被发送到同一节点。 但是这种方法的问题是,如果服务器节点发生故障,那么该服务器上的所有用户会话都将消失。

3.具有会话复制的多节点服务器

在此模型中,用户会话数据将在所有服务器节点上复制,以便任何请求都可以路由到任何服务器节点。 即使一个节点发生故障,客户端请求也可以由另一节点服务。

但是会话复制需要更好的硬件支持,并涉及某些服务器特定的配置。

4.具有持久数据存储区中的会话数据的多节点服务器

在此模型中,用户会话数据将不保存在服务器的内存中,而是将其持久保存到数据存储中并将其与SESSION_ID关联。

此解决方案将独立于服务器,但是每当用户向其会话中添加一些信息时,我们可能都需要编写自定义代码以将会话数据透明地存储在Persistent数据存储区中。

这是Spring Session出现的地方。

Spring会议

Spring Session是方法4的一种实现,它是将会话数据存储在持久数据存储区中。 Spring Session支持RDBMS,Redis,HazelCast,MongoDB等多个数据存储,以透明地保存使用会话数据。 像往常一样,将Spring Session与Spring Boot一起使用就像添加依赖项和配置少量属性一样简单。
让我们看看如何在Spring Boot应用程序中将Spring Session与JDBC后端存储一起使用。

https://github.com/sivaprasadreddy/spring-session-samples

步骤1:创建Spring Boot应用程序

使用具有WebThymeleafJPAH2Session starters的最新版本(撰写时为2.0.0.RC1 )创建SpringBoot应用程序。
默认情况下,Session入门程序将添加org.springframework.session:spring-session-core依赖项 ,让我们在使用JDBC后端时将其更改为spring-session- jdbc

<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-jdbc</artifactId>
</dependency>

步骤2:配置Spring Session属性

我们可以在application.properties使用spring.session.store类型的属性配置Spring会议后端数据存储的类型。

spring.session.store-type=jdbc

当我们使用H2内存数据库时,Spring Session将创建以下表,这些表用于通过脚本spring-session- jdbc -2.0.1.RELEASE.jar!/ org / springframework / session / jdbc / schema自动存储会话数据。 -h2.sql

CREATE TABLE SPRING_SESSION (PRIMARY_ID CHAR(36) NOT NULL,SESSION_ID CHAR(36) NOT NULL,CREATION_TIME BIGINT NOT NULL,LAST_ACCESS_TIME BIGINT NOT NULL,MAX_INACTIVE_INTERVAL INT NOT NULL,EXPIRY_TIME BIGINT NOT NULL,PRINCIPAL_NAME VARCHAR(100),CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);CREATE TABLE SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID CHAR(36) NOT NULL,ATTRIBUTE_NAME VARCHAR(200) NOT NULL,ATTRIBUTE_BYTES LONGVARBINARY NOT NULL,CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);CREATE INDEX SPRING_SESSION_ATTRIBUTES_IX1 ON SPRING_SESSION_ATTRIBUTES (SESSION_PRIMARY_ID);

但是,如果我们要使用其他RDBMS(例如MySQL),则可以进行如下配置:

添加MySQL Maven依赖项。

<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>

配置MySQL的数据源属性:

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=admin

使用spring.session.jdbc.initialize-schema属性启用Spring Session表创建。

spring.session.jdbc.initialize-schema=always

有了这个属性,Spring Session将尝试使用脚本“ classpath:org / springframework / session / jdbc / schema-@@ platform @@。sql”创建表,因此在本例中,它将使用schema-mysql.sql

步骤3:将资料新增至HttpSession

现在,在src / main / resources / templates / index.html中创建一个简单的表单。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Spring Session + JDBC Demo</title>
</head>
<body><div><form th:action="@{/messages}" method="post"><textarea name="msg" cols="40" rows="4"></textarea><input type="submit" value="Save"/>
</form></div><div><h2>Messages</h2><ul th:each="m : ${messages}"><li th:text="${m}">msg</li></ul></div></body>
</html>

让我们实现一个Controller,以将消息添加到HttpSession并显示它们。

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;@Controller
public class MessagesController 
{@GetMapping("/")public String index(Model model, HttpSession session) {List<String> msgs = (List<String>) session.getAttribute("MY_MESSAGES");if(msgs == null) {msgs = new ArrayList<>();}model.addAttribute("messages", msgs);return "index";}@PostMapping("/messages")public String saveMessage(@RequestParam("msg") String msg, HttpServletRequest request) {List<String> msgs = (List<String>) request.getSession().getAttribute("MY_MESSAGES");if(msgs == null) {msgs = new ArrayList<>();request.getSession().setAttribute("MY_MESSAGES", msgs);}msgs.add(msg);return "redirect:/";}
}

现在,您可以启动应用程序并将一些消息添加到HttpSession中,并且可以看到SPRING_SESSIONSPRING_SESSION_ATTRIBUTES表中的行。 默认情况下,Spring Session将我们尝试添加到HttpSession的对象转换为ByteArray并将其存储在表中。

Spring Security的Spring会议

由于SpringBoot的自动配置, Spring SessionSpring Security无缝集成。
让我们将Spring Security添加到我们的应用程序中。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>

application.properties中添加默认用户凭据,如下所示:

spring.security.user.name=admin
spring.security.user.password=secret

现在,如果您尝试访问http:// localhost:8080 /,将被重定向到自动生成的登录页面。
登录并查看SPRING_SESSION表中的数据后,您可以看到登录用户名存储在PRINCIPAL_NAME列中。

Spring Session如何工作?

Spring Session提供了HttpServletRequestHttpSession的实现,分别是SessionRepositoryRequestWrapperHttpSessionWrapper 。 Spring Session提供SessionRepositoryFilter来拦截所有请求,并将HttpServletRequest包装在SessionRepositoryRequestWrapper中

SessionRepositoryRequestWrapper.getSession(boolean)中,它被重写以返回HttpSessionWrapper对象,而不是默认的HttpSession服务器实现。 HttpSessionWrapper使用SessionRepository将会话信息保存在数据存储中。

SessionRepository接口具有多种管理会话的方法。

public interface SessionRepository<S extends Session> 
{S createSession();void save(S session);S findById(String id);void deleteById(String id);
}

这个SessionRepository接口由各种类根据我们使用的后端类型实现。 在我们的例子中,我们使用的是spring-session-jdbc提供的JdbcOperationsSessionRepository

结论

正如您可能已经观察到的,由于Spring Boot的自动配置,我们可以通过使用Spring Session进行非常少的配置来有效地管理用户会话。 如果由于某种原因我们想将后端从JDBC更改为Redis或Hazelcast等,那只是简单的配置更改,因为我们不直接依赖于任何Spring Session类。

您可以在https://github.com/sivaprasadreddy/spring-session-samples中找到本文的源代码。

翻译自: https://www.javacodegeeks.com/2018/02/session-management-using-spring-session-jdbc-datastore.html

datastore

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334055.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

做一个公众号大概要多少钱_公众号流量主一个月可以赚多少钱?

我是小郁儿&#xff0c;点击上方“关注”&#xff0c;每天为你分享自媒体运营与个人精进干货。细心的读者会发现&#xff0c;阅读我文章的时候&#xff0c;最下面不再出现广告卡片了&#xff0c;因为我前几天已经把流量主功能关掉。起初是因为我在看自己发的视频时&#xff0c;…

从Speedment 3.0.17或更高版本的事务轻松返回值

交易次数 在我以前的文章中&#xff0c;我写了关于如何使用Speedment轻松使用事务的方法&#xff0c;其中我们原子地更新了两个银行帐户。 众所周知&#xff0c;事务是一种将多个数据库操作组合到一个原子执行的单个操作中的方法。 但是事务不仅与更新数据库有关&#xff0c;而…

分布式锁的三种实现方式_分布式锁的多种实现方式

目前几乎很多大型网站及应用都是分布式部署的&#xff0c;分布式场景中的数据一致性问题一直是一个比较重要的话题。分布式的CAP理论告诉我们“任何一个分布式系统都无法同时满足一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区…

apache ignite_使用Apache Ignite优化Spark作业性能(第1部分)

apache ignite来看看他们是如何工作的&#xff01; 本文的某些部分摘自我的书《 Apache Ignite的高性能内存计算》 。 如果您对这篇文章感兴趣&#xff0c;请查看本书的其余部分&#xff0c;以获取更多有用的信息。 Apache Ignite提供了多种方法来提高Spark作业的性能&#xf…

微软家庭服务器,微软公布Windows Server 2012版本方案,不再提供家庭服务器版

微软官方网站今日公布Windows Server 2012将有四个版本&#xff0c;分别为Foundation、Essentials、Standard以及Datacenter。其中Foundation只供给原始设备制造商(OEM)&#xff1b;Essentials适合中小企业使用&#xff0c;最大用户数为25个&#xff1b;Standard与Datacenter版…

eclipse创建神经网络_使用Eclipse Deeplearning4j构建简单的神经网络

eclipse创建神经网络神经网络导论 深度学习包含深度神经网络和深度强化学习&#xff0c;它们是机器学习的子集&#xff0c;而机器学习本身就是人工智能的子集。 广义地说&#xff0c;深度神经网络执行机器感知&#xff0c;该机器感知从原始数据中提取重要特征&#xff0c;并对每…

angluar cdk_零分钟即可在容器开发套件(CDK)上实现云运营

angluar cdk尽管这很有趣&#xff0c;但是它实际上并不可行&#xff0c;并且很快就遇到了使用限制。前一段时间&#xff0c; 我逐步完成了在容器中安装称为CloudForms的云管理解决方案。 真正的解决方案是将这个示例放入Red Hat Demo Central集合中&#xff0c;并将其放在基于…

网络研讨室_免费网络研讨会:Java应用程序中的吞咽异常

网络研讨室1月30日参加我们的网络研讨会&#xff0c;以发现Java应用程序中的“隐藏”异常。 如果一棵树落在森林中&#xff0c;但是没有写到原木上&#xff0c;它会发出声音吗&#xff1f; 答案是肯定的。 这些类型的错误可能会对用户体验造成严重影响&#xff0c;而没有根本原…

java8默认内存收集器_使用正确的垃圾收集器将Java内存使用量降至最低

java8默认内存收集器大小对于软件至关重要。 很明显&#xff0c;与大的整体方法相比&#xff0c;在微服务体系结构中使用小片段具有更多优势。 最新的Java版本的Jigsaw有助于分解旧应用程序或从头开始构建新的云原生应用程序。 这种方法减少了磁盘空间&#xff0c;构建时间和启…

oc 协议 回调 静态成员_每日一问:c++类的成员函数,能作为线程的参数吗?

问&#xff1a;类的成员函数可以传入线程参数吗&#xff1f;回答&#xff1a;如果c语言的全局函数&#xff0c;可以。如果是类的静态成员函数&#xff0c;可以如果是类的普通成员函数&#xff0c;不可以为什么&#xff1f;《深入探索C对象模型》中提到成员函数时&#xff0c;当…

flink读取不到文件_日处理数据量超10亿:友信金服基于Flink构建实时用户画像系统的实践...

简介&#xff1a; 友信金服公司推行全域的数据体系战略&#xff0c;通过打通和整合集团各个业务线数据&#xff0c;利用大数据、人工智能等技术构建统一的数据资产&#xff0c;如 ID-Mapping、用户标签等。友信金服用户画像项目正是以此为背景成立&#xff0c;旨在实现“数据驱…

apache pulsar_Apache Pulsar:分布式Pub-Sub消息系统

apache pulsarApache Pulsar是一个开源的分布式pub-sub消息传递系统&#xff0c;最初是由Yahoo创建的&#xff0c;并且是Apache Software Foundation的一部分 。 Pulsar是用于服务器到服务器消息传递的多租户高性能解决方案。 脉冲星的主要功能包括[4]&#xff1a; 对Pulsar…

python deque索引超出范围_Python基础语法

学习Python的四个要素有数据&#xff0c;函数&#xff0c;条件循环和模块一、数据数据是Python编程过程中的原材料&#xff0c;通过导入数据&#xff0c;对数据进行操作&#xff0c;实现预先设想的功能。数据共有5种类型&#xff0c;分别是字符串、数字、容器、布尔值和空值。字…

Path环境变量的理解以及设置MinGW环境变量

配置path环境变量 在使用MinGW的时候&#xff0c;不小心把path变量的东西全部删掉了&#xff0c;结果只能自己重新设置path变量&#xff0c;首先要知道如何设置path变量。 Path路径&#xff1a;用来指定可执行文件的搜索路径&#xff0c;也就是后缀名为.exe文件&#xff0c;方…

python爬取网站的图片

python爬取网站的图片 本次爬取图片所需要用到的库&#xff1a;Requests库&#xff0c;BeautifulSoup库&#xff0c;正则表达式&#xff0c;os库。 思路&#xff1a;先爬一张图片&#xff0c;再爬一个网站的图片 先爬一张图片&#xff1a; 首先要得到这张图片的地址&#x…

用户登陆_华为路由器AAA用户密码登陆你了解吗?

AAA Authentication&#xff08;认证&#xff09;、Authorization&#xff08;授权&#xff09;、Accounting&#xff08;&#xff09;它提供了认证、授权、计费三种安全功能,可以验证用户帐户是否合法&#xff0c;授权用户可以访问的服务&#xff0c;并记录用户使用网络资源的…

word域变成正常文本_【Word小技巧】不学会后悔哦~

工作中使用Word早已成了习惯&#xff0c;因此&#xff0c;今天小编将为大家分享几个实用的的Word小技巧。重叠字快速录入文字录入是word最基本操作&#xff0c;过程中我们难免要输入重叠字&#xff0c;例如&#xff1a;热热闹闹&#xff0c;卿卿我我等……你知道如何快速录入吗…

sql server 2008 年累计数_Windows Server 2008 和 SQL Server 2008将终止支持 迁移至Azure 微软提供3年免费技术支持...

点击上方蓝色字关注我们~迁移至 Azure 并利用免费扩展安全更新。了解有关支持终止建议的更多信息&#xff0c;请使用浏览器访问&#xff1a;https://www.microsoft.com/zh-cn/sql-server/sql-server-2008.对您意味着什么1 2017年基于风险的安全报告; 思科 2017 年度网络安全报告…

旧版Requests库

requests库基本使用Requests解析库方法response对象response对象的属性**r.encoding**属性与**r.apparent_encoding**属性的区别requests库的异常举例Requests解析库 方法 最常用的两个方法: request.get() request.post() 作用&#xff1a;都是从服务器获取网页信息 区别&…

夸克浏览器怎么安装脚本_iOS 第一浏览器发布安卓版,除了真香我还能说什么...

如果不算 Safari 的话&#xff0c;iOS 平台公认最好的浏览器是 Alook。无推送无新闻无广告、日常售价 12 元、工具类排行第三、7.8 万个评分足以证明其优秀。以至于很多双持或对 Alook 有所了解的用户都希望 Alook 能推出安卓端。现在安卓端真的来了。(安卓端免费)假如这个时候…