引言:“微服务”是当前软件架构领域非常热门的词汇,能找到很多关于微服务的定义、准则,以及如何从微服务中获益的文章,在企业的实践中去应用“微服务”的资源却很少。本篇文章中,会介绍微服务架构(Microservices Architecture)的基础概念,以及如何在实践中具体应用。

单体架构(Monolithic Architecture )

企业级的应用一般都会面临各种各样的业务需求,而常见的方式是把大量功能堆积到同一个单体架构中去。比如:常见的ERP、CRM等系统都以单体架构的方式运行,同时由于提供了大量的业务功能,随着功能的升级,整个研发、发布、定位问题,扩展,升级这样一个“怪物”系统会变得越来越困难。

单体架构的初期效率很高,应用会随着时间推移逐渐变大。在每次的迭代中,开发团队都会面对新功能,然后开发许多新代码,随着时间推移,这个简单的应用会变成了一个巨大的怪物。

图1:单体架构

大部分企业通过SOA来解决上述问题,SOA的思路是把应用中相近的功能聚合到一起,以服务的形式提供出去。因此基于SOA架构的应用可以理解为一批服务的组合。SOA带来的问题是,引入了大量的服务、消息格式定义和规范。

多数情况下,SOA的服务直接相互独立,但是部署在同一个运行环境中(类似于一个Tomcat实例下,运行了很多web应用)。和单体架构类似,随着业务功能的增多SOA的服务会变得越来越复杂,本质上看没有因为使用SOA而变的更好。图1,是一个包含多种服务的在线零售网站,所有的服务部署在一个运行环境中,是一个典型的单体架构。

单体架构的应用一般有以下特点:

  • 设计、开发、部署为一个单独的单元。
  • 会变得越来越复杂,最后导致维护、升级、新增功能变得异常困难
  • 很难以敏捷研发模式进行开发和发布
  • 部分更新,都需要重新部署整个应用
  • 水平扩展:必须以应用为单位进行扩展,在资源需求有冲突时扩展变得比较困难(部分服务需要更多的计算资源,部分需要更多内存资源)
  • 可用性:一个服务的不稳定会导致整个应用出问题
  • 创新困难:很难引入新的技术和框架,所有的功能都构建在同质的框架之上

微服务架构(Microservices Architecture)

微服务架构的核心思想是,一个应用是由多个小的、相互独立的、微服务组成,这些服务运行在自己的进程中,开发和发布都没有依赖。

多数人对于微服务的定义是,把本来运行在单体架构中的服务拆分成相互独立的服务,并运行在各自的进程中。在我看来,不仅如此。最关键的地方在于,不同的服务能依据不同的业务需求,构建的不同的技术架构之上,并且聚焦在有限的业务功能之上。

因此,在线零售网站可以用图2的微服务架构来简单概括。基于业务需求,需要增加一个账户服务微服务,因此构建微服务绝不是在单体架构中把服务拆分开这么简单。

图2:微服务架构

微服务设计:规模、范围、业务功能

你可能从零开始用微服务来构建应用,也可能重构现有系统,确定微服务的规模,范围和功能都特别重要。让我们讨论一些有关微服务设计的关键问题和对它的误解:

  • “微”很容易被误解:很多开发者会倾向于把服务往尽量小的颗粒度去做
  • 在SOA方式下,服务都还是以单体架构在运行,用于支持不同的功能。如果依旧采用SAO类似的服务,仅仅是名义上叫做微服务,并不能带来任何微服务的优势。

那我们在微服务中应该怎样设计呢。以下是微服务的设计指南:

  • 职责单一原则(Single Responsibility
  • Principle):把某一个微服务的功能聚焦在特定业务或者有限的范围内会有助于敏捷开发和服务的发布。
  • 设计阶段就需要把业务范围进行界定。
  • 需要关心微服务的业务范围,而不是服务的数量和规模尽量小。数量和规模需要依照业务功能而定。
  • 于SOA不同,某个微服务的功能、操作和消息协议尽量简单。
  • 项目初期把服务的范围制定相对宽泛,随着深入,进一步重构服务,细分微服务是个很好的做法。

微服务消息

在单体架构中,不同功能之间通信通过方法调用,或者跨语言通信。SOA降低了这种语言直接的耦合度,采用基于SOAP协议的web服务。这种web服务的功能和消息体定义都十分复杂,微服务需要更轻量的机制。

同步消息 – REST, Thrift

同步消息就是客户端需要保持等待,直到服务器返回应答。REST是微服务中默认的同步消息方式,它提供了基于HTTP协议和资源API风格的简单消息格式,多数微服务都采用这种方式(每个功能代表了一个资源和对应的操作)。

Thrift是另外一个可选的方案。它采用接口描述语言定义并创建服务,支持可扩展的跨语言服务开发,所包含的代码生成引擎可以在多种语言中,如 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, Smalltalk 等创建高效的、无缝的服务,其传输数据采用二进制格式,相对 XML 和 JSON 体积更小,对于高并发、大数据量和多语言的环境更有优势。

图3:REST接口,对外微服务

异步消息 – AMQP, STOMP, MQTT

异步消息就是客户端不需要一直等待服务应答,有应到后会得到通知。某些微服务需要用到异步消息,一般采用AMQP, STOMP, MQTT。

消息格式 – JSON, XML, Thrift, ProtoBuf, Avro

消息格式是微服务中另外一个很重要的因素。SOA的web服务一般采用文本消息,基于复杂的消息格式(SOAP)和消息定义(xsd)。微服务采用简单的文本协议JSON和XML,基于HTTP的资源API风格。如果需要二进制,通过用到Thrift, ProtoBuf, Avro。

服务约定 – 定义接口 – Swagger, RAML, Thrift IDL

如果把功能实现为服务,并发布,需要定义一套约定。单体架构中,SOA采用WSDL,WSDL过于复杂并且和SOAP紧耦合,不适合微服务。

REST设计的微服务,通常采用Swagger和RAML定义约定。

对于不是基于REST设计的微服务,比如Thrift,通常采用IDL(Interface Definition Languages),比如Thrift IDL。

微服务集成 (服务间通信)

微服务架构下,应用的服务直接相互独立。在一个具体的商业应用中,需要有些机制支持微服务之间通信。因此服务间的通信机制特别重要。

SOA体系下,服务之间通过企业服务总线(Enterprise Service Bus)通信,许多业务逻辑在中间层(消息的路由、转换和组织)。微服务架构倾向于降低中心消息总线(类似于ESB)的依赖,将业务逻辑分布在每个具体的服务终端。

大部分微服务基于HTTP、JSON这样的标准协议,集成不同标准和格式变的不再重要。另外一个选择是采用轻量级的消息总线或者网关,有路由功能,没有复杂的业务逻辑。下面就介绍几种常见的架构方式。

点对点方式 – 直接调用服务

点对点方式中,服务之间直接用。每个微服务都开放REST API,并且调用其它微服务的接口。

图4:通过点对点方式通信

很明显,在比较简单的微服务应用场景下,这种方式还可行,随着应用复杂度的提升,会变得越来越不可维护。这点有些类似SOA的ESB,尽量不采用点对点的集成方式。

点对点有下面几个缺点:

  • 非功能的需求,比如用户授权、限制、监控,需要在每个微服务中进行实现
  • 随着功能的演进,服务会变得越来越复杂。
  • 不同的服务直接,客户端和服务直接没有控制功能(监控、跟踪、过滤)
  • 直接通信在大型系统设计中,一般是反面典型。

因此,如果设计一个大型的微服务系统,尽量避免点对点的通信方式,也不能像ESB这样重量级的总线。而是一个轻量级的总线,能够提供非业务功能的抽象。这就是API网关方式。

API-网关方式

API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能个。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。

图5:通过API-网关暴露微服务

用我们网上商店的例子,在图5中,所有的业务接口通过API网关暴露,是所有客户端接口的唯一入口。微服务之间的通信也通过API网关。

采用网关方式有如下优势:

  • 有能力为微服务接口提供网关层次的抽象。比如:微服务的接口可以各种各样,在网关层,可以对外暴露统一的规范接口。
  • 轻量的消息路由、格式转换。
  • 统一控制安全、监控、限流等非业务功能。
  • 每个微服务会变得更加轻量,非业务功能个都在网关层统一处理,微服务只需要关注业务逻辑

目前,API网关方式应该是微服务架构中应用最广泛的设计模式。

消息代理方式

微服务也可以集成在异步的场景下,通过队列和订阅主题,实现消息的发布和订阅。一个微服务可以是消息的发布者,把消息通过异步的方式发送到队列或者订阅主题下。作为消费者的微服务可以从队列或者主题共获取消息。通过消息中间件把服务之间的直接调用解耦。

图6:异步通信方式

通常异步的生产者/消费者模式,通过AMQP、MQTT等异步消息规范。

数据的去中心化

单体架构中,不同功能的服务模块都把数据存储在某个中心数据库中。

图7:单体架构,用一个数据库存储所有数据

微服务方式,多个服务之间的设计相互独立,数据也应该相互独立(比如,某个微服务的数据库结构定义方式改变,可能会中断其它服务)。因此,每个微服务都应该有自己的数据库。

图8:每个微服务有自己私有的数据库,其它微服务不能直接访问。

数据去中心话的核心要点:

  • 每个微服务有自己私有的数据库持久化业务数据
  • 每个微服务只能访问自己的数据库,而不能访问其它服务的数据库
  • 某些业务场景下,需要在一个事务中更新多个数据库。这种情况也不能直接访问其它微服务的数据库,而是通过对于微服务进行操作。

数据的去中心化,进一步降低了微服务之间的耦合度,不同服务可以采用不同的数据库技术(SQL、NoSQL等)。在复杂的业务场景下,如果包含多个微服务,通常在客户端或者中间层(网关)处理。

下篇文章会介绍微服务实战的其它内容:管理去中心化、服务的注册和发现、安全、事务、失败的设计、其它。

PS:欢迎大家加入交流群:733234221,群内免费分享Spring框架、Mybatis框架SpringBoot框架、SpringMVC框架、SpringCloud微服务、Dubbo框架、Redis缓存、RabbitMq消息、JVM调优、Tomcat容器、MySQL数据库教学视频及架构学习思维导图

mqtt发布json数据_微服务实战:从架构到发布(一)相关推荐

  1. 腾讯游戏数据应用微服务实战

    作者注:本文是作者在GIAC全球互联网大会上的一个分享整理成稿子,介绍了微服务以及腾讯游戏数据应用在微服务中的实践,整理时间仓促,如有偏颇,请联系小编修正. 各位架构师们,大家下午好.我是来自于腾讯游 ...

  2. 发布json数据_技术分享 | MySQL 8.0.17 GA 发布!

    昨日 MySQL 官网正式发布 8.0.17 / 5.7.27 / 5.6.45 三个(维护)版本,距离上一个 GA 版本(8.0.16)发布时隔仅 88 天! MySQL 各开发团队的博客网站,同一 ...

  3. docker -v 文件夹下没有数据_微服务就是Dubbo?并没有那么简单!微服务架构+Docker+k8s了解下...

    微服务算是面试中非常高频的词汇了! 之前我就遇到一个候选人,我问他微服务是什么,他说:"微服务就是 Dubbo--",然后把 Dubbo 的原理说的清清楚楚.回答的我都动心了,我猜 ...

  4. 发布json数据_数据库每周国际新闻 20201211

    数据库每周国际新闻 2020-12-11阅览文章内容详情,请点击最下方的"阅读原文"!备注:原文内含有文章原有链接,详细信息均可通过原文链接查看.英文原文地址:https://db ...

  5. 微服务实战:从架构到发布(二)

    引言:上篇文章介绍了微服务和单体架构的区别.微服务的设计.消息.服务间通信.数据去中心化,本篇会继续深入微服务,介绍其它特性. 治理去中心化 通常"治理"的意思是构建方案,并且迫使 ...

  6. 微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关

    微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关 1. 微服务简介 1.1 服务架构演变 1.2 SpringCloud ...

  7. Docker与微服务实战2022:基础篇

    Docker与微服务实战2022:高级篇 目录 一.简介 二.安装docker 三.操作命令 3.1.帮助命令 3.2.镜像命令 3.3.容器命令 四.镜像分层 五.本地镜像推送到阿里云 1.阿里云镜 ...

  8. 异构服务器 微服务_微服务架构是什么?

    如果你懂或者不理解,希望你看到这篇文章之后就能搞懂. 以下: 正文 看到最近"微服务架构"这个概念这么火,作为一个积极上进的程序猿,成小胖忍不住想要学习学习.而架构师老王(不是隔壁 ...

  9. 两个server 两个数据库 微服务_微服务的数据库设计

    单独的数据库: 微服务设计的一个关键是数据库设计,基本原则是每个服务都有自己单独的数据库,而且只有微服务本身可以访问这个数据库.它是基于下面三个原因. 优化服务接口:微服务之间的接口越小越好,最好只有 ...

最新文章

  1. 我国网络安全人才培养缺口巨大
  2. Mat与IplImage*类型间的转换
  3. quartz Cron-Expression的表达式
  4. Android官方开发文档Training系列课程中文版:动画视图之创建自定义转场动画
  5. ci/cd heroku_在GitLab上设置CI / CD以在Heroku上部署Python Flask应用程序
  6. lz0-007 读书笔记03
  7. curviloft插件怎么用_Curviloft插件下载
  8. Twaver-HTML5基础学习(33)自动布局
  9. 第二人生的源码分析(十四)人物角色的实现
  10. 戴尔笔记本安装双系统(win10+ubuntu20.04)避坑记录
  11. S4 BP供应商批导
  12. 办公技巧:如何快速提取办公文档里面的所有图片
  13. 如何让横坐标倾斜(Matlab画直方图)
  14. 弹簧物理-如何模拟弹簧和阻尼
  15. unity URP内置shader lit解析
  16. 模取幂运算 计算a^b mod n
  17. 第一课2021014615
  18. Windows常用的快捷键 让妹子办公效率速提升
  19. 自动洗车车牌识别系统
  20. Kaldi单步完美运行AIShell v1 S5之三:三音tri1,tri2,tri3,tri4,tri5

热门文章

  1. weblogic 12C集群环境下的session复制
  2. Cisco路由配置命令
  3. 浏览器并发连接数(转载)
  4. RDMA相关的技术网站
  5. 52)PHP,加了单例模式的数据库代码
  6. JSON.stringify(Data) 在IE8 里面不可用
  7. 作业4:结对编程项目四则运算
  8. JavaScript——创建运动框架
  9. 通过伙伴系统申请内核内存的函数有哪些?
  10. 管理博文Hive大数据-Mysql的安装和启动---大数据之Hive工作笔记0007