您的位置:首页 > 运维架构 > Docker

Spring boot 与 Docker-compose构建微服务应用

2016-12-19 09:52 1026 查看

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 教程

若有不熟悉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" 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>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>

<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>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<url>http://repo.spring.io/snapshot</url>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<url>http://repo.spring.io/milestone</url>
</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>


在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;
}

}


在这里,我们需要单独的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());
}
}


相当简单,在此不作过多赘述。

其他程序模块

在这里还需一个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"]


以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"


在其中我们定义了两个镜像,一个是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。

源码下载地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: