使用HazelCast实现Spring Config Server配置

19-01-10 banq
                   

我们可以通过RabbitMQ将Spring Cloud Config服务器的发布配置设置用于MicroServices节点。这个解决方案的缺点:

  • Spring Cloud Config仅支持GIT repo以保存配置
  • 当配置服务器上的数据发生更改时,您需要手动将事件发送到所有MicroServices节点

让我们考虑另一个解决方案,如何删除Spring Config Server并将配置数据的分发替换为具有HazelCast数据网格的节点。

配置Hazelcast

首先你需要为Hazelcast添加maven依赖:( hazelcast-spring,因为我们将使用Spring缓存API和Hazelcast作为CACHE提供者)

<!-- https://mvnrepository.com/artifact/com.hazelcast/hazelcast-spring -->
<dependency>
    <groupId>com.hazelcast</groupId>
    <artifactId>hazelcast-spring</artifactId>
</dependency>

然后你需要配置Hazelcast,你有以下选择:

  • 配置com.hazelcast.config.Config 或
  • 将hazelcast.xml配置放到classpath中。请参阅此文档 或
  • 如果您对hazelcast.xml名称不满意,请在文件中设置-Dhazelcast.config变量

我的配置看起来:

@Bean
    public Config config() {
        Config config = new Config();

        config.setInstanceName("HazelcastService");
        config.setProperty("hazelcast.wait.seconds.before.join","10");

        config.getGroupConfig().setName("mygroup");
        config.getGroupConfig().setPassword("mypassword");

        config.getNetworkConfig().setPortAutoIncrement(true);
        config.getNetworkConfig().setPort(10555);
        config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(true);

        SSLConfig sslConfig = new SSLConfig();
        sslConfig.setEnabled(false);
        config.getNetworkConfig().setSSLConfig(sslConfig);

        return config;
    }

  • 始终使用Hazelcast群组。不要干涉他人。检查GroupConfig。
  • 始终使用端口增量。有时某些环境中的端口可能会被占用。

如果您计划将Hazelcast用作分布式缓存,那么您需要使用Hazelcast实现覆盖cacheManager bean:

@Bean 
 HazelcastInstance hazelcastInstance(){ 
     return Hazelcast.newHazelcastInstance(config()); 
 } 

 @Bean 
 public CacheManager cacheManager(){ 
     return new HazelcastCacheManager(hazelcastInstance()); 
 }

带有HazelCast缓存的MicroServices

有以下Util服务:

package com.example.hazelcast;

import org.springframework.cache.annotation.Cacheable;

/**
 * Created by tomas.kloucek on 18.1.2017.
 */
public interface IHazelCastUtilService {
    @Cacheable("batchSize")
    int getBatchSize();
}

实现:

public class HazelCastUtilService implements IHazelCastUtilService {
    @Override
    public int getBatchSize() {
        try {
            System.out.println("Getting batch size from DAO...");
            TimeUnit.SECONDS.sleep(5);  // (1)
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 3;
    }
}

让我们在以下的上下文MicroServices之间共享此服务:

Cities MicroService:

@RestController
public class CitiesController {
    final City[] cities = {
            new City("Brno", "Czech republic"),
            new City("Bern", "Switzeland"),
            new City("Berlin", "Germany"),
            new City("London", "England")
    };

    @Autowired
    private IHazelCastUtilService hazelCastUtilService;

    @RequestMapping("/cities")
    public Cities getCities() {
        final Cities result = new Cities();

        System.out.println("...Getting city from controller!!...");
        for (int i=0; i < hazelCastUtilService.getBatchSize();i++) {
            result.getCities().add(cities[i]);
        }

        return result;
    }
}

Persons MicroService:

@RestController
public class PersonsController {

    @Autowired
    private IHazelCastUtilService hazelCastUtilService;

    final Person[] persons = {
            new Person("Tomas", "Kloucek", "Programmer"),
            new Person("Linus", "Torvalds", "Linux"),
            new Person("Heinz", "Kabutz", "Java"),
            new Person("Jonathan", "Locke", "Wicket")
    };

    @RequestMapping("/persons")
    public Persons getPersons() {
        final Persons result = new Persons();

        System.out.println("...Getting person from controller!!...");
        for (int i=0; i < hazelCastUtilService.getBatchSize();i++) {
            result.getPersons().add(persons[i]);
        }

        return result;
    }
}

测试演示:

git clone https://bitbucket.org/tomask79/microservice-spring-hazelcast-caching.git
mvn clean install (in the root folder with pom.xml)
cd spring-microservice-registry
java -jar target/registry-0.0.1-SNAPSHOT.war
verify that NetFlix Eureka is running at http://localhost:9761

cd ..
cd spring-microservice-service1
java -jar target/service1-0.0.1-SNAPSHOT.war
verify at http://localhost:9761 that citiesService has been registered

cd ..
cd spring-microservice-service2
java -jar target/service2-0.0.1-SNAPSHOT.war
verify at http://localhost:9761 that personsService has been registered

为了确保两个 MicroServices形成Hazelcast集群,你需要看到类似的东西:

Members [2] {
        Member [10.130.48.104]:10555 this
        Member [10.130.48.104]:10556
}

访问: http://localhost:8081/cities

看到下面输出:

...Getting city from controller!!...
Getting batch size from DAO...

访问http://localhost:8082/persons调用第二个微服务:

...Getting person from controller!!...

因为之前已经由城市MicroService缓存了“batchSize”设置。太可爱了!