Одним из наиболее важных методов непрерывной доставки является сборка ваших двоичных файлов только один раз и их использование в различных средах (разработка, тестирование, приемка и т. Д.). Это означает, что, скорее всего, вам потребуется выполнить внешнюю настройку приложения . С приложениями Spring Boot все сводится к тому, чтобы сохранить значения ваших свойств в ваших application.properties за пределами вашего jar приложения . Делая это, вы можете использовать один и тот же файл jar для развертываний в разных средах (альтернативой является упаковка значений свойств для всех возможных сред с вашим файлом jar, но я не считаю это хорошей практикой в большинстве ситуаций).
Особенно, когда вы создаете и развертываете приложения Spring Boot, вам следует взглянуть на проект Spring Cloud Config . В этом посте я пройдусь по шагам, описанным здесь, и вы увидите, как настроить собственную службу конфигурации всего за несколько шагов.
Прежде чем я покажу, как его настроить, сначала рассмотрим архитектуру:

- Git-репозиторий используется для хранения значений конфигурации. Git — отличный выбор для этого, так как он позволяет отслеживать и хранить изменения.
- DevOps (или любая система, которая хочет внести изменения в конфигурацию) может просто изменить значения конфигурации, отправив свои изменения в репозиторий Git.
- Служба конфигурации поддерживает Git-репозиторий и публикует значения конфигурации по запросу.
- Службы действуют как клиенты конфигурации и могут запрашивать значения конфигурации у службы конфигурации.
Чтобы запустить его на локальном компьютере, выполните следующие действия:
- Настройте репозиторий Git
- Настройте службу конфигурации
- Настройте обслуживание клиентов
- Протестируйте настройку
Самый простой способ — создать каталог ‘spring-config-example’, который будет содержать весь код, необходимый для этой демонстрации. Это будет считаться корневым каталогом для этого поста.
Настройте репозиторий Git
На этом шаге я создаю файл свойств, который помещаю в (локальное) хранилище Git. Затем файл свойств будет использоваться в качестве источника значений свойств для нашего демонстрационного клиентского приложения.
Сначала создайте новый каталог «configstore» и в этом каталоге создайте новый файл с именем «a-bootiful-client.properties». Добавьте следующее содержимое в файл:
|
1
2
3
4
|
server.port=8000message = Hello Worldmanagement.security.enabled=false |
Затем создайте git-репо с помощью команды
‘ git init ‘, добавьте и передайте файл в локальный репозиторий
‘ git commit -a -m 'initial commit' ‘
Вот именно для этого шага.
Настройте службу конфигурации
Как было сказано ранее, сервис — это просто еще один проект Spring Boot. Для настройки проекта я создал новый подкаталог и поместил в него проект Spring Boot «по умолчанию» со следующим макетом:
|
01
02
03
04
05
06
07
08
09
10
|
├── pom.xml└── src └── main ├── java │ └── net │ └── pascalalma │ └── cloud │ └── ConfigServiceApplication.java └── resources └── application.properties |
Файл «pom.xml» имеет следующее содержимое:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
<?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" <modelVersion>4.0.0</modelVersion> <groupId>net.pascalalma.cloud</groupId> <artifactId>configuration-service</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project> |
Это довольно простой pom для Spring Boot Project. Единственная добавленная зависимость — это зависимость для ‘spring-cloud-config-server’.
Класс Application выглядит следующим образом:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
package net.pascalalma.cloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.config.server.EnableConfigServer;@EnableConfigServer@SpringBootApplicationpublic class ConfigServiceApplication { public static void main(String[] args) { SpringApplication.run(ConfigServiceApplication.class, args); }} |
Единственное, что здесь отличается, — это аннотация «EnableConfigServer», которая делает это приложение Spring Boot действующим в качестве сервера конфигурации.
Наконец, есть application.properties, содержащий следующее:
|
1
2
|
server.port=8888spring.cloud.config.server.git.uri=/Users/pascalalma/projects/sandbox/spring-config-example/configstore |
Помимо определения порта, я добавил URI в репозиторий Git, который содержит свойства для использования. Как уже было сказано, я использую локальное репо здесь, но это, конечно же, может быть и удаленный репозиторий Git.
Это все, что есть для сервера. Позволяет настроить клиентское приложение дальше.
Настройте обслуживание клиентов
Чтобы настроить клиентский проект, я создал новый подкаталог и поместил в него другой проект Spring Boot «по умолчанию» со следующей компоновкой:
|
1
2
3
4
5
6
7
8
|
├── pom.xml└── src └── main ├── java │ └── hello │ └── ConfigClientApplication.java └── resources └── bootstrap.properties |
Как видите, этот проект так же прост, как и другой. Он содержит pom, один файл Java и файл свойств. Давайте пройдемся по каждому из них.
«Pom.xml» содержит следующее:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<?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" <modelVersion>4.0.0</modelVersion> <groupId>net.pascalalma.cloud</groupId> <artifactId>configuration-client</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Camden.SR5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project> |
Далее идет файл Java. На самом деле он содержит два класса: приложение для запуска Spring Boot и контроллер, обрабатывающий входящие HTTP-запросы. Файл выглядит так:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
package net.pascalalma.cloud.client;import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.context.config.annotation.RefreshScope;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@SpringBootApplicationpublic class ConfigClientApplication { public static void main(String[] args) { SpringApplication.run(ConfigClientApplication.class, args); }}@RefreshScope@RestControllerclass MessageRestController { @Value("${message:Hello default}") private String message; @RequestMapping("/message") String getMessage() { return this.message; }} |
RefreshScope добавлен, чтобы иметь возможность перезагрузить свойства, когда я изменю их позже в нашем тесте.
Последний файл — это «bootstrap.properties». Этот файл используется приложением Spring Boot CLient при запуске приложения для загрузки удаленного файла «application.properties» до его запуска. Файл содержит следующее:
|
1
2
|
spring.application.name=a-bootiful-clientspring.cloud.config.uri=http://localhost:8888 |
Тоже не очень сложно, я думаю. Содержит название клиентского приложения. Это имя используется для выбора правильного файла свойств в службе конфигурации. Вторая строка содержит местоположение сервера конфигурации облака. Вы можете прочитать больше об этом здесь .
Протестируйте настройку
Теперь, когда весь код установлен, я могу проверить, работает ли он. Я открываю три терминальных сессии.
Первым я перехожу в каталог ‘configuration-server’ и выполняю ‘ mvn spring-boot:run ‘, чтобы запустить сервер конфигурации.
Во втором я перехожу в каталог ‘ mvn spring-boot:run -client’ и выполняю ‘ mvn spring-boot:run ‘, чтобы запустить клиент конфигурации.
Третий, который я использую, чтобы позвонить клиенту, чтобы проверить сервер конфигурации. Когда я выполняю команду « curl localhost:8000/message », я ожидаю получить возвращенное сообщение, которое я положил в configstore на первом шаге:
|
1
2
|
$ curl localhost:8000/messageHello World! |
Теперь, когда я внесу изменение в хранилище конфигурации, оно не будет автоматически отражено в клиенте. Я редактирую файл «a-bootiful-client.properties» и обновляю сообщение так:
message = Hello World from Spring Boot!\n\n . И, конечно, зафиксируйте файл в хранилище с помощью ‘ git commit -a -m 'updated message' ‘
Когда я выполняю ту же команду curl в клиентском приложении, никаких изменений не произойдет. Если я закручиваю сообщение прямо на сервере конфигурации, я вижу изменение:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
$ curl localhost:8888/a-bootiful-client/default{"name":"a-bootiful-client","profiles":"default"],"label":"master","version":"98c6f8d8dd9a9b2cb36496ca4ac54ffb35806dbc","state":null,"propertySources":[ {"name":"/Users/pascalalma/projects/sandbox/spring-config-example/configstore/a-bootiful-client.properties" ,"source":{"server.port":"8000" ,"management.security.enabled":"false" ,"message":"Hello World from Spring Boot!\n\n"} } ]} |
Чтобы получить это измененное значение с сервера конфигурации на клиент, мне нужно обновить клиент с помощью следующей команды:
'curl -X POST http://localhost:8000/refresh ' . Если я сейчас сверну клиента, то увижу ожидаемое обновленное сообщение:
|
1
2
|
$ curl localhost:8000/messageHello World from Spring Boot! |
Возможно, вы заметили, что свойство ‘management.security.enabled’ установлено в false в ‘application.properties’ для этой демонстрации. Это было сделано для того, чтобы это было легко протестировать (по умолчанию начиная с Spring Boot 1.5 конечные точки привода по умолчанию защищены)
Функциональность, показанная в этом посте, на самом деле является лишь вершиной айсберга Возможно гораздо больше, в сочетании с другими инструментами, такими как Spring Cloud Consul и Spring Cloud Bus , но также и со стандартными функциями Spring, такими как безопасность и профили . Этого поста должно быть достаточно, чтобы вы сами начали его проверять.
| Ссылка: | Используйте Spring Cloud Config в качестве внешней конфигурации от нашего партнера JCG Паскаля Альмы в блоге Pragmatic Integrator . |