微服务学习笔记

收藏学习七篇微服务系列的博文,点击标题查看原文内容。

优势与不足

  • 单体应用的主要缺陷
    随着应用不断地开发迭代、更新版本,单体应用的体量越来越大,造成以下问题:
    • 启动时间长:应用越大启动服务的时间越长,影响生产
    • 部署困难:以往大版本发布大多是在每月固定时间,临时性的小版本应急发布也需要审批,发布一个功能修改却需要停掉整个应用,并且需要事前事后大量的人工测试,无法实现单日内的多次修改上线,持续部署
    • 扩展性差:“如果单体应用的不同模块在资源需求方面有冲突的话,那应用的扩展也很难。”
    • 可靠性低:只要一处代码的bug,就有可能把整个应用拖垮
    • 代码架构修改困难

总的来说,很难适应敏捷开发和交付

  • 微服务出现
    将一个应用分为一整套体量小且相互关联的服务,为每个微服务提供独立的数据库,每个服务可以选择自己所需要的特定类型的数据库
    -优势

    • 复杂性降低:单体应用被分解成多个小型服务
    • 方便开发:每个服务可以单独团队开发,团队内部自行选择技术
    • 独立部署:每个服务可以单独部署,服务之间的部署互不影响
    • 独立扩展:每个服务可以独立使用各类资源进行功能扩展

    -不足

    • 分布式应用造成各服务之间的通信机制较单体服务复杂
    • 每个微服务独立数据库造成数据重复或同步问题
    • 测试需启动所有相关服务
    • “微服务架构模式应用的改变将会波及多个服务”
    • 众多服务的部署其实也是一个不小的工作,并不是很简单的事情(但也是复杂应用的首选

比较优势和不足,微服务应用和单体应用各有千秋,前者适合大体量的应用,后者适合小体量的应用。

API 网关

本篇聚焦客户端对微服务的访问方式,提出了两种可能的访问方式:

  • 客户端直接访问微服务:这种方法会面临1:N的访问,如果一个web页面包含N个服务,那就需要从客户端向N条请求(每条都要根据服务的不同,选择不同的适配协议),每个服务从众多的实例中分配一个相应,此种方法不仅请求响应耗时,同时不利于后续服务的重构(拆分/合并),并且部分服务对于http请求并不是特别友好,不是所有服务都适合从客户端直接发起请求
  • 由API代表众多微服务统一对外提供访问接口:通过统一的API网关,封装后面各个服务,对客户端形成的一种请求,自动完成转换(“服务请求路由、组合及协议转换”)。它的优点是对外封装了应用的各个服务,缺点是必须新,开发这样的API,但是相比优势,这样的缺点是可接受。

之后还需要考虑API与各个服务之间的通信,即如何让API发现这些服务,在微服务应用中,很难想传统应用那样直连,“应用程序服务的位置是动态分配的,而且,单个服务的一组实例也会随着自动扩展或升级而动态变化。”。

进程间通信

微服务之间的通信是基于进程的(Inter-process communication,IPC),从两个维度去理解服务之间的交互问题,一个是1对1/1对多,另一个是同步/异步。具体的IPC技术,文章描述了三种方式:

  • 基于消息的异步通信:因为是异步的,所以消息机制下客户端不需要等待服务端的及时响应,但是这样服务端在回复的时候需要指定特定的客户端id

  • 基于请求/响应的同步通信:因为是同步的,所以客户端需要等待服务端的及时响应,典型的例子就是REST API,存在阻塞的可能性,客户端也必须知道服务端的位置,即要有服务实例发现机制

  • 消息格式的选择

    • 文本:JSON和XML
    • 二进制

服务发现

本篇主要关注服务发现问题。在微服务应用中,客户端向服务端发起通信的前提是需要知道服务实例的地址,而基于云的微服务中,服务实例的地址通常是动态分配的,因此需要有特定的服务实例发现机制。有两种方式:

  • 客户端发现模式:客户端查询服务注册表,由后者完成服务位置的提供。这种方法对客户端要求较高,需要和服务注册绑在一起,“要针对服务端用到的每个编程语言和框架,实现客户端的服务发现逻辑”
  • 服务端发现模式:客户端通过一个负载均衡器再连接服务注册表,将请求转到相应的服务实例。这种方法相对于客户端发现模式,对客户端要求较低,“只需要简单地向负载均衡器发送请求,这减少了编程语言框架需要完成的发现逻辑”,但是对于负载均衡器又有了较高的要求。

上述两种模式都提到了服务注册表。服务注册表通过心跳机制,定时更新服务。服务注册由自注册模式和第三方注册模式,区别在于是否使用服务注册器。

数据管理

微服务存在每个服务使用和管理自己的数据库,相互之间访问受限,因此就涉及到了服务之间数据的协同管理问题:

  • 如何实现业务事务,保持多个服务的一致性
  • 如何从多个服务中检索数据,实现查询

使用事件驱动的架构来解决,服务之间发送各类事件,进而实现各自内部数据的更新

部署策略

本文关注微服务应用的部署。相比于单体应用的部署,微服务部署相对复杂,不再是把应用直接部署到一个或多个主机上那么简单。微服务应用一般会有很多个相互独立的服务,每个服务的开发技术、对资源的需求可能是不同的,同时每个服务所需的服务实例数目也是不同的,如何部署这些服务是本文所关注的。

  • 单主机多服务实例模式:一台主机(虚拟机)部署多个服务实例,其他主机(虚拟机)部署和这台相同服务的其他实例,即一台主机(虚拟机)上部署多个服务,一个服务的多个实例分布在多台主机(虚拟机)上。此种方式和传统的应用将多个实例部署在多个主机上差别不大,部署速度快,但无法限制主机内实例之间对资源的使用,并且运维团队需要提前了解主机中服务实例的部署情况。
  • 单主机单服务实例模式
    • 单虚拟机单服务实例模式:每个服务实例完全隔离运行,独占各自的资源,对外完全封装成为“黑盒”,但是每个服务实例依托的虚拟机需要额外给操作系统分配资源,同时虚拟机体量大,构建缓慢。
    • 单容器单服务实例模式:典型的代表技术Docker。“不同于虚拟机,容器技术更为轻量,容器镜像构建速度更快。由于没有冗长的操作系统启动机制,容器启动也非常迅速。容器启动,服务立刻运行。”
    • 无服务器部署:举AWS Lambda为例

应用的微服务改造

总的原则:逐步重构,先将微服务与单体应用的功能共存,之后将后者逐步替代。
先对新功能开发微服务,对于旧功能,提出拆分前后端的方法,但是也不是一个最终的办法,需要一种策略,即提取微服务,将单体应用的模块转化为微服务。为此,文章建议先确定好转化优先级,优先处理频繁更改的模块、资源需求(有的要求大内存/有的要求高计算量)大不相同的模块。
总的来说,还是需要具体项目的实践才更加直观。

posted @ 2020-03-12 17:15  旺得福000  阅读(137)  评论(0编辑  收藏  举报