Maison  >  Article  >  Java  >  Comment SpringBoot intègre Spring Session pour implémenter des sessions distribuées

Comment SpringBoot intègre Spring Session pour implémenter des sessions distribuées

WBOY
WBOYavant
2023-05-13 13:52:06933parcourir

Spring propose une solution de gestion des sessions distribuées : Spring-Session. Spring-Session prend en charge le stockage commun tel que Redis, MongoDB, MySQL, etc. Spring-Session fournit une intégration transparente avec HttpSession, ce qui signifie que les développeurs peuvent utiliser l'implémentation prise en charge par Spring-Session pour basculer HttpSession vers Spring-Session.

1. Configuration et développement

Étape 1. Ajouter des dépendances

Ajoutez les packages de dépendances de Redis et Spring-Session dans le fichier pom.xml du projet.

        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

Étape 2. Configurer les méthodes de persistance Redis et Spring-Session

L'auteur est habitué à utiliser application.properties comme fichier de configuration SpringBoot, et vous pouvez également utiliser application.yml pour le configurer. Ajoutez la configuration suivante dans le fichier de configuration application.properties.

# 配置 Redis 服务器地址(此处是一个虚假地址)
spring.redis.host=10.211.12.6
# 配置 Redis 端口
spring.redis.port=6379
# 配置 Redis 密码
spring.redis.password=123456
# 其他 Redis 的配置还有很多,例如 Redis 连接池的配置,此处暂时只配置上述几项关键点
# spring session 配置
spring.session.store-type=redis

Étape 3. Utiliser le mécanisme de sérialisation JSON

Spring-Session utilise le mécanisme de sérialisation JDK par défaut, ce qui nécessite que les classes implémentent l'interface Serialisable. Après la sérialisation, il s'agit d'un tableau d'octets binaires, difficile à comprendre. Grâce au mécanisme de sérialisation JSON, la chaîne sérialisée est facile à comprendre.

package com.test.conf;

import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.RedisSerializer;

// spring session 使用 json 序列化机制
@Configuration
public class SessionConfig {
    @Bean
    public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
        return new GenericFastJsonRedisSerializer();
    }
}

Étape 4. Ajoutez l'annotation @EnableRedisHttpSession à la classe de démarrage SpringBoot pour ouvrir Spring-Session

package com.test;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

@SpringBootApplication
// 开启 Spring-Session
@EnableRedisHttpSession
// @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, redisNamespace = "test:session")
public class TestSessionAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestSessionAppApplication.class, args);
    }
}

Ajoutez l'annotation @EnableRedisHttpSession pour ouvrir Spring-Session. L'annotation comporte plusieurs paramètres qui peuvent être définis individuellement, parmi lesquels maxInactiveIntervalInSeconds représente le délai d'expiration de la session, la valeur par défaut est de 30 minutes ; redisNamespace représente l'espace de noms lorsque la session est stockée dans Redis, c'est-à-dire le préfixe du nom de clé de la session stockée. dans Redis, la valeur par défaut est "spring :session", dans les projets réels, différents systèmes peuvent utiliser le même Redis afin d'économiser des ressources. Afin de distinguer les sessions des différents systèmes, un espace de noms distinct peut être défini pour chaque système.

2. Tests

2.1 Démo de test d'écriture de la couche contrôleur

    @RequestMapping(value = "testSession")
    public String testSession(HttpServletRequest request) {
        HttpSession session = request.getSession();
        log.info("sessionId:[{}]", session.getId());
        session.setAttribute("name", "Lucy");
        session.setAttribute("age", "20");
        return session.getAttribute("name").toString();
    }

2.2 Processus de test

Démarrez le projet SpringBoot avec différents ports 9001/9002 en même temps pour simuler différents nœuds du cluster distribué sur l'ordinateur local. Utilisez Google Chrome pour ouvrir le lien http://localhost:9001/testSession Le serveur imprime le journal comme indiqué ci-dessous.

sessionId:[5c417104-4f6d-430d-b569-cbc1e19cdf02]

Le client se connecte au serveur Redis et affiche le contenu de la session dans Redis.

[testuser@vm ~]$ redis-cli -h 10.211.12.6 -p 6379
10.211.12.6:6379> auth 123456
OK
10.211.12.6:6379> keys *
1) "spring:session:expirations:1658127780000"
2) "spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02"
3) "spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02"

Redis stockera trois paires clé-valeur (ci-après dénommées clé-valeur) pour chaque RedisSession :

  • La première clé-valeur stocke l'ID de cette session, qui est une structure de données Redis de type Set. La dernière valeur 1658127780000 de cette clé est un horodatage calculé en fonction du moment d'expiration de la session reporté à la minute suivante.

  • La deuxième valeur-clé est utilisée pour stocker les informations détaillées de la session. Il s'agit d'une structure de données Redis de type Hash, comprenant l'heure du dernier accès de la session (lastAccessedTime), l'intervalle de temps d'expiration (maxInactiveInterval, la valeur par défaut). est de 30 minutes, enregistrée ici la valeur des secondes), l'heure de création (creationTime), sessionAttr, etc.

  • La troisième valeur-clé est utilisée pour représenter le délai d'expiration de la session dans Redis. Il s'agit d'une structure de données Redis de type String. Cette valeur-clé ne stocke aucune donnée utile, elle est simplement définie pour indiquer l'expiration de la session. Le délai d'expiration de cette clé dans Redis est l'intervalle d'expiration de la session. Vous pouvez utiliser la commande ttl pour afficher le délai d'expiration de la clé, qui est le délai d'expiration de la session.

Lors de ce test, les détails des données dans Redis sont les suivants.

10.211.12.6:6379> type spring:session:expirations:1658127780000
set
10.211.12.6:6379> smembers spring:session:expirations:1658127780000
1) "\"expires:5c417104-4f6d-430d-b569-cbc1e19cdf02\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
hash
10.211.12.6:6379> hgetall spring:session:sessions:5c417104-4f6d-430d-b569-cbc1e19cdf02
 1) "lastAccessedTime"
 2) "1658125969794"
 3) "maxInactiveInterval"
 4) "1800"
 5) "creationTime"
 6) "1658125925139"
 7) "sessionAttr:age"
 8) "\"20\""
 9) "sessionAttr:name"
10) "\"Lucy\""
10.211.12.6:6379>
10.211.12.6:6379> type spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
string
10.211.12.6:6379> get spring:session:sessions:expires:5c417104-4f6d-430d-b569-cbc1e19cdf02
""
10.201.42.26:6379>

Vérifiez le cookie du navigateur À ce moment, le navigateur a déjà un cookie utilisé, comme le montre l'image ci-dessous.

SpringBoot怎么整合Spring Session实现分布式会话

Actualisez le navigateur, le SessionId imprimé sur le backend reste inchangé, le contenu de la session dans Redis n'est pas ajouté et le navigateur renvoie le contenu normalement. Cela signifie que le fonctionnement de session de ce nœud est normal.

Avec le même navigateur, ouvrez un autre lien de port de test http://localhost:9002/testSession. Le navigateur transporte automatiquement les cookies. Le contenu d'impression backend est le même et le contenu Redis est le même (le délai d'expiration a été mis à jour). , indiquant que les nœuds du cluster sont en session partagée.

3. Inconvénients de Spring-Session

Bien que Spring-Session fournisse une méthode d'intégration facile à utiliser et presque transparente qui rend la prise en charge des sessions de cluster triviale, Spring-Session présente en fait quelques défauts.

  • Impossible de publier les événements d'expiration et de destruction de session en temps réel ;

  • La méthode de sérialisation peut ne pas très bien prendre en charge certains types spécifiques de sessions

  • Redis nécessite 3 clés pour stocker une valeur de session, occupant légèrement ; espace plus grand ;

  • Dans les scénarios de concurrence élevée, étant donné que Session n'est pas une opération CAS (Compare And Set), il peut y avoir des problèmes de concurrence (problèmes mineurs).

Bien que Spring-Session présente quelques défauts, dans l'ensemble, il reste très utilisable. De plus, vous pouvez écrire vous-même un ensemble de filtres pour optimiser les lacunes de Spring-Session et implémenter des sessions distribuées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer