现现在咱们常常在讨论服务端开发(主要是API服务)的时候谈及“微服务”。微服务设计方法逐渐成为了API开发的新业界标准。几乎全部的组织都在推广它。java
在这篇教程当中,咱们将探讨而且完成一个叫作配置服务(Config Server)的微服务特性。全部微服务的可配置参数都在配置服务中写入和维护。它更像是将属性/资源文件从项目的代码中统一抽离到一个外部服务,这样的话若是某个属性发生了改变,那么使用它的服务并不须要从新部署。在不从新部署微服务的状况下,全部的属性改变将能够体现出来。git
配置服务器的想法来自于12-factor app宣言。这份宣言与开发现代原生云应用的最佳实践指导相关。它建议将属性/资源保存在服务器的环境当中。在这个环境里,这些资源会在服务运行的时候发生变化——不一样的配置一般在每一个环境当中有所不一样。web
举个例子,若是一个服务依赖与另外一个服务(因为特定业务场景被调用),而且被依赖的服务的URL发生了改变,那么咱们必须用新的地址构建和部署咱们的服务。可是若是咱们如今运用了12 factor app方法,而且从一个运行在不一样进程里的外部服务读取配置,咱们就只须要刷新配置服务了。spring
因此,这个想法很是清晰以及有效。如今让咱们来看看如何建立配置服务器。shell
咱们将使用基于spring-boot的spring-cloud API,它很是易于使用和流行。在spring framework的命名中,它被称做Config Server。同时咱们也会经过git来托管属性文件。数据库
因此咱们最终用于这个demo的技术栈是:bootstrap
咱们首先将开发2个基于spring boot的微服务。windows
首先咱们经过给定的步骤构建配置服务器部分。浏览器
从spring boot初始化程序门户开始,这是建立任何基于Spring Boot的应用的一个特别好的起点。在这里咱们只会选用Config Server starter pom。经过使用此配置,只要咱们生成项目,就能够下载一个zip文件,而后解压缩后导入eclipse。 安全
一旦你从spring初始化器门户得到了zip文件,咱们须要将它解压缩到咱们选择的目录并将其做为maven项目导入eclipse
下一步是选择你喜欢的方式,从命令提示符或eclipse运行mvn clean install。
如今打开spring已经提供的Spring Application类,并在类以前添加@EnableConfigServer注解并再次构建项目。在使用这个注解以后,这个artifact将会表现得像一个spring配置服务器。
此类被添加这个注解以后看起来会像下面那样——类名由你生成的项目名决定,固然你也能够手动更改一个你喜欢的名称。
package com.howtodoinjava.example.springconfigserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class SpringConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringConfigServerApplication.class, args);
}
}
复制代码
下一个很是重要的步骤是创建一个本地git仓库。它能够很轻松地经过在属性文件里配置URL被替换成远程仓库。咱们将放置被配置服务器微服务
使用的外部属性文件来提供外部属性配置。咱们须要跟着下面的步骤来建立一个本地git仓库而且检查样例属性文件。
首先请确保在你的机器上已经安装了git shell,并且你能够经过命令行运行git bash。能够经过打开命令行,输入git命令来确认。
在桌面建立一个目录config-server-repo。
而后在config-server-repo目录中建立一个文件config-server-client.properties
,并在文件中添加内容msg = Hello world - this is from config server
。
而后在config-server-repo目录中建立一个文件config-server-client-development.properties
,并在文件中添加内容msg = Hello world - this is from config server - development environment
。
而后在config-server-repo目录中建立一个文件config-server-client-production.properties
,并在文件中添加内容msg = Hello world - this is from config server - production environment
。
在这里咱们为不一样的环境维护了一样名称的配置,由于咱们一般维护不一样环境的属性,如urls,credentials,数据库详细信息等。最重要的一点是咱们须要在每一个属性文件中附加带有环境名称的连字符( - ),以便配置服务器理解它。此外,咱们须要使用咱们将在此以后建立的配置客户端服务名称命名属性文件。
如今从config-server-repo目录打开命令提示符并运行命令git init,使该目录成为git存储库。
运行git add。将全部内容添加到仓库中。
最后咱们须要经过运行命令git commit -m“initial checkin”来提交属性文件。下面是所有命令操做的截图(译者注:你也能够用git bash操做。原做者使用的是windows命令行)。
在spring-config-sever项目的src\main\resources
目录中建立一个名为bootstrap.properties
的文件,并添加如下行。
#服务器端
server.port = 8888
#Git 仓库地址。能够替换成你本地git仓库的绝对路径
spring.cloud.config.server.git.uri=${USERPROFILE}\\Desktop\\config-server-repo
#关闭Management endpoint的安全检验
management.security.enabled=false
#译者注,在springboot的2.x版本当中,
#management.security.enabled已经被废弃。
#应该该成如下配置,才能够访问刷新配置的url /actuator/refresh
#management.endpoints.web.exposure.include=refresh
复制代码
如今让咱们了解这些属性。
server.port
定义嵌入式服务器将启动的端口spring.cloud.config.server.git.uri
将绑定git位置以查找配置。这里咱们使用本地git仓库,但只需更改此配置便可切换到远程仓库。management.security.enabled = false
将禁用/env,/refresh等上management endpoint的安全性。这是针对开发设置的,在生产环境当中应该启用安全性。为了确认服务器是否能够识别这些属性,咱们首先在项目根目录运行如下命令:
java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar
复制代码
如今打开浏览器并检查下面的Urls,它将返回JSON输出。在propertySources
部分,咱们能够看到咱们在属性文件中添加的全部属性内容。这确保配置服务器成功运行,它已识别git的位置,而且正在为不一样环境提供配置。
此外,咱们来看看在项目运行的时候,对属性文件中的任何更改是否在服务器没有从新启动的状况下生效——修改环境属性文件当中的值,将它提交到git仓库,而后经过查看对应环境的endponit(浏览器打开对应的url)来检查配置是否在服务没有重启的状况下生效——这就是配置服务器的魔法。
如今咱们将继续进行客户端实现。咱们将从一个单独的微服务中获取属性。这是咱们的最终目标 - 将配置外部化到不一样的服务。
打开https://start.spring.io/,并使用如下选定的依赖生成客户端项目:
屏幕将以下所示。像Spring-Config-Server同样,将生成的zip文件解压缩到某个目录并导入eclipse。
首先添加一个RestController以查看响应中的服务器端属性值。为此,打开已生成的@SpringBootApplication类文件,并在该文件的末尾添加一个该类。这很是简单和直接,咱们仅仅只是在/message上暴露一个方法,用它返回由配置服务器微服务提供的msg属性值。该配置服务器指向本地git仓库(在生产环境它将会被替换为一个远程git仓库)。
package com.howtodoinjava.example.springconfigclient;
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;
@SpringBootApplication
public class SpringConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringConfigClientApplication.class, args);
}
}
@RefreshScope
@RestController
class MessageRestController {
@Value("${msg:Hello world - Config Server is not working..pelase check}")
private String msg;
@RequestMapping("/msg")
String getMsg() {
return this.msg;
}
}
复制代码
在src\main\resources目录中建立一个名为bootstrap.properties的文件,并添加如下属性以及一些必需的配置与配置服务器链接。
spring.application.name=config-server-client
#Active Profile配置与环境有关。
#若是它为空,则配置服务器将会使用末尾没有环境变量的配置文件
#如 config-server-client.properties
spring.profiles.active=development
spring.cloud.config.uri=http://localhost:8888
management.security.enabled=false
复制代码
上述主要的配置与配置服务器的配置意义一致。
让咱们来测试配置服务器应用。
从spring-config-server文件夹打开命令行工具并运行mvn clean install命令。在构建完成以后,运行java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar
配置服务器将会在本地的8888端口启动。
一样的, 从spring-config-clienet文件夹打开命令行工具并运行mvn clean install命令。在构建完成以后,运行java -jar target\spring-config-client-0.0.1-SNAPSHOT.jar
配置服务器将会在本地的8080端口启动。
如今打开浏览器,经过访问http://localhost:8080/msg
打开/msg
的rest endpoinit。它将会返回Hello world - this is from config server - Development environment
。它以前出如今config-server-client-development.properties
文件当中。
如今咱们将进行属性更改并测试是否能够在配置客户端服务中反映,而无需从新启动任何微服务。
对config-server-client-development.properties
中的msg
值进行更改而后提交到本地git,接着在浏览器中再次点击http//localhost:8080/msg
,你将仅仅获得旧值。
要得到新值,咱们须要经过从任意REST
客户端使用POST
方法访问http://localhost:8080/refresh
端点来刷新配置。
一旦配置客户端服务被成功刷新后,新值就应该会出如今服务响应体中。这是由于Rest Controller暴露的@RefreshScope注解。
spring.application.name=config-server-client
须要保持一致,不然属性将没法被检测到。git add/commit
命令来提交代码到git仓库。POST
方法访问http://localhost:8080/refresh
来刷新配置客户端服务。这就是建立配置服务器微服务的所有了。若是你有遇到任何的困难请在这篇文章的评论当中提出,咱们会很高兴帮助你解决这些问题。
Happy Learning !!