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

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 本文讲的是Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构,【编者的话】本篇是《使用Spring Boot和Docker构建微服务架构》系列的第二篇,本篇我们将会利用工具进行设置,深入探讨如何使用Docker工作,然后搭建我们的第一个容器。
本文讲的是Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构 【编者的话】本篇是《使用Spring Boot和Docker构建微服务架构》系列的第二篇,本篇我们将会利用工具进行设置,深入探讨如何使用Docker工作,然后搭建我们的第一个容器。原文作者为3Pillar环球旗下美国Adbanced技术集团的总监Dan Greene,Dan有十八年的软件设计和开发经验,包括在电子商务、B2B集成、空间分析、SOA架构、大数据以及云计算等领域的软件产品架构经验,他是AWS认证解决方案架构师,在3Pillar之前先后就职于Oracle、ChoicePoint和Booz Allen Hamilton。Dan毕业于乔治·华盛顿大学,他也是一个父亲、业余木工爱好者,还参加过包括国际障碍大赛这样的障碍赛跑。

介绍和工具

在本篇中,我们将会构建第一篇中讨论的解决方案。我是在Mac上工作的,但是工具在Mac和PC上是相同的,所以在平台上的操作是99%相同的,我将不会回顾如何安装这些工具,而是直接从如何使用它们开始,你所需要的准备工作如下:
  • Docker Toolbox:包含了VirtualBox(作用为创建虚拟机用来运行容器)、Docker Machine(在虚拟机内运行Docker容器)、Docker Kitematic(一个管理在Docker Machine里运行的容器的GUI)以及Docker Compose(多容器编排工具)
  • Git:我的GitHub链接在这儿,我在Windows上使用Git Extensions,在Mac上使用Source Tree,不过使用其他Git客户端包括命令行都是可以的。
  • Java 8 SDK:Java 8在JVM永久代(PermGen)方面有了改进,另外对于Streams API和Lambda的支持也是非常赞的。
  • 构建工具的选择:让我们使用Gradle吧,我推荐使用SDKMan,正式名称为GVM来管理Gradle版本,如果你使用Windows工作,你可以使用Cygwin安装SDKMan或者SDKMan的Powershell命令行工具,或者Gravy也是可替代的选择。
  • IDE的选择:我们使用Spring Tool Suite(STS)来工作,在本文写作时最新的for Mac版本为3.7.0。
  • Rest工具:对于任何Web服务项目使用都非常方便,我是Chrome扩展工具Postman的粉丝,如果你擅长curl命令行,这个工具也是不错的。
  • uMongo或者Mongo GUI:文档型数据库完美匹配自足性的模型——对象进行自动检索,并且参考对象可以在微服务架构中通过ID来引用,这些ID可以很好地映射到文档存储中,另外地,MongoDB拥有运行很棒的“官方”Docker镜像。

我们对于源代码管理的第一个意见——似乎也是绝大多数的在线观点,就是每个微服务都应该有自己的版本库。微服务的一个基本理念就是跨服务之间不能共享代码。就我个人而言,这对我架构师的小心脏是个小小的打击,因为任何实用工具的重复代码的数量可能会比较多,以及缺乏一个单一、统一的领域模型给我有点心痛的感觉。我理解这个原则——自足性意味着自力更生。为了这篇博文,我把所有的代码都放到了一个单独的代码库,然而,每个微服务在根目录下都有它一个自己的目录。这样做是为了让我可以随着时间的推移展示分支的进展。在一个真实的解决方案中,你应该让每一个微服务都有它自己的不同的版本库,也许会有统一的版本库引用其它的子模块。

总体思路

因为我们要处理隔离的、可重用的组件,我们将做以下的映射:
一个逻辑业务对象→一个微服务→一个Git版本库目录→一个Mongo集合
因为业务对象可能由多个对象组成,任何我们认为可以作为其自身业务对象的子对象都可以划分为其自身的组件栈。

更多有关Docker如何工作的信息,以及我们的第一个容器

为了理解如何构建一个完整的基于Docker容器的产品解决方案,我们将需要深入研究容器是如何在宿主机(或者是虚拟机,正如我们的例子)里运行的,使用Docker通常是有三个阶段:镜像构建、镜像分发和容器部署。

构建镜像——Dockerfile的世界

为了构建镜像,你要写一系列的指令用来获取已有的镜像,接着对该镜像做些改变和配置。官方的Docker Hub Repository包含了许多的“官方”镜像以及数以千计的用户定制的镜像。如果其中的镜像不太符合你的需求,你可以创建一个定制的Dockerfile,用来在镜像上逐步添加一些内容,,比如安装系统软件包、复制文件或者公开一些网络端口,当我们构建微服务时,我们将会创建一个定制的Dockerfile,不过现在,我们将会利用一个标准镜像来启动一个MongoDB实例。

容器联网

当容器启动时,有一个它私有的网络,容器宿主机端口将外部网络通信转发到单个的容器端口上,特定的容器端口可以通过Dockerfile来决定公开,并且端口转发可以通过以下两种方式之一来进行:你可以显式地从宿主机映射端口到容器上,或者如果没有显式映射的话,Docker将映射已声明的容器端口到宿主机一个可用的临时端口上(通常的范围是从32768到61000)。当我们可以对整个解决方案显式地管理端口映射时,通常让Docker处理这一切是一个更加好的主意,并且可以通过Link机制公开端口信息到容器上,这方面将在我们构建我们的第一个微服务容器时有所涉及。

启动MongoDB容器

无论你是使用Kitematic还是Docker命令行,都可以非常简单的启动一个标准的容器。使用命令行的话,如果一切都安装正确,命令提示符将会包含以下三个关键的环境变量:
DOCKER_HOST=tcp://192.168.99.100:2376
DOCKER_MACHINE_NAME=default
DOCKER_TLS_VERIFY=1
DOCKER_CERT_PATH=/Users/[username]/.docker/machine/machines/default

这些是按照你的情况设置的(如果是在安装过程中打开的话,你可能需要重启终端或者命令提示符)。这些都是必要的,因为Docker不能直接运行在我的Mac笔记本上,而是跑在笔记本运行的虚拟机上。Docker客户端非常有效地将Docker命令从我的笔记本“代理”到虚拟机上,在我们启动容器前,让我们重温一下一部分Docker命令是非常有益的,在使用任何图形用户界面之前,了解命令行的东西总是很好的。

Docker级别的命令:

docker ps
该命令将会列出所有运行的容器,显示的信息包括它们的ID、名字、基础镜像名字和端口映射信息等。

docker build
该命令用来定义一个镜像——通过处理Dockerfile来创建一个新的镜像,我们将用这个命令来构建我们的微服务镜像。

docker pull[镜像名字]
该命令从远程Repository拉取镜像并且存储在本地。

docker run
该命令将基于一个本地或者远程Repository(比如Docker Hub)启动一个容器,我们将会相当多地探究这个命令。

docker push
该命令推送一个构建好的镜像到一个Repository,通常是Docker Hub。

容器特定的命令

这些命令使用容器ID或者名字作为一个参数:

docker status [容器名字/ID][容器名字/ID]
这个命令将显示指定的每一个容器的当前负载,比如CPU占用率、内存使用率以及网络流量等。

docker logs [-f][容器名字/ID]
该命令显示容器的最新的日志,-f选项就好比Shell终端中的“tail -f”中的-f选项。

docker inspect [容器名字/ID]
该命令将容器的所有配置信息以JSON的格式转储出来显示。

docker port [容器名字/ID]
该命令显示容器与宿主机之间的所有端口映射信息。

docker exec [-i][-t][容器名字/ID]
该命令将在目标容器上执行一条命令(-i表明以交互方式运行,-t表明以伪TTY终端运行),这个命令常用来获得一个容器终端Shell:
docker exec -it [容器名字/ID]sh

一旦我们理解了这些参考材料,我们可以进入到下一步启动一个Mongo容器。

命令非常简单: docker run -P -d —name mongo mongo

解释如下:
  • P选项告知Docker在临时端口范围里公开容器声明的任何端口
  • d选项告知以Daemon方式运行容器(比如在后台)
  • name选项给容器分配一个名字(名字必须在所有运行的容器实例中唯一,如果你不提供这个选项,将会获得一个随机的半友好的名字比如modest_poitras)
  • 最后的mongo表明了使用哪一个镜像

Docker Hub镜像的定义采用了[所有者]/[镜像名字][:标签]的命名格式,如果没有指定所有者,那么使用的就是“官方”的Docker Hub镜像——这是预留给Docker官方给软件供应商的礼物也就是成为官方镜像,如果最后的标签部分省略的话,那么就会认为你需要获得的是最新版本的镜像。

现在我们来尝试确认我们的Mongo实例已经启动并且运行了:
docker exec -it mongo sh

mongo

MongoDB shell version: 3.0.6 connecting to: test Server has startup warnings: 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never' 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] **        We suggest setting it to 'never' 2015-09-02T00:57:30.761+0000 I CONTROL  [initandlisten] > use microserviceblog switched to db microserviceblog > db.createCollection('testCollection') { "ok" : 1 }

在容器内部,Mongo看起来正在运行,但是我们可以从外部获知吗?为了尝试这个,我们需要查看什么临时端口被映射到了Mongo的端口上,我们运行如下命令:
docker ps

从下面我们可以看到(为了可读性省略了一些列):
CONTAINER ID        IMAGE                PORTS                      NAMES
87192b65de95        mongo                0.0.0.0:32777->27017/tcp   mongodb

我们可以看到宿主机端口32777映射到了容器端口27017上,然而,记住我们的容器是运行在虚拟机上的,所以我们必须回到我们的环境变量:
$ echo $DOCKER_HOST
tcp://192.168.99.100:2376

我们应该可以通过如下的地址访问我们的Mongo容器的27017端口:
192.168.99.100:32777 ,启动Mongo然后点击那个位置显示数据库可以外部访问:
236x174xbuilding_microservice_part2.jpg.pagespeed_.ic_.-L7yvISwcS_.jpg

在这里结束第二篇吧,在本系列的第三篇中,我们将继续探讨,通过创建一个或两个微服务,管理它们的变化,然后运用持续集成以及产品部署技术进行工作。

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

原文发布时间为:2015-12-09
本文作者:国会山上的猫TuxHu 
本文来自云栖社区合作伙伴DockerOne,了解相关信息可以关注DockerOne。
原文标题:Spring Boot与Docker(二):使用Spring Boot和Docker构建微服务架构
目录
相关文章
|
5天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
3天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
8天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
41 6
|
8天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
24 1
|
4天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
14 1
服务架构的演进:从单体到微服务的探索之旅
|
3天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
20 5
|
5天前
|
监控 API 微服务
后端技术演进:从单体架构到微服务的转变
随着互联网应用的快速增长和用户需求的不断演化,传统单体架构已难以满足现代软件开发的需求。本文深入探讨了后端技术在面对复杂系统挑战时的演进路径,重点分析了从单体架构向微服务架构转变的过程、原因及优势。通过对比分析,揭示了微服务架构如何提高系统的可扩展性、灵活性和维护效率,同时指出了实施微服务时面临的挑战和最佳实践。
22 7
|
4天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
17 5
|
4天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
7天前
|
消息中间件 供应链 架构师
微服务如何实现低耦合高内聚?架构师都在用的技巧!
本文介绍了微服务的拆分方法,重点讲解了“高内聚”和“低耦合”两个核心设计原则。高内聚强调每个微服务应专注于单一职责,减少代码修改范围,提高系统稳定性。低耦合则通过接口和消息队列实现服务间的解耦,确保各服务独立运作,提升系统的灵活性和可维护性。通过领域建模和事件通知机制,可以有效实现微服务的高效拆分和管理。
29 7