将 Hazelcast 用于 Spring 会话和 2 级缓存 (LC2) 与 Hibernate

Using Hazelcast for both Spring Session and 2 Level Cache (LC2) with Hibernate

所以我想在我的 Web 应用程序中使用 Hazelcast 进行 2 级缓存(休眠层)和 spring 会话,设置非常简单我希望能够将 NearCache 配置与服务器 运行 在网络上。

我首先 运行 遇到兼容性问题,最新版本的 Hazelcast 4.* 在 spring 会话中尚不支持,所以我很高兴使用支持的版本:3.12.6.. . 下面是我的 hazelcast-client.xml 我已经正确配置它以供 spring.hazelcast.config=file://... 当我启动我的应用程序时,没有创建 Hazelcast 实例,所以我决定我应该创建 ClientConfig HazelcastInstance beans 我自己使用下面的代码:

@Bean()
ClientConfig clientConfig() throws IOException{
    try(final InputStream stream = Files.newInputStream(Paths.get("proper-path/hazelcast-client.xml"))){
      com.hazelcast.client.config.XmlClientConfigBuilder builder = new com.hazelcast.client.config.XmlClientConfigBuilder(stream);
      return builder.build();
    }
  }
@Bean()
HazelcastInstance hazelcastInstance(final ClientConfig clientConfig){
    return HazelcastClient.newHazelcastClient(clientConfig);
}

现在我有一个问题,我无法添加下面的代码,所以我可以在会话中使用它:

final MapAttributeConfig attributeConfig = new MapAttributeConfig()
            .setName(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE)
            .setExtractor(PrincipalNameExtractor.class.getName());

hazelcastInstance.getConfig().getMapConfig(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME)
        .addMapAttributeConfig(attributeConfig)
        .addMapIndexConfig(new MapIndexConfig(HazelcastIndexedSessionRepository.PRINCIPAL_NAME_ATTRIBUTE, false));  

hazelcast-client.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <hazelcast-client xmlns="http://www.hazelcast.com/schema/client-config"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="http://www.hazelcast.com/schema/client-config
                  http://www.hazelcast.com/schema/client-config/hazelcast-client-config-3.12.xsd">
    <group>
        <name>GroupName</name>
        <password>pass</password>
    </group>
    <instance-name>${application.container.name}</instance-name>
    <properties>
        <property name="hazelcast.client.shuffle.member.list">true</property>
        <property name="hazelcast.client.heartbeat.timeout">60000</property>
        <property name="hazelcast.client.heartbeat.interval">5000</property>
        <property name="hazelcast.client.event.thread.count">5</property>
        <property name="hazelcast.client.event.queue.capacity">1000000</property>
        <property name="hazelcast.client.invocation.timeout.seconds">120</property>
    </properties>
    <client-labels>
        <label>web-app</label>
        <label>${application.container.name}</label>
    </client-labels>
    <network>
        <cluster-members>
            <address>127.0.0.1</address>
        </cluster-members>
        <outbound-ports>
            <ports>5801</ports>
        </outbound-ports>
        <smart-routing>true</smart-routing>
        <redo-operation>true</redo-operation>
        <connection-timeout>60000</connection-timeout>
        <connection-attempt-period>3000</connection-attempt-period>
        <connection-attempt-limit>2</connection-attempt-limit>
        <socket-options>
            <tcp-no-delay>false</tcp-no-delay>
            <keep-alive>true</keep-alive>
            <reuse-address>true</reuse-address>
            <linger-seconds>3</linger-seconds>
            <buffer-size>128</buffer-size>
        </socket-options>
    </network>
    <executor-pool-size>40</executor-pool-size>
    <native-memory enabled="false" allocator-type="POOLED">
        <size unit="MEGABYTES" value="128"/>
        <min-block-size>1</min-block-size>
        <page-size>1</page-size>
        <metadata-space-percentage>40.5</metadata-space-percentage>
    </native-memory>
    <load-balancer type="random"/>
    <flake-id-generator name="default">
        <prefetch-count>100</prefetch-count>
        <prefetch-validity-millis>600000</prefetch-validity-millis>
    </flake-id-generator>
    <connection-strategy async-start="true" reconnect-mode="ASYNC">
        <connection-retry enabled="true">
            <initial-backoff-millis>2000</initial-backoff-millis>
            <max-backoff-millis>60000</max-backoff-millis>
            <multiplier>3</multiplier>
            <fail-on-max-backoff>true</fail-on-max-backoff>
            <jitter>0.5</jitter>
        </connection-retry>
    </connection-strategy>

   </hazelcast-client>

您需要在服务器端配置映射,这意味着您需要在成员的类路径中包含一些 Spring 类。但请记住,只有在使用 HazelcastIndexedSessionRepository#findByIndexNameAndIndexValue 时才需要此配置。

同样在客户端模式下,不要忘记部署必要的 类 并为成员启用用户代码部署。否则会话更新将失败:

// member
config.getUserCodeDeploymentConfig().setEnabled(true)
      .setClassCacheMode(UserCodeDeploymentConfig.ClassCacheMode.ETERNAL);

// client
clientConfig.getUserCodeDeploymentConfig().setEnabled(true).addClass(Session.class)
            .addClass(MapSession.class).addClass(SessionUpdateEntryProcessor.class);

但我建议在成员的 cp 而不是用户代码部署中包含 spring-session-hazelcast。这样就可以满足以上两个需求了。

最后,如果 hazelcast-client.xml 存在于项目的已知路径之一中(例如,在 resources/ 下),将使用此配置创建客户端。在这种情况下,您不需要创建 ClientConfig bean。