使用 Infinispan 客户端存储 Web Session
本指南将向你展示如何使用 Vert.x Web Infinispan 扩展将用户会话(Sessions)持久化存储在分布式内存网格 Infinispan 中。
你将构建什么
你将构建一个 Vert.x Web 应用程序,页面将展示:
-
会话 ID 以及该会话的创建时间戳;
-
当前页面的实时动态生成时间。
整个应用程序仅包含一个简洁的 ServerVerticle 类。
前置要求
-
文本编辑器或 IDE
-
Java 11 或更高版本
-
Maven 或 Gradle
-
本地运行的 Infinispan 集群(或 Docker)
创建工程项目
本项目同时提供 Maven 与 Gradle 两种等价构建配置。
使用 Maven
以下是该项目所使用的 pom.xml 构建配置文件内容:
pom.xml<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.vertx.howtos</groupId>
<artifactId>web-session-infinispan-howto</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<vertx.version>5.0.0.CR2</vertx.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-stack-depchain</artifactId>
<version>${vertx.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web-sstore-infinispan</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<mainClass>io.vertx.howtos.web.sessions.ServerVerticle</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
使用 Gradle
使用 Gradle Kotlin DSL 时对应的 build.gradle.kts 文件:
build.gradle.ktsplugins {
java
application
}
repositories {
mavenCentral()
}
java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(11))
}
}
dependencies {
implementation(platform("io.vertx:vertx-stack-depchain:5.0.0.CR2"))
implementation("io.vertx:vertx-web-sstore-infinispan")
}
application {
mainClass = "io.vertx.howtos.web.sessions.ServerVerticle"
}
使用 Infinispan 存储与检索 Session 数据
Vert.x Web 的 SessionStore 接口为读写管理用户会话提供了统一标准抽象。
InfinispanSessionStore 实现类位于 io.vertx:vertx-web-sstore-infinispan 依赖组件中。
以下是 ServerVerticle 类的核心代码:
package io.vertx.howtos.web.sessions;
import io.vertx.core.Future;
import io.vertx.core.VerticleBase;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.Session;
import io.vertx.ext.web.handler.SessionHandler;
import io.vertx.ext.web.sstore.SessionStore;
import io.vertx.ext.web.sstore.infinispan.InfinispanSessionStore;
import java.util.Date;
public class ServerVerticle extends VerticleBase {
public static final String TEMPLATE = ""
+ "Session [%s] created on %s%n"
+ "%n"
+ "Page generated on %s%n";
@Override
public Future<?> start() {
Router router = Router.router(vertx);
JsonObject options = new JsonObject()
.put("servers", new JsonArray()
.add(new JsonObject()
.put("host", "localhost")
.put("port", 11222)
.put("username", "admin")
.put("password", "bar"))
);
SessionStore store = InfinispanSessionStore.create(vertx, options); (1)
router.route().handler(SessionHandler.create(store)); (2)
router.get("/").handler(ctx -> {
Session session = ctx.session();
session.computeIfAbsent("createdOn", s -> System.currentTimeMillis()); (3)
String sessionId = session.id();
Date createdOn = new Date(session.<Long>get("createdOn"));
Date now = new Date();
ctx.end(String.format(TEMPLATE, sessionId, createdOn, now)); (4)
});
return vertx.createHttpServer()
.requestHandler(router)
.listen(8080);
}
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(new ServerVerticle()).await();
}
}
| 1 | 使用目标 Infinispan 集群连接参数(主机名、端口与访问凭据)创建 InfinispanSessionStore 实例; |
| 2 | 注册全局 SessionHandler,负责自动化拦截并管理 Vert.x Web 用户会话; |
| 3 | 在当前会话属性中存入会话创建时间戳; |
| 4 | 拼装响应 HTML 并写回浏览器客户端。 |
运行与测试应用
如果你对 Infinispan 尚不熟悉,建议先行浏览其 官方入门介绍。
你可以使用 Docker 在本地一秒拉起单机版 Infinispan 服务节点:
docker run -p 11222:11222 -e USER="admin" -e PASS="bar" infinispan/server:14.0
若你本地已有独立运行的 Infinispan 实例,请记得同步核对并修改 ServerVerticle 中的网络端口与账密配置。
|
启动 Vert.x Web 应用:
-
在 IDE 中直接右键运行
ServerVerticle; -
使用 Maven:
mvn compile exec:java; -
使用 Gradle:
./gradlew run。
验证高可用会话漂移与容灾
-
在浏览器中访问 http://localhost:8080。当你首次发起请求时,会话创建时间应当与页面生成时间完全一致。
-
现在,模拟 Web 服务端宕机迁移场景:在终端按下 Ctrl+C 强行停止 Vert.x 应用,然后重新启动它。
-
服务重启后,刷新浏览器页面。你会发现会话 ID 与初次创建时间保持完全不变,仅页面生成时间发生了更新。这充分证明了会话数据已经安全持久化在独立的 Infinispan 分布式网格中,成功实现 Web 节点的无状态化与高可用自愈。
本文总结
本指南向你阐明了:
-
创建并配置
InfinispanSessionStore存储实例; -
注册 Vert.x Web
SessionHandler处理管道; -
在分布式会话中存取业务状态数据。