抽丝剥茧,细说架构那些事——【优锐课】
使用Spring Boot和Spring Cloud构建和打包微服务架构(一)
使用Spring Boot和Spring Cloud构建和打包微服务架构(二)
使用Docker打包Spring应用程序
Docker是一项了不起的技术,它允许创建类似于虚拟机的系统映像,但是共享与主机操作系统相同的内核。此功能可以提高系统性能和启动时间。此外,Docker提供了一个精巧的内置系统,该系统可确保一旦创建映像就可以;它永远不会改变。换句话说:不再有“它可以在我的机器上工作!”
提示:需要更深入的Docker背景吗?看看《 Docker开发人员指南》。
您需要为每个项目创建一个Docker映像。每个映像在每个项目的根文件夹中应具有相同的Maven配置和Dockerfile内容(e.g.school-ui/Dockerfile)。
在每个项目的pom中,添加dockerfile-maven-plugin:
<plugins>
...
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>1.4.9</version>
<executions>
<execution>
<id>default</id>
<goals>
<goal>build</goal>
<goal>push</goal>
</goals>
</execution>
</executions>
<configuration>
<repository>developer.okta.com/microservice-docker-${project.artifactId}</repository>
<tag>${project.version}</tag>
<buildArgs>
<JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
</buildArgs>
</configuration>
</plugin>
</plugins>
每次运行./mvnw install时,此XML都会配置Dockerfile Maven插件以构建Docker映像。将使用名称developer.okta.com/microservice-docker-${project.artifactId}创建每个图像,其中project.artifactId因项目而异。
在每个项目的根目录中创建一个Dockerfile文件。
FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/*.jar app.jar
ENV JAVA_OPTS="
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]
Dockerfile遵循Spring Boot对Docker的建议。
现在,更改school-ui/src/main/resources/bootstrap.yml以添加新的failFast设置:
eureka:
client:
serviceUrl:
defaultZone: ${EUREKA_SERVER:http://localhost:8761/eureka}
spring:
application:
name: school-ui
cloud:
config:
discovery:
enabled: true
serviceId: CONFIGSERVER
failFast: true
spring.cloud.failFast: true设置指示Spring Cloud Config在找不到配置服务器时立即终止应用程序。这将对下一步很有用。
添加Docker Compose以运行所有内容
创建一个名为docker-compose.yml的新文件,该文件定义每个项目的启动方式:
version: '3'
services:
discovery:
image: developer.okta.com/microservice-docker-discovery:0.0.1-SNAPSHOT
ports:
- 8761:8761
config:
image: developer.okta.com/microservice-docker-config:0.0.1-SNAPSHOT
volumes:
- ./config-data:/var/config-data
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://discovery:8761/eureka
-Dspring.cloud.config.server.native.searchLocations=/var/config-data
depends_on:
- discovery
ports:
- 8888:8888
school-service:
image: developer.okta.com/microservice-docker-school-service:0.0.1-SNAPSHOT
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://discovery:8761/eureka
depends_on:
- discovery
- config
school-ui:
image: developer.okta.com/microservice-docker-school-ui:0.0.1-SNAPSHOT
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://discovery:8761/eureka
restart: on-failure
depends_on:
- discovery
- config
ports:
- 8080:8080
如您所见,每个项目现在都是Docker中声明的服务,用于组成文件。 它将暴露其端口和其他一些属性。
• 除了发现外,所有项目都将具有变量值—DEUREKA_SERVER=http://discovery:8761/eureka。这将告诉您在哪里可以找到发现服务器。Docker Compose在服务之间创建了一个虚拟网络,每个服务使用的DNS名称就是其名称:这就是为什么可以将发现用作主机名的原因。
**• Config服务将具有用于配置文件的卷。**该卷将映射到docker容器内的/var/config-data。同样,属性spring.cloud.config.server.native.searchLocations将被覆盖为相同的值。您必须将文件school-ui.properties存储在卷映射上指定的同一文件夹中(在上面的示例中,相对文件夹. /config-data)。
**• school-ui 项目将具有restart: on-failure.。**这将Docker Compose设置为在应用程序失败后立即重新启动。与failFast属性一起使用可以使应用程序继续尝试启动,直到Discovery和Config项目完全准备好为止。
就是这样! 现在,构建图像:
cd config && ./mvnw clean install
cd ../discovery && ./mvnw clean install
cd .. && ./mvnw clean install
在school-ui project中,最后一个命令可能会失败,并显示以下错误:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: java.lang.IllegalStateException: No instances found of configserver (CONFIGSERVER)
要解决此问题,请创建一个school-ui/src/test/resources/test.properties文件并添加属性,以便Okta的配置通过,并且在测试时不使用发现或配置服务器。
okta.oauth2.issuer=https://okta.okta.com/oauth2/default
okta.oauth2.clientId=TEST
spring.cloud.discovery.enabled=false
spring.cloud.config.discovery.enabled = false
spring.cloud.config.enabled = false
然后,修改UIWebApplicationTests.java 以加载此文件的测试属性:
import org.springframework.test.context.TestPropertySource;
...
@TestPropertySource(locations="classpath:test.properties")
public class UIWebApplicationTests {
...
}
现在,您应该能够在school-ui 项目中运行/mvnw clean install 。
完成后,运行Docker Compose以启动所有容器(在docker-compose.ymlis所在的目录中)。
docker-compose up -d
Starting okta-microservice-docker-post-final_discovery_1 ... done
Starting okta-microservice-docker-post-final_config_1 ... done
Starting okta-microservice-docker-post-final_school-ui_1 ... done
Starting okta-microservice-docker-post-final_school-service_1 ... done
现在,您应该能够像以前一样浏览该应用程序。
使用Spring配置文件修改微服务的配置
现在,您已经到达了微服务之旅的最后阶段。Spring Profiles是一个功能强大的工具。使用配置文件,可以通过完全注入不同的依赖项或配置来修改程序行为。
假设您有一个结构良好的软件,其持久层与业务逻辑分离。例如,您还提供对MySQL和PostgreSQL的支持。每个数据库可能有不同的数据访问类,这些数据访问类仅由定义的概要文件加载。
另一个用例是配置:不同的配置文件可能具有不同的配置。以身份验证为例。 您的测试环境会进行身份验证吗?如果是这样,则不应使用与生产相同的用户目录。
将您的配置项目更改为在Okta中有两个应用程序:一个默认(用于开发),另一个用于生产。在Okta网站上创建一个新的Web应用程序,并将其命名为“okta-docker-production”。
现在,在您的配置项目中,创建一个名为chool-ui-production.properties的新文件。您已经有了school-ui.properties,每个School UI实例都将使用它。在文件末尾添加环境时,Spring将合并两个文件,并优先于最特定的文件。使用生产应用的客户ID和密码保存文件,如下所示:
school-ui-production.properties
okta.oauth2.clientId={YOUR_PRODUCTION_CLIENT_ID}
okta.oauth2.clientSecret={YOUR_PRODUCTION_CLIENT_SECRET}
现在,使用Maven运行配置项目,然后运行以下两个curl命令:
./mvnw spring-boot:run
> curl http://localhost:8888/school-ui.properties
okta.oauth2.issuer: https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId: ==YOUR DEV CLIENT ID HERE==
okta.oauth2.clientSecret: ==YOUR DEV CLIENT SECRET HERE==
> curl http://localhost:8888/school-ui-production.properties
okta.oauth2.issuer: https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId: ==YOUR PROD CLIENT ID HERE==
okta.oauth2.clientSecret: ==YOUR PROD CLIENT SECRET HERE==
如您所见,即使文件school-ui-production具有两个属性,配置项目也会显示三个属性(因为配置已合并)。
现在,您可以在docker-compose.yml中将school-ui服务更改为使用生产配置文件:
school-ui:
image: developer.okta.com/microservice-docker-school-ui:0.0.1-SNAPSHOT
environment:
- JAVA_OPTS=
-DEUREKA_SERVER=http://discovery:8761/eureka
-Dspring.profiles.active=production
restart: on-failure
depends_on:
- discovery
- config
ports:
- 8080:8080
您还需要将school-ui-production.properties复制到您的config-data目录中。然后,关闭所有Docker容器并重新启动它们。
docker-compose down
docker-compose up -d
您应该在school-ui容器的日志中看到以下内容:
The following profiles are active: production
现在,您可以在生产配置文件中运行微服务架构。Huzzah!
感谢你的阅读!
欢迎进群交流:Java学习资料交流qq群:907135806
有想要JVM、Mysql、Tomcat、Spring Boot、Spring Cloud、Zookeeper、Kafka、RabbitMQ、RockerMQ、Redis、ELK、Git等Java学习资料和视频课程的童鞋也可以加vx:ddmsiqi
下篇再会~