Spring Boot与Docker(三):构建你的第一个微服务和相关容器以及容器的连接

本文讲的是Spring Boot与Docker(三):构建你的第一个微服务和相关容器以及容器的连接,【编者的话】本篇是《使用Spring Boot和Docker构建微服务架构》系列的第三篇,本篇我们将会准备开始构建一个员工对象微服务。原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务、B2B集成、空间分析、SOA架构、大数据以及云计算等领域的软件产品架构经验,他是AWS认证解决方案架构师,在3Pillar之前先后就职于Oracle、ChoicePoint和Booz Allen Hamilton。Dan毕业于乔治·华盛顿大学,他也是一个父亲、业余木工爱好者,还参加过包括国际障碍大赛这样的障碍赛跑。

本篇构建微服务的步骤如下:

  • 建立一个新的Spring Boot工程
  • 定义我们的员工对象
  • 持久连接
  • 公开Web服务
  • 定义一个Docker容器来运行我们的微服务,包括连接到我们在第二篇中创建的Mongo容器
  • 在稍早设置的Docker Machine中运行我们的容器

建立我们的Spring Boot工程
我们将在我们的工程根目录下创建一个文件夹(生产环境中是在一个单独的版本库中)来承载我们的服务,在这个文件夹中,我们将创建build.grade文件。Spring Boot的优势就是在于对于依赖定义非常纯粹,如魔法般地带来了大量的互操作性。我们的build.grade文件看起来如下:

buildscript {
repositories {
jcenter()
}
dependencies { 
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.2.0.RELEASE'
}
}
apply plugin: 'spring-boot'

repositories { jcenter()
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-web"
}

现在,正如我们提到的,我们将使用IDE,具体地说就是Spring Tool Suite(STS),所以我们将增加对于Gradle的支持。首先,打开STS,接着在打开的Dashboard页面上点击“IDE Extensions”的链接:

在屏幕上选择“Grade Support”,点击“Install”,按照提示完成安装,其中包括重启STS:

重启之后,选择“Import project…”,接着选择Gradle project(现在可用了),指向你的目录,然后点击“Build Model”——这将会用“Employee”来产生项目列表——选择这个列表并且点击“Finish”,这将会导入一个简单的build.grade到我们启动的工程。一旦工程被导入之后,第一个将是Spring Boot配置类,在这个场景中,我们将按照他们的服务来命名,所以在这种情况下配置类将会命名为EmployeeBoot。Spring大量使用了注解和反射,所以最小的配置也是需要的(忽略导入):

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class EmployeeBoot {

   public static void main(String[] args) {
        SpringApplication.run(EmployeeBoot.class);
    }
}

我们的Employee类
接下来,我们将使得我们的POJO类来持有员工信息,我们目前保持最少的字段,有必要的话我们将增加:
Employee.Class

@Document(collection=”employees”)
public class Employee {

@Id
private String id; 

private String email;
private String fullName;
private String managerEmail;

// getters and setters omitted for brevity
}

注意@Document这个注解——这会将这个对象连结为一个Mongo文档,并为该Employee“文档”在哪里存储指定了集合名字。
接下来我们将定义一个Spring持久类来读取这些Employee:
EmployeeRepository.class:

public interface EmployeeRepository extends
MongoRepository<Employee, String> {
}

Spring框架的一个优美之处就是在于所有你需要写的——比如扩展自MongoRepository的接口甚至不需要手动编写实现代码。两个通用的参数中第一个表示需要持久化的对象类型(Employee),第二个表示唯一的标识符类型(String类型)。Spring框架将会自动提供所声明的功能95%的实现。接下来的问题就是:Spring如何知道数据库的位置?Spring默认情况下将会寻找localhost:27017,这显然是不会工作的,所以我们需要直接设置位置新型。我们可以实现自己的Mongo模板Bean,但是幸运的是Spring允许我们通过Java属性表传递连接信息。我们可以定义一个属性文件或者在命令行上传递进来。我们选择了后者因为当稍后构建我们的容器时命令行方式非常方便。最后我们需要创建的是一个或者两个Rest端点并确保它们可以工作。我们将构建一个快速的Spring Controller,然后我们就可以测试了。
EmployeeController.java

@RestController
@RequestMapping("/employee")
public class EmployeeController {

@Autowired
EmployeeRepository employeeRepository;

@RequestMapping(method = RequestMethod.POST)
public Employee create(@RequestBody Employee employee){

    Employee result = employeeRepository.save(employee);
    return result;
}

@RequestMapping(method = RequestMethod.GET, value="/{employeeId}")
public Employee get(@PathVariable String employeeId){
    return employeeRepository.findOne(employeeId);
}
}

最开始的@RestController和@RequestMapping这两个类级别的注解告诉Spring框架需要公开这是一个接收JSON的Rest服务,并且公开了URI路径是/employee。@Autowired注解告诉Spring框架采用上面我们定义的Repository接口的自动生成实现代码并将其注入到这个Controller中。现在到了特定的操作——方法级别的@RequestMapping注解表明这个方法将会基于HTTP动词来使用(在本例中是POST和GET),另外对于GET操作,我们指明了一个URL路径{employee},比如使用/employee/abcd1234来寻找一个员工并且返回该值。
现在我们有了足够多的准备工作可以来测试了,第一点,我们需要编译和运行我们的Spring Boot应用,在Eclipse中有很多方法可以做到这一点,但是我们将从命令行开始,并以我们的方式工作。在你的Employee目录中,敲入:gradle build,这个命令将会编译Spring Boot应用到build/lib/Employee.jar,这个jar包包含了运行这个应用所需要的所有东西,包括一个嵌入式的Servlet容器(默认情况下是Tomcat)。
在我们运行和测试这个应用之前,我们需要稍作回顾——我们的Mongo服务又在哪里?观察“docker ps”命令的输出,我们记得虚拟机的32777端口映射到了Mongo容器的27017端口,虚拟机的IP地址是192.126.99.100。如前所述,我们可以通过传递一个环境变量属性的方式来把连接属性传递给Spring,所以运行这个应用的命令行如下:

java -Dspring.data.mongodb.uri=mongodb://192.168.99.100:32777/micros -jar build/libs/Employee.jar

一旦应用启动之后(应该在1~4秒),你可以使用选项中的Rest工具来打开Web服务。

不要忘了在HTTP头部包含值为“application/json”的“Content-Type”,你应该收到如下的响应(id的值取决于你自己的情况):

{
"id": "55fb2f1930e07c6c844b02ff",
"email": "dan.greene@3pillarglobal.com",
"fullName": "Daniel Greene",
"managerEmail": null
}

你可以通过如下的调用测试我们的GET方法:

http://localhost:8080/employee/55fb2f1930e07c6c844b02ff

你应该得到相同的文档,万岁!我们的服务起作用了!

将Boot应用导入容器
现在我们需要构建我们的第一个容器来运行我们的Employee微服务。我们的途径是定义一个Dockerfile,这个文件将会定义如何生成一个镜像并放入我们的精益求精、短小精悍的微服务中。让我们阅读这个文件并逐步解析(参考第三篇第三步请跳到这儿):

FROM java:8
VOLUME /tmp
ADD build/libs/Employee.jar app.jar
EXPOSE 8080
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Dspring.data.mongodb.uri=mongodb://mongodb/micros", "-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

  • 我们从一个包含了安装了Java 8的标准镜像(镜像名字为“Java”,标签为“8”)开始构建过程
  • 我们接着定义了一个名为/tmp的卷
  • 接着将本地文件系统的一个文件添加进来,并且重命名为“app.jar”,重命名不是必须的,只是一个可用的可选项
  • 我们声明想要公开容器的8080端口
  • 在容器内运行一个touch命令,这样可以确保app.jar文件的修改日期
  • ENTRYPOINT命令定义了容器启动时需要运行的内容——我们运行Java,设置我们的Spring Mongo属性,还有快速的附加属性来加速Tomcat启动时间,然后指向我们的jar包。

现在我们通过运行如下命令构建镜像:

docker build -t microservicedemo/employee . 

我们可以敲入docker images看到结果

REPOSITORY                  TAG             IMAGE ID            CREATED             VIRTUAL SIZE
microservicedemo/employee   latest          364ffd8162b9        15 minutes ago      846.6 MB

接下来的问题就是“我们的服务容器如何与Mongo容器交互?”,为此,我们引入了容器的link机制。当你运行一个新的容器时,你可以传入一个可选的-link参数指定一个运行中的容器的名字,这样新的容器就可以与这个容器通讯了,所以我们的命令是:

docker run -P -d --name employee --link mongodb microservicedemo/employee

我们启动了一个新的容器,公开了端口(-P),以后台方式运行(-d),命名为employee(—name),接着将这个新的容器连接到了一个名为“mongodb”的容器(-link),连接过程如下:

  • 在employee容器的host文件添加一个条目指向MongoDB容器的运行位置
  • 在employee容器内添加一些环境变量来协助其他必要的编程访问,可以运行如下命令查看: {{{docker exec employee bash -c 'env | grep MONGODB'}}}
  • 允许容器通过公开的端口来直接通讯,这样就不需要担心主机的部分映射了。如果你还记得上述的内容,我们设置了Spring Mongo到MongoDB的URL作为主机名(mongodb://mongodb/micros),所以有了host文件条目和运行在默认端口的Mongo,Boot应用容器可以连上数据库了

在容器运行时我们可以来执行相同的Web服务,只是这次是作为容器来运行的(对于我来说,容器的8080端口会被映射到虚拟机的32772端口):

本篇我们已经取得了很大的进展,我们有了两个容器可以工作并且可以互相通讯,接下来的第四篇我们将添加一些额外的服务/容器,可以观察到构建更新的进度并与CI工具集成工作。

原文链接:BUILDING A MICROSERVICE ARCHITECTURE WITH SPRING BOOT AND DOCKER, PART III(翻译:胡震)

原文发布时间为:2015-12-14

本文作者:国会山上的猫TuxHu

本文来自合作伙伴DockerOne,了解相关信息可以关注DockerOne。

原文标题:Spring Boot与Docker(三):构建你的第一个微服务和相关容器以及容器的连接

时间: 2024-09-24 17:46:57

Spring Boot与Docker(三):构建你的第一个微服务和相关容器以及容器的连接的相关文章

Spring Boot与Docker(四):额外的微服务、更新容器、Docker Compose和负载均衡

本文讲的是Spring Boot与Docker(四):额外的微服务.更新容器.Docker Compose和负载均衡,[编者的话]本篇是<使用Spring Boot和Docker构建微服务架构>系列的第四篇,本篇我们我们将添加一些额外的服务/容器,并且更新容器,采用Docker Compose以及使用HAProxy容器进行负载均衡.原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务.B2B集成.空间分析.S

Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构

本文讲的是Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构,[编者的话]本篇是<使用Spring Boot和Docker构建微服务架构>系列的第二篇,本篇我们将会利用工具进行设置,深入探讨如何使用Docker工作,然后搭建我们的第一个容器.原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务.B2B集成.空间分析.SOA架构.大数据以及云计算等领域的软件产品架

利用 Spring Boot 在 Docker 中运行 Hadoop

本文讲的是利用 Spring Boot 在 Docker 中运行 Hadoop,[编者的话]Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.本文介绍了如何利用Spring Boot在Docker中运行Hadoop任务. 简介 越来越多的应用都开始使用Hadoop框架.而开发者在使用过程中也遇到一些挑战,比如使用诸如Docker之类的容器开发和部署相关的技术栈开发的应用.我们将会在下面的例子中介绍如何克服这些挑战. 由于 S

Spring Boot与Docker(一):微服务架构和容器化概述

本文讲的是Spring Boot与Docker(一):微服务架构和容器化概述,[编者的话]本篇是<使用Spring Boot和Docker构建微服务架构>系列四部曲的第一篇,本篇将会对我们谈及的微服务架构以及容器化概念作一个概述.原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务.B2B集成.空间分析.SOA架构.大数据以及云计算等领域的软件产品架构经验,他是AWS认证解决方案架构师,在3Pillar之前先

Spring Boot中使用Swagger2构建强大的RESTful API文档

由于Spring Boot能够快速开发.便捷部署等特性,相信有很大一部分Spring Boot的用户会用来构建RESTful API.而我们构建RESTful API的目的通常都是由于多终端的原因,这些终端会共用很多底层业务逻辑,因此我们会抽象出这样一层来同时服务于多个移动端或者Web前端. 这样一来,我们的RESTful API就有可能要面对多个开发人员或多个开发团队:IOS开发.Android开发或是Web开发等.为了减少与其他团队平时开发期间的频繁沟通成本,传统做法我们会创建一份RESTf

Spring Cloud微服务升级总结

一.应用系统的架构历史 [ 二.什么是微服务? 2.1 微服务概述 起源:微服务的概念源于 2014 年 3 月 Martin Fowler 所写的一篇文章"Microservices".文中内容提到:微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调.互相配合,为用户提供最终价值. 通信方式:每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于 HTTP 的 RESTful API). 微服务的常规定义:微服务是一种架构风

用 Docker 构建、运行、发布一个 Spring Boot 应用

本文演示了如何用 Docker 构建.运行.发布来一个 Spring Boot 应用. Docker 简介 Docker 是一个 Linux 容器管理工具包,具备"社交"方面,允许用户发布容器的 image (镜像),并使用别人发布的 image.Docker image 是用于运行容器化进程的方案,在本文中,我们将构建一个简单的 Spring Boot 应用程序. 有关 Docker 的详细介绍,可以移步至 <简述 Docker> 前置条件 JDK 1.8+ Maven

Docker with Spring Boot

前段时间在我厂卷爷的指导下将Docker在我的实际项目中落地,最近几个小demo都尽量熟悉docker的使用,希望通过这篇文章分享我截止目前的使用经验(如有不准确的表述,欢迎帮我指出).本文的主要内容是关于Java应用程序的docker化,首先简单介绍了docker和docker-compose,然后利用两个案例进行实践说明. 简单说说Docker,现在云计算领域火得一塌糊涂的就是它了吧.Docker的出现是为了解决PaaS的问题:运行环境与具体的语言版本.项目路径强关联,因此干脆利用lxc技术

利用Docker轻松实现云原生应用: Spring Boot + Redis分布式会话

本文为利用Docker和容器服务轻松实现云原生应用系列的第二篇 高可用架构设计 Spring Boot + Redis分布式会话 (本文) 前文谈到了云原生应用在部署架构中需要考虑的重要问题.文本将介绍一个常见的应用架构模式来提升应用的可用性和可伸缩性 - 分布式会话管理. 随着业务增长,Web应用也从单节点部署演变为集群部署.这时候除了需要为应用服务器增加负载均衡之外,也要解决会话(session)管理的问题.Session在应用中常被用于存储用户相关的数据.在高可用系统中,如果一台应用服务