Настройте ehcache с репликацией jgroups на kubernetes - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь настроить небольшое приложение Springboot, используя ehcache с репликацией jgroups в kubernetes, но каким-то образом не могу обнаружить других участников для формирования кластера. Запрос начальной загрузки для поиска других узлов не работает, поскольку сообщение отправляется синхронно, но не принимается другим модулем, находящимся на другом узле.

maven 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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.test.k8s</groupId>
    <artifactId>ehcache-jgroups-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>ehcache-jgroups-demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>${ehcache.version}</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-jgroupsreplication</artifactId>
            <version>1.7</version>
            <exclusions>
                <exclusion>
                    <groupId>net.sf.ehcache</groupId>
                    <artifactId>ehcache-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.jgroups</groupId>
                    <artifactId>jgroups</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.jgroups</groupId>
            <artifactId>jgroups</artifactId>
            <version>3.6.17.Final</version>
        </dependency>
        <dependency>
            <groupId>org.jgroups.kubernetes</groupId>
            <artifactId>kubernetes</artifactId>
            <version>0.9.2</version>
            <exclusions>
                <exclusion>
                    <groupId>io.undertow</groupId>
                    <artifactId>undertow-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Приложение Springboot

@SpringBootApplication
public class EhcacheJgroupsDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(EhcacheJgroupsDemoApplication.class, args);
    }

}

@EnableCaching
@Configuration
class EHCacheConfig {

    @Bean
    public CacheManager cacheManager(){
        return new EhCacheCacheManager(ehCacheManagerFactory().getObject());
    }

    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactory(){
        EhCacheManagerFactoryBean ehCacheBean = new EhCacheManagerFactoryBean();
        ehCacheBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        ehCacheBean.setShared(true);
        return ehCacheBean;
    }

}

@Component
@Slf4j
class CacheManagerCheck implements CommandLineRunner {


    private final CacheManager cacheManager;

    public CacheManagerCheck(CacheManager cacheManager) {
        this.cacheManager = cacheManager;
    }

    @Override
    public void run(String... strings) {
        log.info("\n\n" + "=========================================================\n"
                + "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
                + "=========================================================\n\n");
    }

}

@RestController
class CountryController {

    @Autowired
    CountryRepository countryRepository;

    @GetMapping(value = "/country/{code}")
    public ResponseEntity<Country> getCountryByCode(@PathVariable("code") String code) {
        Country country = countryRepository.findByCode(code);
        return ResponseEntity.ok(country);
    }

    @DeleteMapping(value = "/country/{code}")
    public ResponseEntity deleteCountryByCode(@PathVariable("code") String code) {
        countryRepository.deleteCode(code);
        return ResponseEntity.ok().build();
    }
}

@Slf4j
@Component
class CountryRepository {

    @Cacheable(value="countries", key="#code")
    public Country findByCode(String code) {
        log.info("---> Loading country with code={}", code);
        return new Country(code);
    }

    @CacheEvict(value="countries",key = "#code")
    public int deleteCode(String code){
        log.info("---> Deleting country with code={}", code);
        return 0;
    }
}

@Data
class Country implements Serializable {

    private final String code;
}
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
        updateCheck="false">

    <cacheManagerPeerProviderFactory
            class="x.x.x.x.JGroupsCacheManagerPeerProviderFactory"
            properties="file=jgroups/tcp.xml" />

    <defaultCache maxElementsInMemory="50" eternal="false"
                  overflowToDisk="false" memoryStoreEvictionPolicy="LFU">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=false, replicatePuts=true,
            replicateUpdates=true, replicateUpdatesViaCopy=false,
            replicateRemovals=true"/>

        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoaderFactory"
                properties="bootstrapAsynchronously=false"/>
    </defaultCache>

    <cache name="countries" eternal="false" maxElementsInMemory="100"
           overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
           timeToLiveSeconds="60" memoryStoreEvictionPolicy="LRU">
        <cacheEventListenerFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"
                properties="replicateAsynchronously=false, replicatePuts=true,
            replicateUpdates=true, replicateUpdatesViaCopy=false,
            replicateRemovals=true"/>

        <bootstrapCacheLoaderFactory
                class="net.sf.ehcache.distribution.jgroups.JGroupsBootstrapCacheLoaderFactory"
                properties="bootstrapAsynchronously=false"/>
    </cache>

</ehcache>

tcp.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="urn:org:jgroups"
        xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd">
    <TCP
            bind_addr="${jgroups.tcp.address:match-interface:en.*}"
            bind_port="7800"
            recv_buf_size="5M"
            send_buf_size="1M"
            max_bundle_size="64K"
            enable_diagnostics="true"
            thread_naming_pattern="cl"

            thread_pool.min_threads="0"
            thread_pool.max_threads="500"
            thread_pool.keep_alive_time="30000" />

    <org.jgroups.protocols.kubernetes.KUBE_PING
            namespace="${KUBE_NAMESPACE:ehcache-demo}"/>

    <MERGE3 max_interval="30000"
            min_interval="10000"/>

    <VERIFY_SUSPECT timeout="1500"/>

    <BARRIER />
    <pbcast.NAKACK2 xmit_interval="500"
                    xmit_table_num_rows="100"
                    xmit_table_msgs_per_row="2000"
                    xmit_table_max_compaction_time="30000"
                    use_mcast_xmit="false"
                    discard_delivered_msgs="true" />
    <UNICAST3
            xmit_table_num_rows="100"
            xmit_table_msgs_per_row="1000"
            xmit_table_max_compaction_time="30000"/>
    <pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
                   max_bytes="8m"/>
    <pbcast.GMS print_local_addr="true" join_timeout="3000"
                view_bundling="true"/>
    <MFC max_credits="2M"
         min_threshold="0.4"/>
    <FRAG2 frag_size="60K"  />
    <pbcast.STATE_TRANSFER  />
    <CENTRAL_LOCK />
    <COUNTER/>
</config>

1 Ответ

0 голосов
/ 08 июня 2019

Решил, выставив порт контейнера для сервера undertow и заставив использовать стек ipv4 - https://github.com/kunal-bhatia/ehcache-jgroups-demo

...