001-nginx:introduction-to-microservices系列

文献地址:https://www.nginx.com/blog/introduction-to-microservices/

01 Introduce to Microservices

Monolithic Application vs Microservices
微服务可以从三个维度看:X维度-横向复制扩展成多实例,Y维度-按照业务功能切分成不同的微服务,Z维度-数据存储分库分表扩展(这个表述可能不大准确)

微服务的优势:主要从开发、部署、扩展、运维的角度分析
1)把一个很大的应用拆分成多个微服务,微服务之间通过RPC或者消息队列相互通信。这样微服务更容易开发和维护
2)一个大的应用基本只能使用一套技术框架,拆分成微服务后,不同的微服务之间有了可以自由选择技术框架的可能性
3)微服务之间相互独立部署
4)单个微服务可以独立的扩展

微服务的缺点
1)微服务,那一个应用到底拆分成几个微服务合适呢,这是值得深思的一个问题
2)微服务之间通过RPC或者消息队列通信,通信的可靠性和消耗是一个值得思考的问题
3)微服务将数据库拆分,那么跨微服务跨库操作时就很难保证事务的强一致性,只能追求最终一致性了
4)测试会更加复杂一点,当测试涉及微服务之间的调用时,相互依赖的微服务都必须启动起来
5)当迭代需求涉及到多个微服务时,每个微服务都要更新,重新部署启动
6)部署微服务也变得更加复杂,包括监控、部署、扩展、拆分等等

总结:当业务很简单的时候,微服务的必要性没有那么大;当业务复杂的时候,微服务就显得很有必要了;所以随着业务的发展系统越来越复杂,需要提前考量引入微服务


02 Building Microservices:Using an API Gateway

当外部http请求微服务时,如何访问到对应的微服务系统?有以下两种方式:
1)每个微服务都暴露一个域名访问地址给外部,调用时采用:http://serviceName.api.company.name
这种方式显然不大合理。第一,每次新增一个微服务都要新增一个域名访问地址;第二,当将一个微服务拆分或者多个微服务合并的时候,都需要更改或者新增域名,相应的客户端调用的代码也需要修改
2)采用api网关,统一一个入口,由api根据前端访问地址决定访问哪个微服务,以及如何实现同一个微服务之间的负载均衡,还有根据规则如何路由到同一个微服务的不同环境中。

采用api gateway的优缺点:
优点:统一入口,方便管理,客户端只直接跟api网关通信
缺点:引入api网关,就多了一个服务,api网关服务的流量将是巨大的,对于api网关服务自身的性能和稳定性要求是很高的,一旦网关出问题,会导致同一个大系统下面的微服务都不可访问。

实现一个api网关的要素:
1)性能和扩展性
2)采用reactor设计模式,比如java nio的selector(reactor模式还要好好理解理解)

service invocation(服务调用)
微服务之间通信:异步:消息队列,如kafka;同步:rpc/http

service discovery(服务发现)
查询服务注册表,得到每个微服务-版本号-对应部署ip机器和端口号列表

handling partial failures(能处理部分失败)
降级等处理


03 Building Microservices: Inter-Process Communication in a Microservices Architecture

主要讲微服务之间是如何通信的,通信协议采用什么方式?
同步采用http/rest请求,异步通过消息队列通信;如果是一对多则采用消息发布订阅模式


04 Service Discovery in a Microservices Architecture

微服务中的服务发现-实际项目中主要用到的是zookeeper

为什么微服务要使用服务发现?
同一个微服务的不同实例是动态注册的,注册之后可能因为故障等原因而不可用,这就要求服务发现及时去发现并更新最新可用的实例,然后重新去做负载均衡等操作

服务发现的两种模式:Client-Side Discovery vs Server-Side Discovery

Client-Side Discovery
每个微服务都有一个服务发现客户端,如下图的Registry Client.
以单个微服务为例,微服务会注册到服务注册中心,服务注册中心会记录该微服务对应实例的ip和端口,然后通过心跳的机制定期检测服务器是否存活并定期更新微服务对应的实例ip列表。
对应的Registry Client只需要去注册中心读取实例ip列表即可,然后做负载均衡。
相当于每个微服务都需要一个前置的Registry Client.

Client-Side Discovery.png

Server-Side Discovery
请求统一通过一个入口,由一个load balancer 服务去统一从注册中心获取每个微服务的实例ip列表,然后决定如何负载均衡,nginx+就可以作为Server-Side Discovery(这个就是网关可以做的事)

Server-Side Discovery.png

The Service Registry-可以理解为一个存储微服务实例列表的数据库
服务注册中心:微服务注册到服务注册中心,由服务注册中心保存微服务的实例ip列表,通过心跳实时更新微服务实例ip列表

哪些可以作为服务注册中心:

  • Netflix Eureka
  • etcd:Kubernetes and Cloud Foundry
  • consul
  • zookeeper

Service Registry Options

  • The Self‑Registration Pattern: 微服务自己注册到注册中心,自己取消注册到注册中心;当然如果有必要可以定期发送心跳给注册中心,防止过期。有点Client-Side Discovery的意思


    The Self‑Registration Pattern.png
  • The Third‑Party Registration Pattern:采用第三方统一注册、取消注册服务,当某个微服务有新实例时,这个第三方服务会自动发现,当某个微服务实例不可用时通过healthcheck检测到,然后可以取消该注册服务。


    The Third‑Party Registration Pattern.png

zookeeper是通过心跳来取消注册的,当心跳停止一段时间后会从列表中自动删除对应的微服务实例


05 Event-Driven Data Management for Microservices
  1. 分布式数据管理问题:当一个请求跨微服务访问多个数据库时,由于一个微服务无法直接访问另外一个微服务的数据库,只能通过api接口访问,由于跨数据库操作就不能保证ACID了。

解决办法:事件驱动架构方式
大致的思想是将存在跨数据库的访问拆分成一系列事件流,一步一步往下执行(一个一个数据库操作往下执行),当某个步骤失败时,通过补偿的方式回滚之前提交成功的操作(回滚也是可能存在失败的),这种方式是以最终一致性为目标的,所谓的BASE而不是ACID

  1. 事件驱动如何保证原子性:插入一条数据到数据库+发布一个事件,可能存在插入数据库成功但是发布事件失败,导致不一致。

解决办法1:新增一张本地事件表,插入一条数据+插入一条事件记录在同一个本地事务中,然后开启另外一个线程从事件表中读取事件记录并发布,记得标记为已发布。当读取事件发布失败可以重试,比之前要改进很多
解决办法2:通过读取数据库的transaction log, 根据插入的数据记录异步发布对应的事件
解决办法3:采用一个事件保存源,每次都将事件追加,客户端去订阅事件源消费即可。


06 Choosing a Microservices Deployment Strategy

微服务部署方式

  1. 方式1:Multiple Service Instances per Host Pattern
    不同微服务部署在同一台物理机或者虚拟机上,通过不同的端口号区分;不同微服务之间不隔离,易相互影响产生问题

  2. 方式2:Service Instance per Host Pattern
    细分为两种方式:

    • Service Instance per Virtual Machine Pattern:每个虚拟机部署一个微服务
    • Service Instance per Container Pattern:每个容器部署一个微服务
      这样不同微服务之间资源是隔离的,可以指定每个微服务可用的CPU、内存等资源
  3. 方式3:Serverless Deployment
    无服务部署,如AWS Lambda, 不是太了解。。。


07 Refactoring a Monolith into Microservices

如何将一个大的应用拆分成微服务?

  • 第一步:停止继续将应用代码变得更多更复杂
  • 第二步:前后端分离
  • 第三步:抽取module成独立的微服务,根据业务功能、资源消耗等方面考虑
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339