中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis如何快速實現分布式session

發布時間:2022-01-20 11:09:18 來源:億速云 閱讀:177 作者:小新 欄目:開發技術

這篇文章主要為大家展示了“Redis如何快速實現分布式session”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“Redis如何快速實現分布式session”這篇文章吧。

前言

我們在開發一個項目時通常需要登錄認證,常用的登錄認證技術實現框架有Spring Security和shiro

Spring Security

Spring Security是一個功能強大且高度可定制的身份驗證和訪問控制框架。它是保護基于spring的應用程序的事實上的標準。

Spring Security是一個專注于為Java應用程序提供身份驗證和授權的框架。與所有Spring項目一樣,Spring Security的真正強大之處在于它可以很容易地擴展以滿足定制需求,并且Spring Security和spring更加適配貼合,我們工作中常常使用到Spring Security。

Apache Shiro

Apache Shiro 是 Java 的一個安全框架。目前,使用 Apache Shiro 的人越來越多,因為它相當簡單,對比Spring Security,可能沒有 Spring Security 做的功能強大,但是在實際工作時可能并不需要那么復雜的東西,所以使用小而簡單的 Shiro 就足夠了。

不足:

這些都是認證技術框架,在單體應用中都是常用的技術框架,但是在分布式中,應用可能要部署多份,這時通過nginx分發請求,但是每個單體應用都要可能重復驗證,因為他們的seesion數據是放在他們自己服務中的。

Session作用

Session是客戶端與服務器通訊會話跟蹤技術,服務器與客戶端保持整個通訊的會話基本信息。

客戶端在第一次訪問服務端的時候,服務端會響應一個sessionId并且將它存入到本地cookie中,在之后的訪問會將cookie中的sessionId放入到請求頭中去訪問服務器。

spring-session

Spring Session是Spring的項目之一,Spring Session把servlet容器實現的httpSession替換為spring-session,專注于解決session管理問題。

Spring Session提供了集群Session(Clustered Sessions)功能,默認采用外置的Redis來存儲Session數據,以此來解決Session共享的問題。

spring-session提供對用戶session管理的一系列api和實現。提供了很多可擴展、透明的封裝方式用于管理httpSession/WebSocket的處理。

支持功能

  1. 輕易把session存儲到第三方存儲容器,框架提供了redis、jvm的map、mongo、gemfire、hazelcast、jdbc等多種存儲session的容器的方式。這樣可以獨立于應用服務器的方式提供高質量的集群。

  2. 同一個瀏覽器同一個網站,支持多個session問題。 從而能夠很容易地構建更加豐富的終端用戶體驗。

  3. Restful API,不依賴于cookie。可通過header來傳遞jessionID 。控制session id如何在客戶端和服務器之間進行交換,這樣的話就能很容易地編寫Restful API,因為它可以從HTTP 頭信息中獲取session id,而不必再依賴于cookie

  4. WebSocket和spring-session結合,同步生命周期管理。當用戶使用WebSocket發送請求的時候

分布式seesion實戰

步驟1:依賴包

因為是web應用。我們加入springboot的常用依賴包web,加入SpringSession、redis的依賴包,移支持把session存儲在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>

這里因為是把seesion存儲在redis,這樣每個服務登錄都是去查看redis中數據進行驗證的,所有是分布式的。 這里要引入spring-session-data-redis和spring-boot-starter-redis

步驟2:配置文件

spring.application.name=spring-boot-redis
server.port=9090
# 設置session的存儲方式,采用redis存儲
spring.session.store-type=redis
# session有效時長為15分鐘
server.servlet.session.timeout=PT15M

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

步驟3:實現邏輯

初始化用戶數據

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

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

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

這里就不用使用數據庫了,初始化兩條數據代替數據庫,用于模擬登錄

登錄

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

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

查找用戶

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

模擬通過用戶名查找用戶

獲取session

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

退出登錄

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

這里退出時,要把session中的用戶信息刪除。

步驟4:編寫session攔截器

session攔截器的作用:驗證當前用戶發來的請求是否有攜帶sessionid,如果沒有攜帶,提示用戶重新登錄。

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

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

@Slf4j
@Configuration
public class SessionCofig implements WebMvcConfigurer {

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

步驟6:測試

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

查詢user1用戶session:http://127.0.0.1:9090/user/session

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

登錄后查看redis中數據:

Redis如何快速實現分布式session

seesion數據已經保存到redis了,到這里我們就整合了使用spring-seesion實現分布式seesion功能。

以上是“Redis如何快速實現分布式session”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普格县| 罗甸县| 法库县| 阳信县| 英吉沙县| 孝义市| 同德县| 阿拉善左旗| 黄骅市| 留坝县| 沾化县| 阿荣旗| 黄陵县| 夏津县| 台东市| 内丘县| 巴东县| 易门县| 沁源县| 涪陵区| 怀仁县| 建昌县| 黑山县| 长泰县| 资溪县| 布拖县| 美姑县| 巴南区| 自贡市| 娄底市| 莒南县| 明溪县| 九台市| 赤城县| 边坝县| 湟中县| 綦江县| 常山县| 新巴尔虎左旗| 乐安县| 景宁|