使用Spring Boot和Spring Cloud构建和打包微服务架构(三)

抽丝剥茧,细说架构那些事——【优锐课】

使用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

下篇再会~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值