Spring Cloud Config Server 如何将纯文本文件推送到 Config Client Application?

Posted

技术标签:

【中文标题】Spring Cloud Config Server 如何将纯文本文件推送到 Config Client Application?【英文标题】:How Spring Cloud Config Server PUSH plain text files to Config Client Application? 【发布时间】:2017-03-29 05:54:15 【问题描述】:

到目前为止我已经实现的是:

    带有“本机”存储库的 Spring Cloud Config Server。

spring.profiles.active: native

spring.cloud.config.server.native.searchLocations: file:/path/to/config-repo

    Config Server 正在通过 RabbitMQ 向 Config Client App 推送通知,为 http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html#_push_notifications_and_spring_cloud_bus

    Config Client App 在 Service bean 上注解了 @RefreshScope。

所以 /config-repo 有 3 个文件 - application.yaml、client.yaml 和 client.json 所有 yaml 属性更改肯定会由 Config Client App 自动重新加载。但是,client.json 没有。

基于https://github.com/spring-cloud/spring-cloud-config/issues/147,我可以使用 /appname/profile/label/client.json 通过 REST api 调用 Config Server 来获取 Config Client App 上的文件

问题是:

1) Config Server 是否通过“native”监控此纯文本文件的更改?

2) Config Client App 如何在更新后自动重新加载此 client.json? (我可以安排任务来调用配置服务器,但这并不理想。)

【问题讨论】:

嗨,我想知道你是否遇到这个问题:github.com/spring-cloud/spring-cloud-config/issues/546 见cloud.spring.io/spring-cloud-config/… 我已按照此说明进行操作。但它不适用于纯文本文件。 【参考方案1】:

我就是这样偷懒的(还没有完成): 我有以逗号分隔的 URI 列表形式的 spring.cloud.config.server.native.serach-locations

file:/c:/repo/a,file:/c:/repo/b

我创建了 FileMonitorConfiguration bean(但它有一些问题,因为它被调度了 2 次,一个 bean 本身和一个 spring 增强实例,我不熟悉这个)

并实现(只是草稿)NativePropertyPathNotificationExtractor

@Configuration
@EnableAutoConfiguration
@EnableConfigServer
public class ConfigServerApplication 
    public static void main(String[] args) 
        SpringApplication.run(ConfigServerApplication.class, args);
    

    @Bean
    NativePropertyPathNotificationExtractor nativePropertyPathNotificationExtractor(@Autowired(required = false) NativeEnvironmentRepository nativeRepo) 
        return new NativePropertyPathNotificationExtractor(nativeRepo);
    

    @Bean
    FileMonitorConfiguration fileMonitorConfiguration() 
        return new FileMonitorConfiguration();
    


@Order(Ordered.LOWEST_PRECEDENCE - 500)
public class NativePropertyPathNotificationExtractor implements PropertyPathNotificationExtractor 
    private final Set<Path> searchPaths;

    public NativePropertyPathNotificationExtractor(NativeEnvironmentRepository nativeRepo) 
        searchPaths = searchLocations(nativeRepo);
    

    @Override
    public PropertyPathNotification extract(MultiValueMap<String, String> headers, Map<String, Object> payload) 

        // FileMonitor with empty headers, so if some there, ignore
        if (false == headers.isEmpty()) 
            return null;
        
        if (null == searchPaths) 
            return null;
        

        Path path = pathFromPayload(payload);
        if (null == path) 
            return null;
        

        for (Path searchPath : searchPaths) 
            Path relative = searchPath.relativize(path);
            // just a try ;-)
            if (true == relative.startsWith("..")) 
                continue;
            

            return new PropertyPathNotification(relative.toString());
        

        return null;
    

    private Path pathFromPayload(Map<String, Object> payload) 
        if (null == payload) 
            return null;
        
        if (true == payload.isEmpty()) 
            return null;
        
        if (false == payload.containsKey("path")) 
            return null;
        
        if (null == payload.get("path")) 
            return null;
        
        if (true == StringUtils.isEmpty(payload.get("path").toString())) 
            return null;
        
        return Paths.get(payload.get("path").toString()).normalize().toAbsolutePath();
    

    private Set<Path> searchLocations(NativeEnvironmentRepository nativeRepo) 
        if (null == nativeRepo) 
            return null;
        
        if (null == nativeRepo.getSearchLocations()) 
            return null;
        

        final Set<Path> paths = new LinkedHashSet<>();
        for (String location : nativeRepo.getSearchLocations()) 
            try 
                paths.add(Paths.get(new URI(location)).normalize().toAbsolutePath());
             catch (Exception e) 
                System.err.println("Nevalidne search location uri: " + location);
            
        
        return paths;

    

【讨论】:

【参考方案2】:

配置客户端: restTemplate.getForObject("http://localhost:8080/application/default/master/testing-dev.json",String.class);

可以获取.json后缀的文件内容,但我认为它没有获取文件内容,有其他方式获取文件内容

【讨论】:

以上是关于Spring Cloud Config Server 如何将纯文本文件推送到 Config Client Application?的主要内容,如果未能解决你的问题,请参考以下文章

spring-cloud-starter-eureka-server 和 spring-cloud-starter-netflix-eureka-server的区别

spring-cloud-config:spring-cloud-config Maven配置错误

spring-cloud-config-server

无法通过 spring.cloud.config.enabled:false 禁用 Spring Cloud Config

0701-spring cloud config-简介Config Server开发Config Client开发

问题 spring-cloud-config 和 spring-cloud-bus