8.13. 为多个可引导 JAR 实例启用 Web 会话数据存储
您可以将 web 集群应用程序构建和打包为可引导 JAR。
先决条件
-
您已检查了最新的 Maven 插件版本,如
MAVEN_PLUGIN_VERSION.X.GA.Final-redhat-00001,其中 MAVEN_PLUGIN_VERSION 是主版本,X 是 microversion。请参阅 /ga/org/wildfly/plugins/wildfly-jar-maven-plugin 的索引。 -
您已检查了最新的 Galleon 功能包版本,如
3.0.X.GA-redhat-BUILD_NUMBER,其中 X 是 JBoss EAP XP 和 BUILD_NUMBER 的微版本,是 Galleon 功能包的构建号。X 和 BUILD_NUMBER 在 JBoss EAP XP 3.0.0 产品生命周期中都可能会演变。请参阅 /ga/org/jboss/eap/wildfly-galleon-pack 的索引。 您已创建了 Maven 项目,设置父依赖项,并添加了用于创建 web-clustering 应用的依赖项。请参阅 创建可引导 JAR Maven 项目。
重要在设置 Maven 项目时,您必须在 Maven archetype 配置中指定值。例如:
$ mvn archetype:generate \ -DgroupId=com.example.webclustering \ -DartifactId=web-clustering \ -DarchetypeGroupId=org.apache.maven.archetypes \ -DarchetypeArtifactId=maven-archetype-webapp \ -DinteractiveMode=false cd web-clustering注意流程中显示的示例指定以下属性:
-
用于 Maven 插件版本的
${bootable.jar.maven.plugin.version}。 -
Gall
eon 功能包版本的 ${JBoss.xp.galleon.feature.pack.version}。
您必须在项目中设置这些属性。例如:
<properties> <bootable.jar.maven.plugin.version>4.0.3.Final-redhat-00001</bootable.jar.maven.plugin.version> <jboss.xp.galleon.feature.pack.version>3.0.0.GA-redhat-00001</jboss.xp.galleon.feature.pack.version> </properties>-
用于 Maven 插件版本的
流程
将以下内容添加到
pom.xml文件的<build> 元素中。您必须指定任何 Maven 插件的最新版本,以及org.jboss.eap:wildfly-galleon-packGalleon 功能包的最新版本。例如:<plugins> <plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>${bootable.jar.maven.plugin.version}</version> <configuration> <feature-pack-location>org.jboss.eap:wildfly-galleon-pack:${jboss.xp.galleon.feature.pack.version}</feature-pack-location> <layers> <layer>datasources-web-server</layer> <layer>web-clustering</layer> </layers> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin> </plugins>注意本例使用
web-clusteringGalleon 层来启用 Web 会话共享。使用以下配置更新
src/main/webapp/WEB-INF目录中的web.xml文件:<?xml version="1.0" encoding="UTF-8"?> <web-app version="4.0" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"> <distributable/> </web-app><distributable/>标签表示此 servlet 可以分布在多个服务器中。创建用于存储 Java 文件的目录:
$ mkdir -p APPLICATION_ROOT /src/main/java/com/example/webclustering/其中
APPLICATION_ROOT是含有应用的pom.xml配置文件的目录。创建包含以下内容的 Java 文件
MyServlet.java,并将文件保存到APPLICATION_ROOT/src/main/java/com/example/webclustering/目录中:package com.example.webclustering; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns = {"/clustering"}) public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("text/html;charset=UTF-8"); long t; User user = (User) request.getSession().getAttribute("user"); if (user == null) { t = System.currentTimeMillis(); user = new User(t); request.getSession().setAttribute("user", user); } try (PrintWriter out = response.getWriter()) { out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>Web clustering demo</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Session id " + request.getSession().getId() + "</h1>"); out.println("<h1>User Created " + user.getCreated() + "</h1>"); out.println("<h1>Host Name " + System.getenv("HOSTNAME") + "</h1>"); out.println("</body>"); out.println("</html>"); } } }MyServlet.java中的内容定义客户端向其发送 HTTP 请求的端点。创建包含以下内容的 Java 文件
User.java,并将文件保存到APPLICATION_ROOT/src/main/java/com/example/webclustering/目录中:package com.example.webclustering; import java.io.Serializable; public class User implements Serializable { private final long created; User(long created) { this.created = created; } public long getCreated() { return created; } }打包应用程序:
$ mvn package可选 : 要在 JBoss EAP 裸机平台上运行应用,请按照在 JBoss EAP 裸机平台上使用可引导 JAR 中所述的步骤进行操作, 但会有以下差异:
在 JBoss EAP 裸机平台上,您可以使用
java -jar命令来运行多个可引导 JAR 实例,如下例所示:$ java -jar target/web-clustering-bootable.jar -Djboss.node.name=node1 $ java -jar target/web-clustering-bootable.jar -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=10验证 :您可以访问节点 1 实例上的应用 :注意用户会话 ID 和用户创建时间。
终止此实例后,您可以访问节点 2 实例: http://127.0.0.1:8090/clustering。用户必须与会话 ID 和节点 1 实例的用户创建时间匹配。
可选 : 要在 JBoss EAP OpenShift 平台上运行应用,请按照在 JBoss EAP OpenShift 平台上使用可引导 JAR 中所述的步骤,但完成以下步骤:
在插件配置中添加
<cloud/> 元素。例如:<plugins> <plugin> ... <!-- You must evolve the existing configuration with the <cloud/> element --> <configuration > ... <cloud/> </configuration> </plugin> </plugins>重新构建应用程序:
$ mvn clean package-
使用
oc login 命令登录您的 OpenShift 实例。 在 OpenShift 中创建新项目:例如:
$ oc new-project bootable-jar-project若要在 JBoss EAP OpenShift 平台上运行 web-clustering 应用,必须为容器集在其中运行的服务帐户授予授权访问权限。然后,服务帐户可以访问 Kubernetes REST API。以下示例演示了为服务帐户授予授权访问权限:
$ oc policy add-role-to-user view system:serviceaccount:$(oc project -q):default输入以下
oc命令来创建应用程序镜像:$ mkdir target/openshift && cp target/web-clustering-bootable.jar target/openshift1 $ oc import-image ubi8/openjdk-11 --from=registry.redhat.io/ubi8/openjdk-11 --confirm2 $ oc new-build --strategy source --binary --image-stream openjdk-11 --name web-clustering3 $ oc start-build web-clustering --from-dir target/openshift4 部署应用程序:
$ oc new-app web-clustering -e KUBERNETES_NAMESPACE=$(oc project -q) $ oc expose svc/web-clustering重要您必须使用
KUBERNETES_NAMESPACE环境变量来查看当前 OpenShift 命名空间中的其他 pod;否则,服务器会尝试从默认命名空间中检索 pod。获取路由的 URL。
$ oc get route web-clustering --template='{{ .spec.host }}'使用上一命令返回的 URL 访问 Web 浏览器中的应用。例如:
http://ROUTE_NAME/clustering请注意用户会话 ID 和用户创建时间。
将应用程序扩展为两个 pod:
$ oc scale --replicas=2 deployments web-clustering发出以下命令来查看可用的 OpenShift pod 列表,并检查 pod 构建状态:
$ oc get pods-
使用
oc delete pod web-clustering-POD_NAME命令终止最旧的 pod,其中 POD_NAME 是您最旧 pod 的名称。 再次访问应用程序:
http://ROUTE_NAME/clustering预期结果:新容器集生成的会话 ID 和创建时间与已终止 pod 的 相匹配。这表示启用了 Web 会话数据存储。