Solve distributed session cross-domain sharing issues using spring session and Redis

Source: Internet
Author: User
Tags session id redis cluster redis server

Preface

For the distributed use of NGINX+TOMCAT to achieve load balancing, the most commonly used equalization algorithm has ip_hash, rotation, according to weight, random and so on. Regardless of which load-balancing algorithm, because nginx to different requests distributed to a certain tomcat,tomcat at the time of the operation is different containers, so there will be the session is out of sync or missing problems.

at the end of the article, I shared a portion of my personal collection that I was interested in . The Architect's advanced content
实际上实现Session共享的方案很多,其中一种常用的就是使用Tomcat、Jetty等服务器提供的Session共享功能,将Session的内容统一存储在一个数据库(如MySQL)或缓存(如Redis)中。 如何使用 tomcat-redis-session-manager 开源项目解决分布式session跨域的问题,他的主要思想是利用Servlet容器提供的插件功能,自定义HttpSession的创建和管理策略,并通过配置的方式替换掉默认的策略。tomcat-redis-session-manager重写了Tomcat的org.apache.catalina.session.ManagerBase里边的具体写的操作, 将tomcat的session存储位置指向了Redis:

Https://img-blog.csdn.net/20170226114651267?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast

Redissessionmanager inherited Org.apache.catalina.session.ManagerBase and re-wrote the Add, Findsession, Createemptysession, remove and other methods, and to the session of the Add and delete operations to the Redis data storage is pointed to the operation.

Interested to refer to a session in Tomcat management mechanism: http://www.cnblogs.com/interdrp/p/4935614.html

However, the use of Tomcat-redis-session-manager should know that the configuration is still a bit cumbersome, it is necessary to manually modify the tomcat configuration, you need to coupling tomcat and other servlet container code, And the management of the distributed Redis cluster is not very good, the relative individual think that a better framework spring session can really be transparent to the user to manage the distributed session.

The spring session does not rely on the servlet container, but rather the implementation of the Web application code level, which is directly added to the existing project based on the spring session framework to enable the session to be uniformly stored in redis. If your web app is developed based on the spring framework, you can change a single stand-alone web app to a distributed application by simply configuring a small number of existing projects, and you are free to port the project to another container because it is not based on a servlet container.

Spring Session Use
Official address: http://projects.spring.io/spring-session/

Official Document Address: http://docs.spring.io/spring-session/docs/1.3.0.RELEASE/reference/html5/

The Spring session provides a set of scenarios for creating and managing servlet httpsession. The Spring session provides the cluster session (Clustered Sessions) feature, which uses an external Redis to store session data to solve the session sharing problem.

first, the characteristics

The Spring session provides the following features:

APIs and implementations for managing user sessions;
HttpSession-Allows the substitution of HttpSession in an application container (that is, Tomcat) in a neutral manner;
The Clustered sessions-spring session makes it less cumbersome to support cluster sessions and does not bind to application container gold habits.
The multiple Browser sessions-spring session supports the management of multiple user sessions in a single browser instance.
The RESTful apis-spring session allows the session ID to be provided in headers to use the RESTful API.

implementation of spring session case based on XML configuration Method

A small case based on the SSM framework, Git OS Project code address: Http://git.oschina.net/xuliugen/spring-session-demo
Https://img-blog.csdn.net/20170226141717129?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast

Project Showcase:
Https://img-blog.csdn.net/20170226142056838?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast
(1) Basic environmental requirements

The first thing to do with spring session is that there is a REDIS server already installed!

(2) Add Project Dependencies (most basic dependency usage)

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>1.3.0.RELEASE</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>biz.paluch.redis</groupId>
<artifactId>lettuce</artifactId>
<version>3.5.0.Final</version>
</dependency>
(3) Add Spring configuration file

After adding the necessary dependencies, we need to create a corresponding spring configuration. The spring configuration is to create a servlet filter that replaces the HttpSession implementation of the container itself with the HttpSession implementation supported by the spring session. This step is also at the heart of spring session.

<context:annotation-config/>

<bean class= "Org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration "/>

<bean class= "Org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
The above code comment:
Https://img-blog.csdn.net/20170226145153620?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast

The Lettuceconnectionfactory instance is the connectionfactory that configures Redis.

Attention:

<bean class= "Org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory"/>
View the source code to see that the default Redis link configuration is:
Https://img-blog.csdn.net/20170226150015627?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast

Therefore, if you have your own Redis configuration, modify, for example, the configuration below:

<bean class= "Org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory" >
<property name= "HostName" value= "192.168.1.149"/>
<property name= "Port" value= "6379"/>
<property name= "Password" value= "123456"/>
</bean>
(4) About error creating Bean with Name ' Enablerediskeyspacenotificationsinitializer ' errors:

Add the following configuration to let the spring session no longer execute the config command

<util:constant static-field= "Org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>
If not added, the following error will be reported:

Context initialization failed org.springframework.beans.factory.BeanCreationException:Error creating bean with Name ' Enablerediskeyspacenotificationsinitializer ' defined in class path resource [org/springframework/session/data/redis/ Config/annotation/web/http/redishttpsessionconfiguration.class]:
Invocation of Init method failed; Nested exception is java.lang.IllegalStateException:Unable to configure Redis to keyspace notifications.
See http://docs.spring.io/spring-session/docs/current/reference/html5/# Api-redisoperationssessionrepository-sessiondestroyedevent
caused By:redis.clients.jedis.exceptions.JedisDataException:ERR Unknown command config

(5) Add Delegatingfilterproxy to Web. xml

<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

Delegatingfilterproxy will find the bean and convert it to a filter by the name of the Springsessionrepositoryfilter. For each request that calls Delegatingfilterproxy, Springsessionrepositoryfilter is also called.

(6) The Spring MVC controller code is used for testing:

@Controller
@RequestMapping (value = "/spring/session", produces = {conststring.app_json_utf_8})
public class Springsessiondemocontroller {

@RequestMapping(value = "/setSession.do", method = RequestMethod.GET)public void setSession(HttpServletRequest request, HttpServletResponse response) {    String name = request.getParameter("name");    String value = request.getParameter("value");    request.getSession().setAttribute(name, value);}@RequestMapping(value = "/getSession.do", method = RequestMethod.GET)public void getInterestPro(HttpServletRequest request, HttpServletResponse response) {    String name = request.getParameter("name");    System.out.println("------" + request.getSession().getAttribute(name));}@RequestMapping(value = "/removeSession.do", method = RequestMethod.GET)public void removeSession(HttpServletRequest request, HttpServletResponse response) {    String name = request.getParameter("name");    request.getSession().removeAttribute(name);}

}

Https://img-blog.csdn.net/20170226152438708?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast
(7) test

Access Link: http://localhost:8080/spring/session/setSession.do?name=xuiliugen&value=123456

Use the tool to view Redis content:
Https://img-blog.csdn.net/20170226154301031?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGxnZW4xNTczODc=/font /5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/dissolve/70/gravity/southeast

You can see that there are already values! And there are expirations, you can see the position of the arrow pointing, is the time record value of failure!

(8) to this, the use of Spring session has been completed! for other specific details please refer to: Http://git.oschina.net/xuliugen/spring-session-demo Project source code.

Summarize:
The question of cross-domain sharing in a distributed environment, whether using an open source framework or using a framework that you have developed, requires a clear problem: creating a session in a Tomcat container is a memory-intensive thing. So, when we write our own similar framework, we have to be aware that it is not that Tomcat created the session for us, that we first get the session and then upload it to Redis and so on to store it, but we create the session ourselves directly, This is crucial!
Share some of your favorites:
High-availability cluster architecture technology step by step teach you to play with the Nginx and Docker
Link: Https://pan.baidu.com/s/1A7Z75fN2UR-cteT8fgY5kQ Password: yp8e
To the architect, you must understand the advanced features of the Java Virtual machine
Link: Https://pan.baidu.com/s/1hAPo19keNFHb9ycBctkU2A Password: iayw
High concurrency processing technology old driver take you play RABBITMQ performance multiplier
Link: https://pan.baidu.com/s/1nZNYXtqkmEAHPm1JKT2iBg Password: Y3SA
2018.07.09-t5 Architect takes you to understand spring source ~ handwritten SPRINGMVC combat
Link: https://pan.baidu.com/s/1-NRFpVQd0TLyzT1SjskXdg Password: 6AMK

Solve distributed session cross-domain sharing issues using spring session and Redis

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.