欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Redis快速實(shí)現(xiàn)分布式session的方法詳解

 更新時(shí)間:2022年01月20日 09:22:46   作者:小伙子vae  
Session是客戶(hù)端與服務(wù)器通訊會(huì)話跟蹤技術(shù),服務(wù)器與客戶(hù)端保持整個(gè)通訊的會(huì)話基本信息。本文主要介紹了Redis快速實(shí)現(xiàn)分布式session的方法,感興趣的可以學(xué)習(xí)一下

前言

我們?cè)陂_(kāi)發(fā)一個(gè)項(xiàng)目時(shí)通常需要登錄認(rèn)證,常用的登錄認(rèn)證技術(shù)實(shí)現(xiàn)框架有Spring Security和shiro

Spring Security

Spring Security是一個(gè)功能強(qiáng)大且高度可定制的身份驗(yàn)證和訪問(wèn)控制框架。它是保護(hù)基于spring的應(yīng)用程序的事實(shí)上的標(biāo)準(zhǔn)。

Spring Security是一個(gè)專(zhuān)注于為Java應(yīng)用程序提供身份驗(yàn)證和授權(quán)的框架。與所有Spring項(xiàng)目一樣,Spring Security的真正強(qiáng)大之處在于它可以很容易地?cái)U(kuò)展以滿足定制需求,并且Spring Security和spring更加適配貼合,我們工作中常常使用到Spring Security。

Apache Shiro

Apache Shiro 是 Java 的一個(gè)安全框架。目前,使用 Apache Shiro 的人越來(lái)越多,因?yàn)樗喈?dāng)簡(jiǎn)單,對(duì)比Spring Security,可能沒(méi)有 Spring Security 做的功能強(qiáng)大,但是在實(shí)際工作時(shí)可能并不需要那么復(fù)雜的東西,所以使用小而簡(jiǎn)單的 Shiro 就足夠了。

不足:

這些都是認(rèn)證技術(shù)框架,在單體應(yīng)用中都是常用的技術(shù)框架,但是在分布式中,應(yīng)用可能要部署多份,這時(shí)通過(guò)nginx分發(fā)請(qǐng)求,但是每個(gè)單體應(yīng)用都要可能重復(fù)驗(yàn)證,因?yàn)樗麄兊?code>seesion數(shù)據(jù)是放在他們自己服務(wù)中的。

Session作用

Session是客戶(hù)端與服務(wù)器通訊會(huì)話跟蹤技術(shù),服務(wù)器與客戶(hù)端保持整個(gè)通訊的會(huì)話基本信息。

客戶(hù)端在第一次訪問(wèn)服務(wù)端的時(shí)候,服務(wù)端會(huì)響應(yīng)一個(gè)sessionId并且將它存入到本地cookie中,在之后的訪問(wèn)會(huì)將cookie中的sessionId放入到請(qǐng)求頭中去訪問(wèn)服務(wù)器。

spring-session

Spring Session是Spring的項(xiàng)目之一,Spring Session把servlet容器實(shí)現(xiàn)的httpSession替換為spring-session,專(zhuān)注于解決session管理問(wèn)題。

Spring Session提供了集群Session(Clustered Sessions)功能,默認(rèn)采用外置的Redis來(lái)存儲(chǔ)Session數(shù)據(jù),以此來(lái)解決Session共享的問(wèn)題。

spring-session提供對(duì)用戶(hù)session管理的一系列api和實(shí)現(xiàn)。提供了很多可擴(kuò)展、透明的封裝方式用于管理httpSession/WebSocket的處理。

支持功能

  1. 輕易把session存儲(chǔ)到第三方存儲(chǔ)容器,框架提供了redis、jvm的map、mongo、gemfire、hazelcast、jdbc等多種存儲(chǔ)session的容器的方式。這樣可以獨(dú)立于應(yīng)用服務(wù)器的方式提供高質(zhì)量的集群。
  2. 同一個(gè)瀏覽器同一個(gè)網(wǎng)站,支持多個(gè)session問(wèn)題。 從而能夠很容易地構(gòu)建更加豐富的終端用戶(hù)體驗(yàn)。
  3. Restful API,不依賴(lài)于cookie??赏ㄟ^(guò)header來(lái)傳遞jessionID ??刂苨ession id如何在客戶(hù)端和服務(wù)器之間進(jìn)行交換,這樣的話就能很容易地編寫(xiě)Restful API,因?yàn)樗梢詮腍TTP 頭信息中獲取session id,而不必再依賴(lài)于cookie
  4. WebSocket和spring-session結(jié)合,同步生命周期管理。當(dāng)用戶(hù)使用WebSocket發(fā)送請(qǐng)求的時(shí)候

分布式seesion實(shí)戰(zhàn)

步驟1:依賴(lài)包

因?yàn)槭莣eb應(yīng)用。我們加入springboot的常用依賴(lài)包web,加入SpringSession、redis的依賴(lài)包,移支持把session存儲(chǔ)在redis

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

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

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.8</version>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-redis</artifactId>
    <version>1.4.7.RELEASE</version>
</dependency>

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

這里因?yàn)槭前裺eesion存儲(chǔ)在redis,這樣每個(gè)服務(wù)登錄都是去查看redis中數(shù)據(jù)進(jìn)行驗(yàn)證的,所有是分布式的。 這里要引入spring-session-data-redis和spring-boot-starter-redis

步驟2:配置文件

spring.application.name=spring-boot-redis
server.port=9090
# 設(shè)置session的存儲(chǔ)方式,采用redis存儲(chǔ)
spring.session.store-type=redis
# session有效時(shí)長(zhǎng)為15分鐘
server.servlet.session.timeout=PT15M

## Redis 配置
## Redis數(shù)據(jù)庫(kù)索引
spring.redis.database=1
## Redis服務(wù)器地址
spring.redis.host=127.0.0.1
## Redis服務(wù)器連接端口
spring.redis.port=6379
## Redis服務(wù)器連接密碼(默認(rèn)為空)
spring.redis.password=

步驟3:實(shí)現(xiàn)邏輯

初始化用戶(hù)數(shù)據(jù)

@Slf4j
@RestController
@RequestMapping(value = "/user")
public class UserController {

    Map<String, User> userMap = new HashMap<>();

    public UserController() {
        //初始化1個(gè)用戶(hù),用于模擬登錄
        User u1=new User(1,"user1","user1");
        userMap.put("user1",u1);
    }
}

這里就不用使用數(shù)據(jù)庫(kù)了,初始化兩條數(shù)據(jù)代替數(shù)據(jù)庫(kù),用于模擬登錄

登錄

 @GetMapping(value = "/login")
    public String login(String username, String password, HttpSession session) {
        //模擬數(shù)據(jù)庫(kù)的查找
        User user = this.userMap.get(username);
        if (user != null) {
            if (!password.equals(user.getPassword())) {
                return "用戶(hù)名或密碼錯(cuò)誤?。?!";
            } else {
                session.setAttribute(session.getId(), user);
                log.info("登錄成功{}",user);
            }
        } else {
            return "用戶(hù)名或密碼錯(cuò)誤?。?!";
        }
        return "登錄成功!?。?;
    }

登錄接口,根據(jù)用戶(hù)名和密碼登錄,這里進(jìn)行驗(yàn)證,如果驗(yàn)證登錄成功,使用 session.setAttribute(session.getId(), user);把相關(guān)信息放到session中。

查找用戶(hù)

    /**
     * 通過(guò)用戶(hù)名查找用戶(hù)
     */
    @GetMapping(value = "/find/{username}")
    public User find(@PathVariable String username) {
        User user=this.userMap.get(username);
        log.info("通過(guò)用戶(hù)名={},查找出用戶(hù){}",username,user);
        return user;
    }

模擬通過(guò)用戶(hù)名查找用戶(hù)

獲取session

  /**
     *拿當(dāng)前用戶(hù)的session
     */
    @GetMapping(value = "/session")
    public String session(HttpSession session) {
        log.info("當(dāng)前用戶(hù)的session={}",session.getId());
        return session.getId();
    }

退出登錄

  /**
     * 退出登錄
     */
    @GetMapping(value = "/logout")
    public String logout(HttpSession session) {
        log.info("退出登錄session={}",session.getId());
        session.removeAttribute(session.getId());
        return "成功退出??!";
    }

這里退出時(shí),要把session中的用戶(hù)信息刪除。

步驟4:編寫(xiě)session攔截器

session攔截器的作用:驗(yàn)證當(dāng)前用戶(hù)發(fā)來(lái)的請(qǐng)求是否有攜帶sessionid,如果沒(méi)有攜帶,提示用戶(hù)重新登錄。

 @Configuration
    public class SecurityInterceptor implements HandlerInterceptor {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
            HttpSession session = request.getSession();
            //驗(yàn)證當(dāng)前session是否存在,存在返回true true代表能正常處理業(yè)務(wù)邏輯
            if (session.getAttribute(session.getId()) != null){
                log.info("session攔截器,session={},驗(yàn)證通過(guò)",session.getId());
                return true;
            }
            //session不存在,返回false,并提示請(qǐng)重新登錄。
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            response.getWriter().write("請(qǐng)登錄!?。。?!");
            log.info("session攔截器,session={},驗(yàn)證失敗",session.getId());
            return false;
        }
    }

步驟5:把攔截器注入到攔截器鏈中

@Slf4j
@Configuration
public class SessionCofig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SecurityInterceptor())
                //排除攔截的2個(gè)路徑
                .excludePathPatterns("/user/login")
                .excludePathPatterns("/user/logout")
                //攔截所有URL路徑
                .addPathPatterns("/**");
    }
}

步驟6:測(cè)試

登錄user1用戶(hù):http://127.0.0.1:9090/user/login?username=user1&password=user1

查詢(xún)user1用戶(hù)session:http://127.0.0.1:9090/user/session

退出登錄: http://127.0.0.1:9090/user/logout

登錄后查看redis中數(shù)據(jù):

seesion數(shù)據(jù)已經(jīng)保存到redis了,到這里我們就整合了使用spring-seesion實(shí)現(xiàn)分布式seesion功能。

以上就是Redis快速實(shí)現(xiàn)分布式session的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Redis 分布式session的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文)

    Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文)

    這篇文章主要介紹了Windows環(huán)境下Redis Cluster環(huán)境搭建(圖文),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • Redis分布式鎖實(shí)例分析講解

    Redis分布式鎖實(shí)例分析講解

    分布式鎖是控制分布式系統(tǒng)不同進(jìn)程共同訪問(wèn)共享資源的一種鎖的實(shí)現(xiàn)。如果不同的系統(tǒng)或同一個(gè)系統(tǒng)的不同主機(jī)之間共享了某個(gè)臨界資源,往往需要互斥來(lái)防止彼此干擾,以保證一致性
    2022-12-12
  • 為什么RedisCluster設(shè)計(jì)成16384個(gè)槽

    為什么RedisCluster設(shè)計(jì)成16384個(gè)槽

    本文主要介紹了為什么RedisCluster設(shè)計(jì)成16384個(gè)槽,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Redis中3種特殊的數(shù)據(jù)類(lèi)型(BitMap、Geo和HyperLogLog)

    Redis中3種特殊的數(shù)據(jù)類(lèi)型(BitMap、Geo和HyperLogLog)

    這篇文章主要給大家介紹了關(guān)于Redis中3種特殊的數(shù)據(jù)類(lèi)型(BitMap、GEOADD和GEODIST)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • redis 交集、并集、差集的具體使用

    redis 交集、并集、差集的具體使用

    這篇文章主要介紹了redis 交集、并集、差集的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Redis中的zset類(lèi)型詳解

    Redis中的zset類(lèi)型詳解

    有序集合zset保留了set集合不能有重復(fù)成員的特點(diǎn),但與set集合不同的是,zset的每個(gè)member都有一個(gè)唯一的浮點(diǎn)數(shù)類(lèi)型的分?jǐn)?shù)score與之關(guān)聯(lián),這篇文章主要介紹了Redis的zset類(lèi)型,需要的朋友可以參考下
    2023-08-08
  • Redis三種常用的緩存讀寫(xiě)策略步驟詳解

    Redis三種常用的緩存讀寫(xiě)策略步驟詳解

    Redis有三種讀寫(xiě)策略分別是:旁路緩存模式策略、讀寫(xiě)穿透策略、異步緩存寫(xiě)入策略,接下來(lái)通過(guò)本文給大家詳細(xì)介紹下Redis三種常用的緩存讀寫(xiě)策略,感興趣的朋友一起看看吧
    2022-05-05
  • 壓縮Redis里的字符串大對(duì)象操作

    壓縮Redis里的字符串大對(duì)象操作

    這篇文章主要介紹了壓縮Redis里的字符串大對(duì)象操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • Redis安全策略詳解

    Redis安全策略詳解

    緩存穿透是指當(dāng)用戶(hù)在查詢(xún)一條數(shù)據(jù)的時(shí)候,而此時(shí)數(shù)據(jù)庫(kù)和緩存卻沒(méi)有關(guān)于這條數(shù)據(jù)的任何記錄,而這條數(shù)據(jù)在緩存中沒(méi)找到就會(huì)向數(shù)據(jù)庫(kù)請(qǐng)求獲取數(shù)據(jù)。用戶(hù)拿不到數(shù)據(jù)時(shí),就會(huì)一直發(fā)請(qǐng)求,查詢(xún)數(shù)據(jù)庫(kù),這樣會(huì)對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)造成很大的壓力
    2022-07-07
  • Redis高效率原因及數(shù)據(jù)結(jié)構(gòu)分析

    Redis高效率原因及數(shù)據(jù)結(jié)構(gòu)分析

    這篇文章主要為大家詳細(xì)的介紹了Redis高效的原因以及分析了Redis高效的數(shù)據(jù)結(jié)構(gòu),有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09

最新評(píng)論