Spring Bootで簡単にセッションレプリケーションを行う方法
Spring Bootで簡単にセッションレプリケーションを行う方法をご紹介します。
- 複数ポートで動作している同一のSpring Bootモジュール間で、セッション情報を共有できるようにします。
- 今回は「Hazelcast」を用いて実現します。
目次
条件
- Spring Boot 2.1.4
- maven
- Windows 10 64bit
- java 1.8
- Hazelcast
プロジェクトの構成
ここでは、以下のような構成とします。
ソース
コントローラ
TestController.java
package com.example.controller; import javax.servlet.http.HttpSession; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping("/") public class TestController { @GetMapping(value = "/") public String index(HttpSession httpSession) { Integer hits = (Integer) httpSession.getAttribute("hits"); if (hits == null) { hits = 0; } httpSession.setAttribute("hits", ++hits); return "index"; } }
画面
index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <h3>Session Id</h3> <p th:text="${#httpSession.id}"/> <h3>Hits</h3> <p th:text="${#httpSession.getAttribute('hits')}"/> </body> </html>
セッションレプリケーションに必要なもの
pom.xml
以下を追記します。
<dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-all</artifactId> <version>${version.hazelcast}</version> </dependency>
今回は以下のようになりました。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.1</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>rep</artifactId> <version>0.0.1-SNAPSHOT</version> <name>rep</name> <description>Example Project</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-core</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.hazelcast</groupId> <artifactId>hazelcast-all</artifactId> <version>4.2.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <finalName>rep</finalName> </build> </project>
Application.java
以下を追記します。
@Bean public Config config() { return new Config(); } @Bean public WebFilter webFilter(HazelcastInstance hazelcastInstance) { Properties properties = new Properties(); properties.put("instance-name", hazelcastInstance.getName()); properties.put("sticky-session", "false"); return new WebFilter(properties); }
今回は以下のようになりました。
RepApplication.java
package com.example; import java.util.Properties; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import com.hazelcast.config.Config; import com.hazelcast.core.HazelcastInstance; import com.hazelcast.web.WebFilter; @SpringBootApplication public class RepApplication { public static void main(String[] args) { SpringApplication.run(RepApplication.class, args); } @Bean public Config config() { return new Config(); } @Bean public WebFilter webFilter(HazelcastInstance hazelcastInstance) { Properties properties = new Properties(); properties.put("instance-name", hazelcastInstance.getName()); properties.put("sticky-session", "false"); return new WebFilter(properties); } }
実行例
実行形式のJarを作成し、8080と8081の2つのポートで実行します。
例)ポート8080を指定する場合
java -jar rep.jar --server.port=8080
以下のURLをそれぞれブラウザで開きます。
http://localhost:8080/
http://localhost:8081/
当該URLをリロードするたびに以下のような動きとなります。
- セッションIDは変わらない。
- Hitsの数字が加算される。
上記2つのURLを交互にリロードしても、セッションIDは同一でHitsの数字が加算されることがわかります。
セッションレプリケーションを行わない場合(参考)
以下のように、別ポートでモジュールが呼ばれるたびにセッションが変わってしまいます。
(同一ポートのみで動かす場合、セッションは変わりません)
参考
Session Replication with Spring Boot and Hazelcast
https://guides.hazelcast.org/springboot-webfilter-session-replication/