Spring boot 與 Docker-compose構建微服務應用

memr4964 8年前發布 | 43K 次閱讀 MongoDB Compose 微服務 Spring Boot

Spring boot 與 Docker-compose構建微服務應用

前兩天看了一篇文章,講的是使用docker-compose將spring boot應用和mongodb應用一起構建,實現容器之間的相互通信,spring boot應用能夠直接將數據存儲到容器之中,但是那篇博客中在已有docker-compose.yml文件可以直接使用docker-compose進行build的時候,使用docker進行build,運行等等,并且其中各種過程并不詳細,感覺作者在這里沒有完全將docker-compose弄明白,因此我也寫一篇來介紹使用docker-compose實現管理兩個容器,并進行兩個容器之間通信。

docker compose

docker compose是從 fig 項目中而來, fig 可以說是 docker compose 前身,docker compose向下兼容fig,具體使用不再描述,有盡可能多的文章描述怎么安裝使用docker compose,但是在這里還是推薦閱讀官方的教程,以下就是:

若有不熟悉docker compose的可以閱讀以上教程。

spring boot需要的依賴

這個spring boot應用比較簡單,就是spring boot使用mongodb,將數據存儲在mongodb之中,其中操作mongodb的方法不是使用原生的mongodb提供的api,也不是使用spring boot提供的spring-data-mongodb來操作,而是使用morphia這一種mongodb orm框架來操作mongodb,使用morphia十分方便,具體用法在這里就不再詳述, google 一下有著足夠多的教程來教怎么使用morphia,以下就是個人的相關程序:

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0 ;
  <modelVersion>4.0.0</modelVersion>

<groupId>cn.com</groupId> <artifactId>SpringBootMongoDocker</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging>

<name>spring :: boot :: mongo :: docker</name> <url>http://maven.apache.org</url&gt;

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.1.RELEASE</version> </parent>

<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <start-class>cn.com.Application</start-class> </properties>

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>

<dependency>
  <groupId>org.mongodb.morphia</groupId>
  <artifactId>morphia</artifactId>
  <version>1.3.0</version>
</dependency>

</dependencies>

<repositories> <repository> <id>spring-snapshots</id> <url>http://repo.spring.io/snapshot</url&gt; <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <url>http://repo.spring.io/milestone</url&gt; <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>

<pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <url>http://repo.spring.io/snapshot</url&gt; </pluginRepository> <pluginRepository> <id>spring-milestones</id> <url>http://repo.spring.io/milestone</url&gt; </pluginRepository> </pluginRepositories>

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>cn.com.Application</mainClass> <layout>ZIP</layout> </configuration> <executions> <execution> <goals> <goal> repackage </goal> </goals> </execution> </executions> </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></code></pre>

在pom.xml中重要的依賴其實就是兩個,一個是:

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

這個支撐我們使用spring boot提供的spring web,ioc等等模塊,另外一個就是我們需要的mongodb的orm框架morphia依賴:

<dependency>
      <groupId>org.mongodb.morphia</groupId>
      <artifactId>morphia</artifactId>
      <version>1.3.0</version>
</dependency>

在這里我們并不需要單獨引入mongodb的驅動依賴,在引入morphia的時候,morphia會將mongodb的依賴一同引入進來。

spring boot程序

引入morphia后,mongo Bean的注入如下:

package cn.com.config;

import com.mongodb.Mongo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment;

import javax.annotation.PreDestroy; import java.net.UnknownHostException;

@Configuration @ConditionalOnClass(Mongo.class) @EnableConfigurationProperties(MongoProperties.class) public class MongoAutoConfiguration {

@Autowired
private MongoProperties properties;  

private Mongo mongo;  

@Autowired
private Environment environment;

@PreDestroy
public void close() {  
    if (this.mongo != null) {  
        this.mongo.close();  
    }  
}  

@Bean
@ConditionalOnMissingBean
public Mongo mongo() throws UnknownHostException {
    this.mongo = this.properties.createMongoClient(null, environment);
    return this.mongo;  
}  

}</code></pre>

在這里,我們需要單獨的mongo bean的注入,這里為下文中的Morphia配置提供了一些依賴:

morphia的配置:

package cn.com.config;

import com.mongodb.Mongo; import com.mongodb.MongoClient; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Morphia; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.mongo.MongoProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;

@Configuration @ConditionalOnClass(Mongo.class) public class MorphiaFactory {

@Autowired
private Mongo mongo;

@Autowired
MongoProperties mongoProperties;

@Bean
public Datastore get() {
    Morphia morphia = new Morphia();
    return morphia.createDatastore((MongoClient) mongo,mongoProperties.getDatabase());
}  

}</code></pre>

相當簡單,在此不作過多贅述。

其他程序模塊

在這里還需一個Application啟動類,一個controller,這些都是基本需要的,而且我也只是提供了一個十分簡單的功能,因此不再過多贅述,具體的可以到下面的源碼中去查看。

docker相關文件

使用docker-compose構建應用,需要以下幾個文件,當前應用的Dockerfile,docker-compose.yml,存儲容器的Dockerfile,但是在個人多次嘗試之后放棄了存儲鏡像的Dockerfile文件,直接將鏡像寫在docker-compose.yml之中,等會詳細講述:

當前應用的Dockerfile,因為在docker-compose.yml文件之中可以指定Dockerfile的名字,所以可以不一定完全Dockerfile命名,我在這里的命名為:

springapp.dockerfile:

FROM maven:3.3.3

ADD pom.xml /tmp/build/ RUN cd /tmp/build && mvn -q dependency:resolve

ADD src /tmp/build/src

    #構建應用

RUN cd /tmp/build && mvn -q -DskipTests=true package \

    #拷貝編譯結果到指定目錄
    && mv target/*.jar /app.jar \
    #清理編譯痕跡
    && cd / && rm -rf /tmp/build

VOLUME /tmp EXPOSE 8080 ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]</code></pre>

以maven3.3為基礎鏡像,將當前程序打入鏡像之中后,進行相關的編譯打包,移出打出來的jar文件,然后執行這個文件,在這里相應的編譯打包過程中,其實也要下載相當多的jar,我再前面的幾篇的博文中曾經提到想要直接將本地的jar打進鏡像之中,但在這里試了許多次,一直是失敗的,應該是某個步驟出了一定的問題,在未來嘗試成功后,還是要單獨寫一篇博文來講下如何進行操作,在我找到的很多其他文章中,其實都講過怎么實現,但是在本機上實驗就是失敗的,十分沮喪。

在這里面另外一個相當重要的文件就是docker-compose.yml,其中內容如下:

version : '2'
services:

springappserver: build: context: . dockerfile: springapp.dockerfile ports:

  - "8080:8080"
volumes:
  - .:/vol/development
links:
    - mongodb:mongodb

mongodb: image: daocloud.io/library/mongo:latest ports:

  - "27017:27017"

</code></pre>

在其中我們定義了兩個鏡像,一個是spring boot應用,一個是mongodb,然后springboot應用可以和mongodb之間進行通信。

在以上這些全部完成之后,就可以運行我們的docker應用了。

運行

在當前spring boot應用的根目錄下執行 docker-compose up -d ,其中如果不清楚docker-compose用法的可以看上面我給出的教程,里面有詳細講述, docker-compose up -d 執行完之后,會進行一系列的拉取鏡像,完成鏡像的操作,具體不再展示出來,在經過一系列漫長的過程后(主要就是在下載jar),容器基本就運行起來了,使用 docker ps 觀察當前運行起來的容器,具體如下:

可以看到有兩個容器正處于運行之中,現在查看一下springboot這個容器的運行情況,使用 docker logs 來進行查看,如下:

可以看到springboot應用已經成功啟動起來。

在這里需要說明一下,為什么不需要檢查mongodb容器是否處于正常狀態,因為在我們再springboot應用中配置了mongodb后,并注入了bean,那么在springboot應用啟動的時候會去檢查mongodb是否可以正常連接上,如果springboot這里就拒絕連接了,在本身的配置文件沒有出錯的情況下,多半就是mongodb容器的運行不正常。

測試

我們在這里使用postman進行相應請求的發送,postman是chrome中的一款進行http操作的插件,進行http請求的發送十分方便,在這里也可以使用linux系統中的curl來進行操作,如果是使用curl的話,輸入以下即可:

curl -l -H "Content-type: application/json" -X POST -d '{ "username": "xiaxuan","mobile": "135xxxxxxxx","password": "123456"}' http://192.168.99.100:8080/add

使用postman的話,就是如下圖所示:

上半部分是請求參數,下半部分書返回結果,這個時候,已經得到spring boot應用的正常響應,說明運行一切正常,這個時候我們在連接上mongodb看看響應的數據是否已經保存進mongodb容器之中,如下圖所示:

可以看到mongodb之中有兩條記錄,mongodb容器之中也正常保存數據。

綜上

  • 在使用docker-compose將多個容器之間關聯起來的時候,管理、運行便相當方便,啟動、關閉容器都可使用一條命令來完成,docker-compose因此也是docker徹底火起來的一個很大的原因之一。

  • 在這里有多點需要改善,有一個點就是之前提過許多次的,spring boot應用的jar可以在本地打成jar之后直接打進鏡像之中,這樣運行起來就會十分迅速,不需要額外花費許多時間來下載jar。

 

 

 本文由用戶 memr4964 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!