Table of Contents
Redis implements session sharing" >Redis implements session sharing
Home Database Redis Detailed explanation of Redis implementation of Session sharing

Detailed explanation of Redis implementation of Session sharing

Jul 30, 2020 am 11:34 AM
redis session

Detailed explanation of Redis implementation of Session sharing

Redis implements session sharing

In the past few days, I have been working on such a small module for session sharing. After checking a lot of information, I feel that it is too confusing and I have never been able to find what I want. Almost all implementation methods are different from what I thought. Here, I will summarize how I use Redis to implement sessions. It is shared to facilitate future inquiries, and I hope it can provide some help to friends who have needs in this regard.

Related topic recommendations: php session (including pictures, texts, videos, cases)

Let’s talk first Let’s take a look at my development environment: nginx, redis, tomcat, use moven to build the project, and run the jetty server. So here, the following will also cover how to use maven to build a war package and deploy it to run on tomcat.

Redis is a key-value database. Saving and retrieving values ​​depends entirely on the key. I’m going to say a long sentence here because it’s original and professional. I won’t paste it here. I want to know more about it. For the official introduction, you can search by yourself.

Configuration in pom.xml:

<!-- redis -->  
<dependency>  
<groupId>redis.clients</groupId>  
<artifactId>jedis</artifactId>  
<version>2.8.1</version>  
</dependency>  
<dependency>  
<groupId>org.springframework.data</groupId>  
<artifactId>spring-data-redis</artifactId>  
<version>1.7.2.RELEASE</version>  
</dependency>
Copy after login

Configuration in applicationContext-redis.xml

<!-- redis 客户端配置 -->  
   <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">  
       <property name="maxTotal" value="${jedisPoolConfig.maxTotal}"/>  
       <property name="maxIdle" value="${jedisPoolConfig.maxIdle}"/>  
       <property name="maxWaitMillis" value="${jedisPoolConfig.maxWaitMillis}"/>  
       <property name="testWhileIdle" value="true"/>  
       <property name="testOnBorrow" value="false"/>  
       <property name="testOnReturn" value="false"/>  
   </bean>  
   <bean id="readJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
       <property name="hostName" value="${jedis.read.host}" />  
       <property name="port" value="${jedis.read.port}" />  
       <property name="password" value="${jedis.read.password}" />  
       <property name="timeout" value="${jedis.read.timeout}" />  
       <property name="database" value="${jedis.read.database}" />  
       <property name="poolConfig" ref="jedisPoolConfig" />  
   </bean>  
   <bean id="writeJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">  
       <property name="hostName" value="${jedis.write.host}" />  
       <property name="port" value="${jedis.write.port}" />  
       <property name="password" value="${jedis.write.password}" />  
       <property name="timeout" value="${jedis.write.timeout}" />  
       <property name="database" value="${jedis.write.database}" />  
       <property name="poolConfig" ref="jedisPoolConfig" />  
   </bean>  
   <bean id="readRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
       <property name="connectionFactory" ref="readJedisConnectionFactory" />  
   </bean>  
   <bean id="writeRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">  
       <property name="connectionFactory" ref="writeJedisConnectionFactory" />  
   </bean>
Copy after login

After the configuration is completed, start the code implementation:

In LoginController:

The first step, introduce RedisTemplate

@Autowired  
@Qualifier("writeRedisTemplate")  
private StringRedisTemplate writeTemplate;
Copy after login

You only need to introduce writeRedisTemplate here. When logging in, it is only responsible for writing. Only when refreshing again, after passing the filter, do you need to read

The second step, normal login process, after successful login, the request also needs to save the session information

##The third step, set the cookie value, store the key value in redis as the key value for saving userSession information in the cookie, refresh the browser At this time, the filter can get the key value from the cookie, and then go to redis to get the corresponding value, that is, userSession

String domain = request.getServerName();  
       String cookieId=MD5Util.MD5Encode("uasLoginer", "UTF-8");  
       //生成token,用作session在redis存储中的key值      
       StringredisSessionKey= UUID.randomUUID().toString();  
       Cookie uasLoginer = new Cookie(cookieId, redisSessionKey);  
       if (domain.startsWith("uas.")) {  
    uasLoginer.setDomain(domain.substring(4,domain.length()));  
}else {  
    uasLoginer.setDomain(domain);  
}  
       uasLoginer.setMaxAge(60000);  
       uasLoginer.setPath("/");  
       response.addCookie(uasLoginer);
Copy after login

here Cookie cross-domain setDomain and setPath settings

The fourth step, store the userSession information into redis

The value written to redis in RedisTemplate must be of String type, and the userSession object needs to be converted into a Json string

userSessionString = JSON.toJSONString(userSession);
Copy after login

在转Json的时候,遇到问题,导入import com.alibaba.fastjson.JSON;一直失败,发现pom中没有依赖Json的关系,如果有遇到相同的问题,可以检查下在pom.xml中是否有关于json的依赖关系,没的话,在pom.xml中导入json的依赖关系,如下:

<dependency>  
    <groupId>net.sf.json-lib</groupId>  
    <artifactId>json-lib</artifactId>  
    <version>2.3</version>  
    <classifier>jdk15</classifier>  
</dependency>
Copy after login

写入redis的代码如下:

writeTemplate.opsForHash().put(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey,redisSessionKey, userSessionString);  
writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);//设置redis中值的有效期
Copy after login

完成这一操作,用户的session信息已经存入到redis中,可在redis中查看是否存入。

第五步:进入页面后,刷新页面,请求会经过过滤器,在Filter.Java中读取redis的值并进行一些处理

在过滤器这里,就无法通过注解的方式引入redisTemplate,可以通过如下的方式引入:

BeanFactory beans = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());  
     StringRedisTemplate readTemplate = (StringRedisTemplate) beans.getBean("readRedisTemplate");  
     StringRedisTemplate writeTemplate = (StringRedisTemplate) beans.getBean("writeRedisTemplate");
Copy after login

过滤器从cookie中取出redis的key值,用readTemplate读出value值

String cookid=MD5Util.MD5Encode("uasLoginer", "UTF-8");  
Cookie[] cookies = req.getCookies();  
String redisSessionKey = "";  
if(cookies != null){  
    for (Cookie cookie : cookies) {  
        if(cookie.getName().equals(cookid)){  
            redisSessionKey = cookie.getValue() ;  
        }  
    }  
}  
UserSession userSession = null;  
String userSessionString = (String) readTemplate.boundHashOps(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey).get(redisSessionKey);  
if(null != userSessionString ){  
    @SuppressWarnings("static-access")  
    JSONObject obj = new JSONObject().fromObject(userSessionString);//将json字符串转换为json对象  
    userSession = (UserSession)JSONObject.toBean(obj,UserSession.class);  
    writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);  
    request.getSession().setAttribute(UasContants.USER_SESSION, userSession);  
}  
if (userSession != null) {  
    chain.doFilter(req, res);  
    return;  
}else {  
    res.sendRedirect(UasContants.LOGIN_URL);  
    return;  
}
Copy after login

在这里,另外附上关于web.xml关于LoginFilter的配置,有需要的可以参考下:

<!-- Spring监听器 -->  
<listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  
<filter>  
    <filter-name>loginFilter</filter-name>  
    <filter-class>com.sfbest.uas.filter.LoginFilter</filter-class>  
    <init-param>  
        <param-name>excludePaths</param-name>  
        <param-value>/login,/user/login,/user/auth</param-value>  
    </init-param>  
</filter>  
<filter-mapping>  
    <filter-name>loginFilter</filter-name>  
    <url-pattern>/*</url-pattern>  
</filter-mapping>
Copy after login

按照上面的配置,就可以用redis实现session共享的功能,但我在开发的时候,遇到一个蛋疼的问题,在测试环境上,

把项目部署在两台tomcat服务器上的时候,cookie里一直存不进去redis的key值,单台可以存进去,经过长期的检测,

终于发现是nginx配置出的问题,引以为戒,深深的阴影。下面我贴出我正常运行时nginx的配置代码

upstream uassessiontest.d.com {  
        server 10.103.16.226:8088;  
        server 10.103.16.226:8089;  
        }  
       server {  
                 log_format  sf_uastest  &#39;$remote_addr - $remote_user [$time_local] "$request" &#39;  
                                        &#39;$status $body_bytes_sent "$http_referer" &#39;  
                                        &#39;"$http_user_agent" $http_cookie&#39;;  
                listen 80;  
                server_name uassessiontest.d.com;  
                access_log /var/log/nginx/uassessiontest.log sf_uastest; 
  
                location / {  
                        rewrite ^/$ /uas/ break;  
                        proxy_pass http://uassessiontest.d.com;  
                }  
        }
Copy after login

红色的为当初少配的部分,这些部分是的作用是往浏览器端写入cookie值。

相关学习推荐:redis视频教程

The above is the detailed content of Detailed explanation of Redis implementation of Session sharing. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

How to build the redis cluster mode How to build the redis cluster mode Apr 10, 2025 pm 10:15 PM

Redis cluster mode deploys Redis instances to multiple servers through sharding, improving scalability and availability. The construction steps are as follows: Create odd Redis instances with different ports; Create 3 sentinel instances, monitor Redis instances and failover; configure sentinel configuration files, add monitoring Redis instance information and failover settings; configure Redis instance configuration files, enable cluster mode and specify the cluster information file path; create nodes.conf file, containing information of each Redis instance; start the cluster, execute the create command to create a cluster and specify the number of replicas; log in to the cluster to execute the CLUSTER INFO command to verify the cluster status; make

How to clear redis data How to clear redis data Apr 10, 2025 pm 10:06 PM

How to clear Redis data: Use the FLUSHALL command to clear all key values. Use the FLUSHDB command to clear the key value of the currently selected database. Use SELECT to switch databases, and then use FLUSHDB to clear multiple databases. Use the DEL command to delete a specific key. Use the redis-cli tool to clear the data.

How to use the redis command How to use the redis command Apr 10, 2025 pm 08:45 PM

Using the Redis directive requires the following steps: Open the Redis client. Enter the command (verb key value). Provides the required parameters (varies from instruction to instruction). Press Enter to execute the command. Redis returns a response indicating the result of the operation (usually OK or -ERR).

How to use redis lock How to use redis lock Apr 10, 2025 pm 08:39 PM

Using Redis to lock operations requires obtaining the lock through the SETNX command, and then using the EXPIRE command to set the expiration time. The specific steps are: (1) Use the SETNX command to try to set a key-value pair; (2) Use the EXPIRE command to set the expiration time for the lock; (3) Use the DEL command to delete the lock when the lock is no longer needed.

How to read redis queue How to read redis queue Apr 10, 2025 pm 10:12 PM

To read a queue from Redis, you need to get the queue name, read the elements using the LPOP command, and process the empty queue. The specific steps are as follows: Get the queue name: name it with the prefix of "queue:" such as "queue:my-queue". Use the LPOP command: Eject the element from the head of the queue and return its value, such as LPOP queue:my-queue. Processing empty queues: If the queue is empty, LPOP returns nil, and you can check whether the queue exists before reading the element.

How to implement the underlying redis How to implement the underlying redis Apr 10, 2025 pm 07:21 PM

Redis uses hash tables to store data and supports data structures such as strings, lists, hash tables, collections and ordered collections. Redis persists data through snapshots (RDB) and append write-only (AOF) mechanisms. Redis uses master-slave replication to improve data availability. Redis uses a single-threaded event loop to handle connections and commands to ensure data atomicity and consistency. Redis sets the expiration time for the key and uses the lazy delete mechanism to delete the expiration key.

How to read the source code of redis How to read the source code of redis Apr 10, 2025 pm 08:27 PM

The best way to understand Redis source code is to go step by step: get familiar with the basics of Redis. Select a specific module or function as the starting point. Start with the entry point of the module or function and view the code line by line. View the code through the function call chain. Be familiar with the underlying data structures used by Redis. Identify the algorithm used by Redis.

How to make message middleware for redis How to make message middleware for redis Apr 10, 2025 pm 07:51 PM

Redis, as a message middleware, supports production-consumption models, can persist messages and ensure reliable delivery. Using Redis as the message middleware enables low latency, reliable and scalable messaging.

See all articles