简介

维基上对其定义为:一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务与服务间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据上下文,选择合适的语言、工具对其进行构建。

参考:

百度百科:微服务

理论知识

现阶段首先提及到微服务一定离不开虚拟化,现阶段的微服务实现基本上都是基于虚拟化和容器进行开展的。

参考:

LXC and LXD: Explaining Linux Containers

知乎:IaaS、PaaS、SaaS的区别

腾讯云:四种正确的微服务部署方式

了解LXC&LXD和Docker&CoreOS

LXC Vs Docker

除了以上的对比,重要的还有:

  • This means you should consider the type of deployment you will have to manage before making a choice regarding LXD or Docker (or CoreOS, which is similar to Docker in this regard). Are you going to be spinning up large numbers of containers quickly based on generic app images? If so, go with Docker or CoreOS. Alternatively, if you intend to virtualize an entire OS, or to run a persistent virtual app for a long period, LXD will likely prove a better solution.

    这意味着在选择LXD或Docker(或CoreOS,在这方面与Docker类似)之前,应该考虑必须管理的部署类型。你是否打算基于通用的应用图像快速旋转大量容器?如果是,请使用Docker或CoreOS。另外,如果您打算虚拟化整个操作系统,或者长时间运行持久的虚拟应用程序,那么LXD可能是更好的解决方案。

  • The second factor to consider is your host environment. LXD only supports Linux—and, at least for now, it’s really only documented for use with Ubuntu. So if your servers run another flavor of Linux or Windows, LXD won’t work well for you. In contrast, Docker and CoreOS are pretty portable across almost any Linux-based OS, and you can now even run Docker natively on Windows and OS X.

    第二个要考虑的因素是宿主环境。LXD只支持Linux,至少目前,它只在文档中描述了与Ubuntu一起使用。因此,如果您的服务器运行另一种类型的Linux或Windows, LXD将不能很好地为您工作。相比之下,Docker和CoreOS在几乎所有基于linux的操作系统上都是非常可移植的,你现在甚至可以在Windows和OS X上本机运行Docker。

了解云计算三种服务模型

preview

云服务三种类别:

  • IaaS (Infrastructure as a Service),基础架构即服务

    • 说白了就是公司不用直接买硬件搞硬件维护了和系统维安全维护等,直接找IaaS提供商,直接购买虚拟机按需购买虚拟机配置。
    • 例如:AWS,阿里云,腾讯云,华为云
  • PaaS(Platform as a Service).平台即服务

    • PaaS主要由构建软件或应用程序的开发人员使用,PaaS解决方案为开发人员提供了创建独特的、可定制软件的平台。
    • 例如:Spring Cloud、Microsoft Windows Azure,百度BAE、新浪SAE、京东云擎JAE
  • SaaS(Software as a Service),软件即服务

    • 租用已开发好的软件,开发、维护、升级换代都不用考虑,更方便、更安全。
    • 例如:企业微信、Microsoft Office 365

发展阶段

参考:

CDSN-kimmking:如何向小白讲述软件架构发展历程?

凤凰架构

四大发展阶段

  • 单体架构阶段
    • 简单单体模式
    • 单体架构MVC模式
  • 分布式架构阶段
    • SOA 架构阶段
    • 微服务架构阶段(MSA)

单体架构

简单单体模式

严重影响开发效率。如果一个使用 Java 的简单单体项目代码超过 100 万行,那么在一台笔记本电脑上修改了代码后执行自动编译,可能需要等待十分钟以上,并且内存可能不够编译过程使用,这是非常难以忍受的。

  • 适用于规模较小的系统开发。
  • 项目开发,直接上手,质量换速度。
  • 项目的依赖关系混乱,修改一处代码,可能影响一大片的功能无法正常使用。
  • 项目的任何业务逻辑调整都会导致整个系统的重新打包、部署、停机、再启动。
  • 扩展性受限,业务存在性能问题,就要部署几个完整的实例集群,或加上负载均衡,才能保障系统性能可以支撑用户的使用。

MVC模式

由于简单单体存在诸多问题,MVC模式很好的将简单单体模式直接分为三层模型,模型层(Model Layer)、视图层(View Layer)、控制器层(Controller Layer)。发展的同时出现了ORM简化数据操作层,相比于简单单体模式的开发效率提升了,但也存在未解决的问题,可用性、扩展性等问题依旧存在。

  • 把整个系统拆解成了很多粒度较小的零件,简单、直观、可以非常有效的上手。
  • 有利于分配开发工作,投入大量的后端工程师进行大规模工程的开发。
  • 基于MVC模式,发展了ORM等简化数据操作层,以及响应的代码生成工具等,提升软件开发效率。

前后端分离模式

JSP或页面Tag技术,比如FreeMaker、Velocity等模板技术,导致前端技术和后端技术处理的逻辑和数据耦合到一起,使得前后端开发工程师很难只处于各自独立的领域进行开发。随着富网络应用程序(Rich Internet Application,RIA)概念的兴起,比如Ajax 和 JQuery 框架,越来越多的业务逻辑需要在浏览器端实现,此时前端技术发展到了一个百花齐放的阶段,特别是NodeJS前端技术成功应用,使前端技术成为了一个与后端技术领域并驾齐驱的阶段。

  • Web 系统就由原来的 BS 系统,变成了提供 UI 和交互的前端 B 系统,提供数据接口的后端 S 系统。
  • 前后端开发人员可进行并行开发工作,前端团队负责前端系统开发,后端团队负责后端系统开发,两个团队一起制定前后端系统的数据接口。
  • 前后端系统可以各自独立发展和维护。这一条准则不仅仅是单体架构独有的,所有的 Web 系统都可以按照这种方式进行设计。

分布式架构阶段

SOA 架构阶段

SOA 在 21 世纪最初的十年里曾经盛行一时,有 IBM 等一众行业巨头厂商为其呐喊冲锋,吸引了不少软件开发商、尤其是企业级软件的开发商的跟随,最终却还是偃旗息鼓,沉寂了下去。本质原因:过于严格的规范定义带来过度的复杂性。而构建在 SOAP 基础之上的 ESB、BPM、SCA、SDO 等诸多上层建筑,进一步加剧了这种复杂性。开发信息系统毕竟不是作八股文章,过于精密的流程和理论也需要懂得复杂概念的专业人员才能够驾驭。SOA 诞生的那一天起,就已经注定了它只能是少数系统阳春白雪式的精致奢侈品,它可以实现多个异构大型系统之间的复杂集成交互,却很难作为一种具有广泛普适性的软件架构风格来推广。SOA 最终没有获得成功的致命伤与当年的EJB如出一辙,尽管有 Sun Microsystems 和 IBM 等一众巨头在背后力挺,EJB 仍然败于以 Spring、Hibernate 为代表的“草根框架”,可见一旦脱离人民群众,终究会淹没在群众的海洋之中,连信息技术也不曾例外过。

参考:

凤凰架构:SOA 时代

微服务架构(MSA)

微服务是一种通过多个小型服务组合来构建单个应用的架构风格,这些服务围绕业务能力而非特定的技术标准来构建。各个服务可以采用不同的编程语言,不同的数据存储技术,运行在不同的进程之中。服务采取轻量级的通信机制和自动化的部署机制实现通信与运维。

虽有诸多的优点,比如测试阶段,一个全流程的测试跨8-10个系统。数据的一致性、系统监控等都会因为拆分太细,复杂度大幅度增加。如果代码设计上有一个涉及到多个不同的微服务,那么团队协调配合也会增加。合理的组件边界应该如何确定,这是非常困难的。

Martin Fowler 建议:不要一上来就以微服务架构作为系统设计的起点。相反地,要用一个单块系统作为起点,并保持其模块化。当这个单块系统出现了问题后,再将其分解为微服务。

参考:

凤凰架构:微服务时代

51CTO-老_张:微服务架构超强讲解,通俗易懂,写得太好了!

  • 更加彻底的组件化,系统内部各个组件之间解耦的比较干脆,单个系统的规模小很多;
  • 可以组建每个服务独立的维护团队,利于各自团队独立的开发和维护;
  • 每个微服务独立部署,只要服务间的接口稳定,各系统可以相互之间互不干扰的独立发展;
  • 微服务架构使得每个服务本身可以独立的扩展,性能出现瓶颈,优化或增加这个服务的配置即可。

传统开发模式

微服务架构的设计

越来越多的论坛、社区、blog以及互联网行业巨头开始对微服务进行讨论、实践,可以说这样更近一步推动了微服务的发展和创新。而微服务的流行,Martin Fowler功不可没。

这老头是个奇人,特别擅长抽象归纳和制造概念。特别是微服务这种新生的名词,都有一个特点: 一解释就懂,一问就不知,一讨论就打架。

Martin Fowler是国际著名的OO专家,敏捷开发方法的创始人之一,现为ThoughtWorks公司的首席科学家。在面向对象分析设计、UML、模式、软件开发方法学、XP、重构等方面,都是世界顶级的专家,现为Thought Works公司的首席科学家。Thought Works是一家从事企业应用开发和——集成的公司。早在20世纪80年代,Fowler就是使用对象技术构建多层企业应用的倡导者,他著有几本经典书籍:《企业应用架构模式》、《UML精粹》和《重构》等。

—— 百度百科

This common manifestation of SOA has led some microservice advocates to reject the SOA label entirely, although others consider microservices to be one form of SOA , perhaps service orientation done right. Either way, the fact that SOA means such different things means it’s valuable to have a term that more crisply defines this architectural style

由于与 SOA 具有一致的表现形式,这让微服务的支持者更加迫切地拒绝再被打上 SOA 的标签,尽管有一些人坚持认为微服务就是 SOA 的一种变体形式,也许从面向服务方面这个方面来说是对的,但无论如何,SOA 与微服务都是两种不同的东西,正因如此,使用一个别的名称来简明地定义这种架构风格就显得更有必要。

—— Martin Fowler / James Lewis,Microservices

无服务时代

如果说微服务架构是分布式系统这条路的极致,那无服务架构,也许就是“不分布式”的云端系统这条路的起点。

大家看看就好,是一种预言新技术发展的架构。

参考:

凤凰架构:无服务时代

微服务部署方式

参考:

K8s中文社区-雷伟:CoreOS VS Docker容器大战,之容器引擎

腾讯云-DevOps时代:DevOps 三剑客:Dev,Ops and Jenkins

博客园-Andya:OpenShift-介绍

OpenShift可以安装在RHEL(Red Hat Enterprise Linux)和RHELAH(Red Hat Eneterprise Linux Atomic Host)、CentOS和Fedora上;K8S最好在Unbuntu、Fedora和Debian上运行,可部署在任何主要的IaaS上,如IBM、AWS、Azure、GCP和阿里云等云平台上。

腾讯云-互联网老辛:【DevOps】持续集成的流程及jenkins的介绍

Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。jenkins 是用java开发的,一款开源的自动化服务器,我们只需要通过界面或者jenkinsfile告诉jenkins,执行什么任务,什么时间执行,就可以

腾讯云-Linyb极客之路 四种正确的微服务部署方式

知乎哈-喽沃德先生:一篇文章搞懂 Spring Cloud 是什么

51CTO-老_张:微服务架构超强讲解,通俗易懂,写得太好了!

CSDN-爱码三疯:Spring Cloud与Docker的完美结合,运维可以不用拜菩萨啦

Java微服务方案

采用Swarm将多台安装Docker的物理机统一管理

Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。

参考:

稀土掘金-code泷:Docker Swarm 搭建集群环境(高可用)

Swarm的基本架构

假如公司有多台物理主机或者云服务主机,我们的主机中都安装了Docker,为了方便统一管理运行的容器和将这些主机视为一个大的Docker主机,或者将分布在不同物理/虚拟机主机的容器之间形成一个大的子网,供所有的容器进行之间跨主机跨容器互访提供了便捷。

将服务打包成镜像

参考:

腾讯云-louiezhou001:Dockerfile究竟是做什么的

GitHub:Mysql8.0 Dockerfile

Docker一般采用“一个容器一个进程”的方式,而我们每个微服务也都是一个spring boot应用单进程,直接采用java -jar的形式即可运行应用,那么我们只需将我们的一个服务打包到一个镜像中即可。每个服务下面都会有一个专门的Docker目录,里面放置了Dockerfile及镜像中需要用到的文件,说白了Dockerfile就是为了使用Maven的插件docker-maven-plugin构建镜像时指挥此插件构建镜像时候需要拿什么资源,就比如,Java项目就必须拿JDK,我的镜像需要运行在什么样的系统,比如Linux,就会拿相应的Linux内核等。

maven的docker打包的插件

配置Jenkins

参考:

腾讯云-互联网老辛:【DevOps】持续集成的流程及jenkins的介绍

Jenkins是一个开源的、可扩展的持续集成、交付、部署(软件/代码的编译、打包、部署)的基于web界面的平台。允许持续集成和持续交付项目,无论用的是什么平台,可以处理任何类型的构建或持续集成。jenkins 是用java开发的,一款开源的自动化服务器,我们只需要通过界面或者jenkinsfile告诉jenkins,执行什么任务,什么时间执行,就可以。

有人可能有疑问,通过上面的Maven进行打包镜像不就可以,其实通过Jenkins批量进行更为方便,可以更方便进行交付、编译、打包、部署的工具,且是一个基于web界面的平台,通过下图shell操作后Jenkins会将打好的镜像包批量推送到比如阿里云容器服务中的镜像库中(没部署,只是上传了)。参考资料发现Jenkins会通过GitHub等发现代码改动自动进行打包部署上线。

Jenkins批量打包推送到自己的镜像库

docker-compose进行服务编排

微服务架构的应用系统中一般包含若干个微服务,每个微服务一般都会部署多个实例,如果每个微服务都要手动启停,维护的工作量会很大。Docker Compose可以轻松的管理容器,降低维护工作量。

简书-AaronSimon:Docker Compose编排微服务

Compose 中有两个重要的概念:

  • 服务 ( service ):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
  • 项目 ( project ):由一组关联的应用容器组成的一个完整业务单元,在 dockercompose.yml 文件中定义。
    Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。可见,一个项目可以由多个服务(容器)关联而成, Compose 面向项目进行管理

基本步骤

  1. 在 Dockfile 中定义你的应用环境,使其可以在任何地方重现该环境。
  2. docker-compose.yml 中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
  3. 运行dcoker-compose up,Compose 将启动并运行整个应用程序。

部署服务示例,请查看本节参考(使用docker compose部署spring cloud项目)。

部署前项目中的maven配置文件必须先满足含有docker-maven-plugin,且每个Module已经含有docker文件夹,其中包含Dockerfile和镜像中需要用到的文件。

像这样

编排示例

服务 端口 备注
eureka-server 1111,1112 服务注册与发现中心(高可用部署)
demo 8102 服务1
feign-upload_first 8100 服务2
feign_upload_second 8101 服务

首先要在两个服务中编写好配置,这里演示配置方式为.properties文件:

  • application-peer1.properties
1
2
3
4
server.port=1111
spring.application.name=eureka-server
eureka.instance.hostname=peer1
eureka.client.service-url.defaultZone=http://peer2:1112/eureka/
  • application-peer2.properties
1
2
3
4
server.port=1112
spring.application.name=eureka-server
eureka.instance.hostname=peer2
eureka.client.service-url.defaultZone=http://peer1:1111/eureka/

写入docker-compose-manage.yml,目的是将这两个服务直接可以运行起来,并设置好正确的端口映射到物理主机:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
version: "2"
services:
# 指定服务名称
peer1:
#指定Eureka镜像地址
image: ibase/eureka-server:0.0.1-SNAPSHOT
#映射端口到物理主机
ports:
- "1111:1111"
environment:
- spring.profiles.active=peer1
peer2:
image: ibase/eureka-server:0.0.1-SNAPSHOT
hostname: peer2
ports:
- "1112:1112"
environment:
- spring.profiles.active=peer2

自己写的服务,将使用docker-compose-services.yml,一样是上面的道理,直接就可以配置端口并运行起来服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
version: "2"
services:
# 指定服务名称
feign_upload_first:
#指定服务所使用的镜像名称
image: ibase/feign_upload_first:0.0.1-SNAPSHOT
ports:
- "8100:8100"
feign_upload_second:
image: ibase/feign_upload_second:0.0.1-SNAPSHOT
ports:
- "8101:8101"
demo:
image: ibase/demo:0.0.1-SNAPSHOT
ports:
- "8102:8102"

启动

执行如下命令执行以上编排配置文件来批量启动服务,但后面的直接可以用Swarm启动即可。

1
docker-compose docker-compose-manage.yml up
1
docker-compose docker-compose-services.yml up

再附上一个docker-compose编排配置代码:

img

其中数据卷映射配置

以上指定了该服务启动时的运行环境、运行数量、数据卷映射(可以创建NAS数据卷做为通用数据存储)、指向的阿里云SLB等,结合着spring cloud的统一配置服务,我们可以通过采用不同的docker-compose编排来区分不同环境。

img

创建应用

此步骤直接可以用Docker-compose命令可以进行,但是Docker的 Swarm直接就可以操作图形化进行编排。

  1. 创建一个应用基本信息填写

  2. 将之前maven配置的编排模板号填入:

    之前定义的系统模板版本号

    点击使用已有编排模板

    比如我之前的模板版本号是2.5.0

    填入镜像版本号

    完成

部署到生产环境

测试通过之后需要部署到生产环境,传统的部署方式要么是通过对测试通过的代码包进行拷贝,并对配置文件进行更改;要么就是通过svn/git中的版本控制从测试到生产的迁移,再进行jenkins的预生产环境测试,但是无论哪种部署方式都很容易出问题:

  • 漏改、错改配置文件;
  • 代码合并/迁移过程中产生新的问题;
  • 生产、测试服务器环境不同,环境差异造成的问题。但docker镜像是一个单进程的应用,而且只要宿主机运行docker没问题,那么docker重的环境也不会出现任何问题,我们将通过测试的应用从测试环境迁移到生产环境就很简单了,只用提供不同的docker-compose服务编排,生产环境直接通过变更配置更改镜像版本号即可。

日志采集详见参考CSDN-爱码三疯:Spring Cloud与Docker的完美结合,运维可以不用拜菩萨啦