为什么使用微服务
项目前期使用单体应用没问题,但随着发展,单体应用越来越大,它会
- 启动时间越长
- 持续部署困难
- 对不同模块存在资源需求冲突,难以扩展
- 可靠性降低,越大的代码,一个bug,发生比如内存泄露,可能会拖垮整个进程
- 使用新框架和语言变得困难
什么是微服务
它的思路是将应用程序分解成一套较小的互联服务,每个实例通常是一个docker容器。在容器之前是负载均衡器,处理如缓存,访问控制,api度量和监控。每个服务都拥有各自的数据库。 优点:
- 它解决了复杂问题,把庞大的单体应用分解成一套服务
- 这种架构使得每个服务都可以由一个团队独立开发
- 可以实现每个微服务独立部署
- 可以独立扩展,满足所需的硬件要求
缺点:
- 微服务是一个分布式系统,会让系统变得复杂,需要处理基于消息或RPC的进程间通信机制
- 需要挑战的是分区数据库架构
- 测试复杂
- 需要另一个挑战是实现了跨服多服务变更,需要开发人员高度控制部署方式和高度自动化
- 使用自动化一是使用平台集服务(PaaS), 另一个是开发自己的PaaS,如Kubernetes
使用API网关
API网关是一个服务器,是系统的单入口点。API网关封装了内部系统架构,并针对每个客户端提供定制的API,还用于认证、监控、负载均衡、缓存和静态响应处理。 API网关负责请求路由、组合和协议转换。所有的客户端请求首先要通过API网关,之后请求被路由到适当的服务,api网关通常会调用多个微服务和聚合结果来处理一个请求。
所以API网关性能和可扩展性是相当重要的,所以api网关要建立在异步、非阻塞的平台上。api网关也要支持各种通信机制,如基于消息的异步机制,AMQP,同步机制,如HTTP。 api网关需要实现服务发现,也要解决局部故障。
进程间通信(IPC)
维度包括一对一,还是一对多,同步的还是异步的。
- 请求/响应, 客户端阻塞
- 通知, 客服端发送请求,但不要求响应
- 请求/异步响应,客户端发送请求,服务端异步响应,客户端不阻塞
- 发布/订阅,客户端发布通知消息,由消费者消费
- 发布/异步响应,客户端发布请求消息,之后等待一定时间来接收消费者的响应
服务发现
主要两种发现模式:客户端发现和服务端发现
客户端发现:客户端查询服务注册中心,它是可用服务实例的数据库。服务实例的网络位置在服务注册中心启动时被注册。当实例终止时,它将从服务注册中心移除。通常使用心跳机制周期性的刷新服务实例的注册信息。
服务端发现:如nginx负载均衡,SLB。
服务注册中心是服务发现的一个关键部分。它是一个包含了服务实例网络位置的数据库,必须是高可用和最新的,要使用复制协议来维护一致性。 比如etcd,一个用于共享配置和服务发现的高可用、分布式和一致的键值存储。
事件驱动数据管理
存储和查询文本的服务使用文本搜索引擎(如Elasticsearch),存储社交图数据的服务使用图数据库(如Neo4j),微服务通常混合使用SQL和NoSQL数据库。 通常每个微服务所拥有的数据对当前微服务来说是私有的,只能通过其提供的API进行访问。 分区的数据存储有很多优点,但引入分布式数据管理有以下挑战。
- 实现业务的事务在多个服务之前保持一致性
- 如何实现从多个服务中检索数据
使用事件驱动架构,微服务发生某些重要的事件,其他微服务订阅了这些事件,然后更新,可以通过消息代理进行交换事件。 实现原子性的一种方式是使用本地事务发布事件,在本地数据库建立一个用作消息队列的EVENT表,应用程序开启了一个数据库事务,更新了业务状态,将事件插入EVENT表,之后提交事务。然后查询EVENT,发布到消息代理,本地标记为已发布。另一种方式是挖掘数据库事务日志。 实现一致性可以用事件溯源。
部署策略
- 单主机多服务
- 单主机单服务
- 每个容器单服务
- serverless部署技术
微服务重构
- 不要大爆炸重写,应该逐步重构单体应用程序
- 停止挖掘,不要继续写单体应用,把新的应用微服务话,还要处理请求路由,旧的还是旧的,新的请求路由到新的服务,还有粘合代码,新的服务要用到旧的数据。可以调接口,直接访问,维护副本,同步。
- 前后端分离
- 提取服务,考虑如何提取模块
分布式和集群
分布式是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务。微服务是分布式。 集群是指在多台不同的服务器中部署相同应用或服务模块,构成一个集群,通过负载均衡设备对外提供服务。
参考
https://github.com/itswcg/Books/blob/master/%E5%BE%AE%E6%9C%8D%E5%8A%A1:%20%E4%BB%8E%E8%AE%BE%E8%AE%A1%E5%88%B0%E9%83%A8%E7%BD%B2.epub>