简体   繁体   English

Spring启动配置服务器

[英]Spring boot config server

I have been trying to get a grip on the spring boot config server that is located Here: https://github.com/spring-cloud/spring-cloud-config and after reading the documentation more thoroughly I was able to work through most of my issues. 我一直试图抓住位于以下位置的spring boot配置服务器: https//github.com/spring-cloud/spring-cloud-config并且在更详尽地阅读文档后我能够完成大部分工作我的问题 I did however have to write an additional class for a file based PropertySourceLocator 但是我必须为基于文件的PropertySourceLocator编写一个额外的类

/*
 * Copyright 2013-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");


* you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.cloud.config.client;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.util.StringUtils;

/**
 * @author Al Dispennette
 *
 */
@ConfigurationProperties("spring.cloud.config")
public class ConfigServiceFilePropertySourceLocator implements PropertySourceLocator {
    private Logger logger = LoggerFactory.getLogger(ConfigServiceFilePropertySourceLocator.class);

    private String env = "default";

    @Value("${spring.application.name:'application'}")
    private String name;

    private String label = name;

    private String basedir = System.getProperty("user.home");

    @Override
    public PropertySource<?> locate() {
        try {
            return getPropertySource();
        } catch (IOException e) {
            logger.error("An error ocurred while loading the properties.",e);
        }

        return null;
    }

    /**
     * @throws IOException
     */
    private PropertySource getPropertySource() throws IOException {
        Properties source = new Properties();
        Path path = Paths.get(getUri());
        if(Files.isDirectory(path)){
            Iterator<Path> itr = Files.newDirectoryStream(path).iterator();
            String fileName = null!=label||StringUtils.hasText(label)?label:name+".properties";
            logger.info("Searching for {}",fileName);
            while(itr.hasNext()){
                Path tmpPath = itr.next();
                if(tmpPath.getFileName().getName(0).toString().equals(fileName)){
                    logger.info("Found file: {}",fileName);
                    source.load(Files.newInputStream(tmpPath));
                }
            }
        }
        return new PropertiesPropertySource("configService",source);
    }

    public String getUri() {
        StringBuilder bldr = new StringBuilder(basedir)
        .append(File.separator)
        .append(env)
        .append(File.separator)
        .append(name);

        logger.info("loading properties directory: {}",bldr.toString());
        return bldr.toString();
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEnv() {
        return env;
    }

    public void setEnv(String env) {
        this.env = env;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    public String getBasedir() {
        return basedir;
    }

    public void setBasedir(String basedir) {
        this.basedir = basedir;
    }

}

Then I added this to the ConfigServiceBootstrapConfiguration.java 然后我将其添加到ConfigServiceBootstrapConfiguration.java中

@Bean
public PropertySourceLocator configServiceFilePropertySource(
        ConfigurableEnvironment environment) {
    ConfigServiceFilePropertySourceLocator locator = new ConfigServiceFilePropertySourceLocator();
    String[] profiles = environment.getActiveProfiles();
    if (profiles.length==0) {
        profiles = environment.getDefaultProfiles();
    }
    locator.setEnv(StringUtils.arrayToCommaDelimitedString(profiles));
    return locator;
}

In the end this did what I wanted. 最后这完成了我想要的。 Now I'm curious to know if this is what I should have done or if I am still missing something and this was already handled and I just missed it. 现在我很想知道这是不是我应该做的,或者我是否仍然遗漏了一些东西,这已经处理过了,我错过了它。

*****Edit for info asked for by Dave****** *****编辑Dave ******要求的信息

If I take out the file property source loader and update the bootstrap.yml with 如果我取出文件属性源加载器并使用更新bootstrap.yml

uri: file://${user.home}/resources

the sample application throws the following error on start up: 示例应用程序在启动时抛出以下错误:

ConfigServiceBootstrapConfiguration : Could not locate PropertySource: Object of class [sun.net.www.protocol.file.FileURLConnection] must be an instance of class java.net.HttpURLConnection

This is why I thought the additional class would be needed. 这就是我认为需要额外课程的原因。 As far as the test case goes I believe you are talking about the SpringApplicationEnvironmentRepositoryTests.java and I agree creating the environment works but as a whole the application does not seem to be opertaing as expected when the uri protocol is 'file'. 就测试用例而言,我相信你在谈论SpringApplicationEnvironmentRepositoryTests.java并且我同意创建环境是有效的,但是当uri协议是'file'时,整个应用程序似乎没有按预期运行。

******Additional Edits******* ******补充编辑*******

This is how I understanding this is working: The sample project has a dependency on the spring-cloud-config-client artifact so therefore has a transitive dependency on the spring-cloud-config-server artifact. 这就是我理解这是如何工作的:示例项目依赖于spring-cloud-config-client工件,因此对spring-cloud-config-server工件具有传递依赖性。 The ConfigServiceBootstrapConfiguration.java in the client artifact creates a property source locator bean of type ConfigServicePropertySourceLocator. 客户端工件中的ConfigServiceBootstrapConfiguration.java创建一个ConfigServicePropertySourceLocator类型的属性源定位器bean。 The ConfigServicePropertySourceLocator.java in the config client artifact has the annotation @ConfigurationProperties("spring.cloud.config") And the property uri exists in said class, hence the setting of spring.cloud.config.uri in the bootstrap.yml file. 配置客户端工件中的ConfigServicePropertySourceLocator.java具有注释@ConfigurationProperties(“spring.cloud.config”)并且属性uri存在于所述类中,因此在bootstrap.yml文件中设置了spring.cloud.config.uri。

I believe this is reenforced up by the following statement in the quickstart.adoc: 我相信这是由quickstart.adoc中的以下语句重新强化的:

When it runs it will pick up the external configuration from the default local config server on port 8888 if it is running. 当它运行时,它将从端口8888上的默认本地配置服务器获取外部配置(如果它正在运行)。 To modify the startup behaviour you can change the location of the config server using bootstrap.properties (like application.properties but for the bootstrap phase of an application context), eg 要修改启动行为,可以使用bootstrap.properties更改配置服务器的位置(如application.properties但适用于应用程序上下文的引导阶段),例如

---- spring.cloud.config.uri: http://myconfigserver.com ---- spring.cloud.config.uri: http ://myconfigserver.com

At this point, some how the JGitEnvironmentRepository bean is getting used and looking for a connection to github. 此时,一些如何使用JGitEnvironmentRepository bean并寻找与github的连接。 I assumed that since uri was the property being set in the ConfigServicePropertySourceLocator then any valid uri protocol would work for pointing to a location. 我假设因为uri是在ConfigServicePropertySourceLocator中设置的属性,所以任何有效的uri协议都可以用于指向某个位置。 That is why I used the 'file://' protocol thinking that the server would pick up the NativeEnvironmentRepository. 这就是为什么我使用'file://'协议认为服务器会选择NativeEnvironmentRepository。

So at this point I'm sure I'm either missing some step or the file system property source locator needs to be added. 所以在这一点上我确定我要么缺少一些步骤,要么需要添加文件系统属性源定位器。

I hope that is a little clearer. 我希望这更清楚一些。

the Full Stack: 全栈:

java.lang.IllegalArgumentException: Object of class [sun.net.www.protocol.file.FileURLConnection] must be an instance of class java.net.HttpURLConnection
    at org.springframework.util.Assert.isInstanceOf(Assert.java:339)
    at org.springframework.util.Assert.isInstanceOf(Assert.java:319)
    at org.springframework.http.client.SimpleClientHttpRequestFactory.openConnection(SimpleClientHttpRequestFactory.java:182)
    at org.springframework.http.client.SimpleClientHttpRequestFactory.createRequest(SimpleClientHttpRequestFactory.java:140)
    at org.springframework.http.client.support.HttpAccessor.createRequest(HttpAccessor.java:76)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:541)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:506)
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:448)
    at org.springframework.cloud.config.client.ConfigServicePropertySourceLocator.locate(ConfigServicePropertySourceLocator.java:68)
    at org.springframework.cloud.bootstrap.config.ConfigServiceBootstrapConfiguration.initialize(ConfigServiceBootstrapConfiguration.java:70)
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:572)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:952)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:941)
    at sample.Application.main(Application.java:20)

I read this thread yesterday and it was missing a vital piece of information 我昨天读了这篇帖子,它遗漏了一条至关重要的信息

If you don't want to use git as a repository, then you need to configure the spring cloud server to have spring.profiles.active=native 如果您不想将git用作存储库,那么您需要将spring cloud服务器配置为具有spring.profiles.active = native

Checkout the spring-config-server code to understand it org.springframework.cloud.config.server.NativeEnvironmentRepository 检查spring-config-server代码以了解它org.springframework.cloud.config.server.NativeEnvironmentRepository

 spring:
   application:
    name: configserver
  jmx:
    default_domain: cloud.config.server
  profiles:
    active: native
  cloud:
    config:
      server:
        file :
          url : <path to config files>  

I just came cross same issue. 我刚刚遇到同样的问题。 I want the configuration server load properties from local file system instead of git repository. 我想从本地文件系统而不是git存储库加载配置服务器的属性。 The following configuration works for me on windows. 以下配置适用于Windows。

spring:  
  profiles:
    active: native
  cloud:
    config:
      server:
        native: 
          searchLocations: file:C:/springbootapp/properties/

Suppose the property file is under C:/springbootapp/properties/ 假设属性文件在C:/ springbootapp / properties /下

For more information please refer to Spring Cloud Documentation and Configuring It All Out 有关更多信息,请参阅Spring Cloud文档配置全部

I think I have the final solution based on your last comments In the configserver.yml I added 我想我有最后的解决方案基于你的最后评论我在configserver.yml中添加了

spring.profiles.active: file
spring.cloud.config.server.uri: file://${user.home}/resources

In the ConfigServerConfiguration.java I added 在我添加的ConfigServerConfiguration.java中

@Configuration
@Profile("file")
protected static class SpringApplicationConfiguration {
@Value("${spring.cloud.config.server.uri}")
String locations;

@Bean
public SpringApplicationEnvironmentRepository repository() {
SpringApplicationEnvironmentRepository repo = new SpringApplicationEnvironmentRepository();
repo.setSearchLocations(locations);
return repo;
}
}

And I was able to view the properties with: 我能够通过以下方式查看属性:

curl localhost:8888/bar/default
curl localhost:8888/foo/development

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM