spring boot教程,docker springboot讀取配置文件_Docker從入門到掉坑(三):容器太多,操作好麻煩

 2023-10-05 阅读 31 评论 0

摘要:前邊的兩篇文章里面,我們講解了基于docker來部署基礎的SpringBoot容器,如果閱讀本文之前沒有相關基礎的話,可以回看之前的教程。Docker 從入門到掉坑?mp.weixin.qq.comDocker從入門到掉坑(二):基于Docker構建SpringBoot微服務?mp.weixin.qq.comsp

872fc834a91cfd782502ce9cfabe5f14.png

前邊的兩篇文章里面,我們講解了基于docker來部署基礎的SpringBoot容器,如果閱讀本文之前沒有相關基礎的話,可以回看之前的教程。

Docker 從入門到掉坑?mp.weixin.qq.com
72616835c6901bb1169cdcac6682b531.png
Docker從入門到掉坑(二):基于Docker構建SpringBoot微服務?mp.weixin.qq.com
72616835c6901bb1169cdcac6682b531.png

spring boot教程?不知道大家在初次使用docker的時候是否有遇到這種場景,每次部署微服務都是需要執行docker run xxx,docker kill xxx 等命令來操作容器。假設說一個系統中依賴了多個docker容器,那么對于每個docker容器的部署豈不是都需要手動編寫命令來啟動和關閉,這樣做就會增加運維人員的開發工作量,同時也容易出錯。

Docker Compose 編排技術

在前邊的文章中,我們講解了Docker容器化技術的發展,但是隨著我們的Docker越來越多的時候,對于容器的管理也是特別麻煩,因此Docker Compose技術也就誕生了。

docker環境變量讀取?Docker Compose技術是通過一份文件來定義和運行一系列復雜應用的Docker工具,通過Docker-compose文件來啟動多個容器,網上有很多關于Docker-compose的實戰案例,但是都會有些細節地方有所遺漏,所以下邊我將通過一個簡單的案例一步步地帶各位從淺入深地對Docker-compose進行學習。

基于Docker Compose來進行對SpringBoot微服務應用的打包集成

我們還是按照老樣子來構建一套基礎的SpringBoot微服務項目,首先我們來看看基礎版本的項目結構:

docker 進入容器。

346618c93e872715d150ee4134ac5440.png


首先是我們pom文件的配置內容:

<?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"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.sise.idea</groupId><artifactId>springboot-docker</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>spring-boot-docker</name><url>http://maven.apache.org</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.3.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version></dependency></dependencies><build><finalName>springboot-docker</finalName><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

然后是java程序的內容代碼,這里面有常規的controller,application類,代碼如下所示:

springboot解析配置文件,啟動類Application

package com.sise.docker;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** @author idea* @data 2019/11/20*/
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class);}
}

控制器 DockerController

package com.sise.docker.controller;import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** @author idea* @data 2019/11/20*/
@RestController
@RequestMapping(value = "/docker")
public class DockerController {@GetMapping(value = "/test")public String test(){System.out.println("=========docker test=========");return "this is docker test";}
}

yml配置文件:

server:port: 7089

docker dockerfile。接下來便是docker-compose打包時候要用到的配置文件了。這里采用的方式通常都是針對必要的docker容器編寫一份dockerfile,然后統一由Docker Compose進行打包管理,假設我們的微服務中需要引用到了MySQL,MongoDB等應用,那么整體架構如下圖所示:

b583135a810d909c64a97203b73246e6.png


那么我們先從簡單的單個容器入手,看看該如何對SpringBoot做Docker Compose的管理,下邊是一份打包SpringBoot進入Docker容器的Dockerfile文件:

#需要依賴的其他鏡像
FROM openjdk:8-jdk-alpine
# Spring Boot應用程序為Tomcat創建的默認工作目錄。作用是在你的主機”/var/lib/docker”目錄下創建一個臨時的文件,并且鏈接到容器中#的”/tmp”目錄。
VOLUME /tmp#是指將原先的src文件 添加到我們需要打包的鏡像里面
ADD target/springboot-docker.jar app.jar#設置鏡像的時區,避免出現8小時的誤差
ENV TZ=Asia/Shanghai#容器暴露的端口號 和SpringBoot的yml文件暴露的端口號要一致
EXPOSE 7089#輸入的啟動參數內容 下邊這段內容相當于運行了java -Xms256m -Xmx512m -jar app.jar 
ENTRYPOINT ["java","-Xms256m","-Xmx512m","-jar","app.jar"]

springboot屬性文件加載?接著便是加入docker-compose.yml文件的環節了,下邊是腳本的內容:

#docker引擎對應所支持的docker-compose文本格式
version: '3'
services:#服務的名稱springboot-docker:build:context: .# 構建這個容器時所需要使用的dockerfile文件dockerfile: springboot-dockerfileports:# docker容器和宿主機之間的端口映射- "7089:7089"

docker-compose.ym配置文件有著特殊的規則,通常我們都是先定義version版本號,然后便是列舉一系列與容器相關的services內容。

接下來將這份docker服務進行打包,部署到相關的linux服務器上邊,這里我采用的是一臺阿里云上邊購買的服務器來演示。

dfc6fd0c37d9de9ae8639a4592f13421.png


目前該文件還沒有進行打包處理,所以沒有target目錄,因此dockerfile文件構建的時候是不會成功的,因此需要先進行mvn的打包:

mvn package

接著便是進行Docker-Compose命令的輸入了:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker-compose up -d
Starting springboot-docker_springboot-docker_1 ... done
[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# 

你會發現這次輸入的命令和之前教程中提及的docker指令有些出入,變成了docker-compose 指令,這條指令是專門針對Docker compose文件所設計的,加入了一個-d的參數用于表示后臺運行該容器。由于我們的docker-compose文件中知識編寫了對于SpringBoot容器的打包,因此啟動的時候只會顯示一個docker容器。

為了驗證docker-compose指令是否生效,我們可以通過docker--compose ps命令來進行驗證。

這里邊我們使用 docker logs [容器id] 指令可以進入容器查看日志的打印情況:

docker logs ad83c82b014d

e53d16305a060ea43499d3c5d4b7dfcf.png


最后我們通過請求之前寫好的接口便會看到相關的響應:

b93eebaf4fa3c9ec871fb45def5a2a57.png


基礎版本的SpringBoot+Docker compose案例已經搭建好了,還記得我在開頭畫的那張圖片嗎:

b583135a810d909c64a97203b73246e6.png

通常在實際開發中,我們所面對的docker容器并不是那么的簡單,還有可能會依賴到多個容器,那么這個時候該如何來編寫docker compose文件呢?

下邊我們對原先的SpringBoot項目增加對于MySQLMongoDB的依賴,為了方便下邊的場景模擬,這里我們增加兩個實體類:

用戶類

package com.sise.docker.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author idea* @data 2019/11/23*/
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {private Integer id;private String username;
}

汽車類:

package com.sise.docker.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;/*** @author idea* @data 2019/11/23*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Car {@Idprivate Integer id;private String number;
}

增加對于mongodb,mysql的pom依賴內容

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.21</version></dependency>

編寫相關的dao層:

package com.sise.docker.dao;import com.sise.docker.domain.Car;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;/*** @author idea* @data 2019/11/23*/
@Repository
public interface CarDao extends MongoRepository<Car, Integer> {
}
package com.sise.docker.dao;import com.sise.docker.domain.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;import java.sql.ResultSet;
import java.sql.SQLException;/*** @author idea* @data 2019/11/23*/
@Repository
public class UserDao {@Autowiredprivate JdbcTemplate jdbcTemplate;public void insert() {String time = String.valueOf(System.currentTimeMillis());String sql = "insert into t_user (username) values ('idea-" + time + "')";jdbcTemplate.update(sql);System.out.println("==========執行插入語句==========");}class UserMapper implements RowMapper<User> {@Overridepublic User mapRow(ResultSet resultSet, int i) throws SQLException {User unitPO = new User();unitPO.setId(resultSet.getInt("id"));unitPO.setUsername(resultSet.getString("username"));return unitPO;}}
}

在控制器中添加相關的函數入口:

package com.sise.docker.controller;import com.sise.docker.dao.CarDao;
import com.sise.docker.dao.UserDao;
import com.sise.docker.domain.Car;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Random;/*** @author idea* @data 2019/11/20*/
@RestController
@RequestMapping(value = "/docker")
public class DockerController {@Autowiredprivate UserDao userDao;@Autowiredprivate CarDao carDao;@GetMapping(value = "/insert-mongodb")public String insertMongoDB() {Car car = new Car();car.setId(new Random().nextInt(15000000));String number = String.valueOf(System.currentTimeMillis());car.setNumber(number);carDao.save(car);return "this is insert-mongodb";}@GetMapping(value = "/insert-mysql")public String insertMySQL() {userDao.insert();return "this is insert-mysql";}@GetMapping(value = "/test2")public String test() {System.out.println("=========docker test222=========");return "this is docker test";}
}

對原先的docker-compose.yml文件添加相應的內容,主要是增加對于mongodb和mysql的依賴模塊,

#docker引擎對應所支持的docker-compose文本格式
version: '3'
services:#服務的名稱springboot-docker:container_name: docker-springbootbuild:context: .dockerfile: springboot-dockerfileports:- "7089:7089"depends_on:- mongodbmongodb:#容器的名稱container_name: docker-mongodbimage: daocloud.io/library/mongo:latestports:- "27017:27017"mysql:#鏡像的版本image: mysql:5.7container_name: docker-mysqlports:- 3309:3306environment:MYSQL_DATABASE: testMYSQL_ROOT_PASSWORD: rootMYSQL_ROOT_USER: rootMYSQL_ROOT_HOST: '%'

這里頭我嘗試將application.yml文件通過不同的profile來進行區分:

5ba1195073969d814dfe0677e6f9d147.png


應上篇文章中有讀者問到,不同環境不同配置的指定問題,這里有一種思路,springboot依舊保持原有的按照profile來識別不同環境的配置,具體打包之后讀取的配置,可以通過springboot-dockerfile這份文件的ENTRYPOINT 參數來指定,例如下邊這種格式:

FROM openjdk:8-jdk-alpineVOLUME /tmpADD target/springboot-docker.jar springboot-docker.jar#設置鏡像的時區,避免出現8小時的誤差
ENV TZ=Asia/ShanghaiEXPOSE 7089
#這里可以通過-D參數在對jar打包運行的時候指定需要讀取的配置問題
ENTRYPOINT ["java","-Xms256m","-Xmx512m","-Dspring.profiles.active=prod","-jar","springboot-docker.jar"]

最后便是我們的yml配置文件內容,由于配置類docker容器的依賴,所以這里面對于yml的寫法不再是通過ip來訪問相應的數據庫了,而是需要通過service-name的映射來達成目標。

application-prod.yml

server:port: 7089spring:data:mongodb:uri: mongodb://mongodb:27017database: testdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://mysql:3306/test?useUnicode=true&amp;characterEncoding=UTF-8username: rootpassword: root

當相關的代碼和文件都整理好了之后,將這份代碼發送到服務器上進行打包。

mvn package

接著我們便可以進行docker-compose的啟動了。

這里有個小坑需要注意一下,由于之前我們已經對單獨的springboot容器進行過打包了,所以在執行docker-compose up指令的時候會優先使用已有的容器,而不是重新創建容器。


這個時候需要先將原先的image鏡像進行手動刪除,再打包操作:

[root@izwz9ic9ggky8kub9x1ptuz springboot-docker]# docker images
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
springboot-docker                  latest              86f32bd9257f        4 hours ago         128MB
<none>                                               <none>              411616c3d7f7        2 days ago          679MB
<none>                                               <none>              77044e3ad9c2        2 days ago          679MB
<none>                                               <none>              5d9328dd1aca        2 days ago          679MB
springbootmongodocker_springappserver                latest              36237acf08e1        3 days ago          695MB

刪除鏡像的命令:

docker rmi 【鏡像id】

8555176784dd30c9bbb14a048e7f7bae.png


此時再重新進行docker-compose指令的打包操作即可:

docker-compose up

197eb822241aa71e7e37fab0e86dd2c6.png


啟動之后,可以通過docker-compose自帶的一些指令來進行操作,常用的一些指令我都歸納在了下邊:

docker-compose [Command]

Commands:build              構建或重建服務bundle             從compose配置文件中產生一個docker綁定config             驗證并查看compose配置文件create             創建服務down               停止并移除容器、網絡、鏡像和數據卷events             從容器中接收實時的事件exec               在一個運行中的容器上執行一個命令help               獲取命令的幫助信息images             列出所有鏡像kill               通過發送SIGKILL信號來停止指定服務的容器logs               從容器中查看服務日志輸出pause              暫停服務port               打印綁定的公共端口ps                 列出所有運行中的容器pull               拉取并下載指定服務鏡像push               Push service imagesrestart            重啟YAML文件中定義的服務rm                 刪除指定已經停止服務的容器run                在一個服務上執行一條命令scale              設置指定服務運行容器的個數start              在容器中啟動指定服務stop               停止已運行的服務top                顯示各個服務容器內運行的進程unpause            恢復容器服務up                 創建并啟動容器version            顯示Docker-Compose版本信息

最后對相應的接口做檢測:

3d97c64b46d7ea1b76f8c6e79bd57e6c.png

c3aecd97d7140bafe5175fbde413aacc.png


相關的完整代碼我已經上傳到了gitee地址,如果有需要的朋友可以前往進行下載。

代碼地址:https://gitee.com/IdeaHome_admin/wfw

370f8da06870bbfd5515c6d1b5a8db05.png


實踐完畢之后,你可能會覺得有了docker-compose之后,對于多個docker容器來進行管理顯得就特別輕松了。

但是往往現實中并沒有這么簡單,docker-compose存在著一個弊端,那就是不能做跨機器之間的docker容器進行管理

因此隨者技術的發展,后邊也慢慢出現了一種叫做Kubernetes的技術。Kubernetes(俗稱k8s)是一個開源的,用于管理云平臺中多個主機上的容器化的應用,Kubernetes的目標是讓部署容器化的應用簡單并且高效(powerful),Kubernetes提供了應用部署,規劃,更新,維護的一種機制。

Kubernetes這類技術對于小白來說入門的難度較高,后邊可能會抽空專門來寫一篇適合小白閱讀的k8s入門文章。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/115471.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息