带有 Hazelcast 会话复制的自定义会话监听器
Custom session Listener with Hazelcast session replication
我为会话复制配置了 Hazelcast:
<filter>
<filter-name>hazelcast-filter</filter-name>
<filter-class>com.hazelcast.web.WebFilter</filter-class>
<init-param>
<param-name>map-name</param-name>
<param-value>my-sessions</param-value>
</init-param>
<init-param>
<param-name>cookie-name</param-name>
<param-value>hazelcast.sessionId</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hazelcast-filter</filter-name>
<url-pattern>/</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<listener>
<listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener>
在我的 Web 应用程序中,用户可以创建订单,该订单在会话结束前一直存在。如果订单未完成且会话被销毁(用户注销或会话过期),我想备份该订单处理的所有数据。
没有 Hz 会话复制,我使用自定义 HttpSessionListener 实现来完成此操作,例如:
@Override
public void sessionDestroyed(HttpSessionEvent se) {
Order order = (Order) se.getSession().getAttribute("order");
if (order != null) {
// Backup all data processed by order
}
}
它工作正常,但使用 Hz 我得到 2 个不同的会话,它们不同步:
switch (action) {
case "addOrderItems":
System.out.print("sesId=" + req.getSession().getId());
System.out.println("order=" + req.getSession().getAttribute("order"));
打印sesId=HZDCDC1C77E7934E03A9FE329AAB7053B0 order=Order@6a5f7445
而
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.print("sesId=" + se.getSession().getId());
System.out.println("order=" + se.getSession().getAttribute("order"));
打印 sesId=8748D170885C44B425FEEAA94AAB8A86 order=null
.
似乎 Hazelcast 创建和销毁它自己的会话,我不能(或不知道如何)监听这个会话事件。
是否可以使两个会话保持同步或实现您自己的 Hz 会话监听器?
只需两步即可到达目的地
如果您先创建一个 Hazelcast 实例,那么您可以将其名称作为参数传递,
<init-param>
<param-name>instance-name</param-name>
<param-value>whatever</param-value>
</init-param>
因此会话复制将使用该预先存在的 Hazelcast 实例,而不是生成一个新实例。
当您创建该实例时,您可以以正常方式将侦听器附加到会话存储映射。
<map name="my-sessions">
<entry-listeners>
<entry-listener local="true" include-value="true">your.entry.Listener</entry-listener>
</entry-listeners>
</map>
正如 Neil Stevenson 提到的,Hazelcast 实例应该为 my-sessions
地图预配置 EntryListener
。在我的情况下使用会话复制过滤器,我添加了
<map name="my-sessions">
<entry-listeners>
<entry-listener local="true" include-value="true">path.to.NewOrderSessionListener</entry-listener>
</entry-listeners>
</map>
到hazelcast.xml
(位于right place)。
EntryRemovedListener<String, SessionState>
监听 Hz 会话删除事件的实现就像
public class NewOrderSessionListener implements EntryRemovedListener<String, SessionState> {
@Override
public void entryRemoved(EntryEvent<String, SessionState> event) {
SessionState state = event.getOldValue();
Map<String, Data> map = state.getAttributes();
Data orderData = map.get("order");
if (orderData != null) {
// Backup all data processed by order
}
实际上,Hazelcast provides 是任何事件的解决方案。
我为会话复制配置了 Hazelcast:
<filter>
<filter-name>hazelcast-filter</filter-name>
<filter-class>com.hazelcast.web.WebFilter</filter-class>
<init-param>
<param-name>map-name</param-name>
<param-value>my-sessions</param-value>
</init-param>
<init-param>
<param-name>cookie-name</param-name>
<param-value>hazelcast.sessionId</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>hazelcast-filter</filter-name>
<url-pattern>/</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<listener>
<listener-class>com.hazelcast.web.SessionListener</listener-class>
</listener>
在我的 Web 应用程序中,用户可以创建订单,该订单在会话结束前一直存在。如果订单未完成且会话被销毁(用户注销或会话过期),我想备份该订单处理的所有数据。
没有 Hz 会话复制,我使用自定义 HttpSessionListener 实现来完成此操作,例如:
@Override
public void sessionDestroyed(HttpSessionEvent se) {
Order order = (Order) se.getSession().getAttribute("order");
if (order != null) {
// Backup all data processed by order
}
}
它工作正常,但使用 Hz 我得到 2 个不同的会话,它们不同步:
switch (action) {
case "addOrderItems":
System.out.print("sesId=" + req.getSession().getId());
System.out.println("order=" + req.getSession().getAttribute("order"));
打印sesId=HZDCDC1C77E7934E03A9FE329AAB7053B0 order=Order@6a5f7445
而
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.print("sesId=" + se.getSession().getId());
System.out.println("order=" + se.getSession().getAttribute("order"));
打印 sesId=8748D170885C44B425FEEAA94AAB8A86 order=null
.
似乎 Hazelcast 创建和销毁它自己的会话,我不能(或不知道如何)监听这个会话事件。
是否可以使两个会话保持同步或实现您自己的 Hz 会话监听器?
只需两步即可到达目的地
如果您先创建一个 Hazelcast 实例,那么您可以将其名称作为参数传递,
<init-param>
<param-name>instance-name</param-name>
<param-value>whatever</param-value>
</init-param>
因此会话复制将使用该预先存在的 Hazelcast 实例,而不是生成一个新实例。
当您创建该实例时,您可以以正常方式将侦听器附加到会话存储映射。
<map name="my-sessions">
<entry-listeners>
<entry-listener local="true" include-value="true">your.entry.Listener</entry-listener>
</entry-listeners>
</map>
正如 Neil Stevenson 提到的,Hazelcast 实例应该为 my-sessions
地图预配置 EntryListener
。在我的情况下使用会话复制过滤器,我添加了
<map name="my-sessions">
<entry-listeners>
<entry-listener local="true" include-value="true">path.to.NewOrderSessionListener</entry-listener>
</entry-listeners>
</map>
到hazelcast.xml
(位于right place)。
EntryRemovedListener<String, SessionState>
监听 Hz 会话删除事件的实现就像
public class NewOrderSessionListener implements EntryRemovedListener<String, SessionState> {
@Override
public void entryRemoved(EntryEvent<String, SessionState> event) {
SessionState state = event.getOldValue();
Map<String, Data> map = state.getAttributes();
Data orderData = map.get("order");
if (orderData != null) {
// Backup all data processed by order
}
实际上,Hazelcast provides 是任何事件的解决方案。