这是我参与【第五届青训营】伴学笔记创作活动的第8天
微服务架构原理及特征
基本概念
- 服务(Service):一组具有相同逻辑的运行实体
- 实例(instance):一个服务中,每个运行实体即为一个实例
- 实例与进程的关系:实例与进程之间没有必然的对应关系,可见一个实例可以对应一个或多个进程(反之不常见)
- 集群(cluster):通常指服务内部的逻辑划分,包含多个实例
- 常见的实例承载形式:进程、VM、k8s pod ......
- 有状态/无状态服务:服务的实例是否存储了可持久化的数据(例如磁盘文件)
如果把 HDFS 看做一组微服务,NameNode和DataNode应该看做两个不同的微服务
服务间通信
- 对于单体服务,不同模块通信只是简单的函数调用
- 对于微服务,服务间通信意味着网络传输
服务注册及发现
在代码层面,如何指定调用一个目标服务的地址(ip:port)?
// ServiceA wants to call serviceB
client := grpc.NewClient("10.23.45.67:8080")
实际开发中不太可能指定一个固定的ip地址,真实的微服务环境中是会动态变化的,同时一个服务里可能会有多个实例,这样只指定一个实例肯定是不行的
在代码层面,如何指定调用一个目标服务的地址(ip:port)? DNS?
- 本地 DNS 存在缓存,导致延时
- 负载均衡问题
- 不支持服务实例的探活检查
- 域名无法配置端口
解决思路:新增一个统一的服务注册中心,用于存储服务名到服务实例的映射,简单理解即是一个哈希表
服务实例上线及下线过程
此时若把instance-3进行下线,在下线之前,现在服务注册中心将instance-3对应的信息删除,经过一定的延迟,此时只会调用前两个实例
当两个实例的压力过大时,此时要重新添加一个实例,先把该实例启动,再把该实例注册到服务注册中心中
流量特征
- 负载均衡、统一网关入口
- 内网通信多数采用RPC,外部采用HTTP
- 网状调用链路
核心服务治理功能
服务发布
服务发布,即让一个服务升级运行新的代码的过程
服务发布的难点
服务不可用:服务提供者A服务的访问压力过大,或者是网络原因,硬件原因等等多种因素,造成了服务提供者的不可访问
服务抖动:某个实例下线后再上线造成流量消失,短暂不可用
服务回滚:比如之前的代码没问题,升级后的代码有问题,这样先回滚到之前代码的状态,再进行bug修复,将损失降到最低
蓝绿发布
假设要升级服务B,那么把服务B的所有实例分为两个集群,两个集群的发布时分别进行的,比如先发布绿色部分的集群,那先把这部分的流量关掉(不是真的关掉而是,切换到蓝色的集群),然后再发布蓝色部分的集群,把这部分流量关掉
优点是简单、稳定,缺点是需要两倍资源
灰度发布(金丝雀发布)
先添加一个新的实例,若运行正常,则下线一个老的实例,然后再上线一个新的实例,依次类推
流量治理
在微服务架构下,我们可以基于地区、集群、实例、请求等维度,对端到端流量的路由路径进行精确控制
负载均衡
负载均衡(Load Banlance)负责分配请求在每个下游实例上的分布
常见的 LB 策略:
- Round Robin
- Random
- Ring Hash
- Least Request
稳定性治理
线上服务总是会出问题的,这与程序的正确性无关
- 网络攻击
- 流量徒增
- 机房断电
- 光纤被挖
- 机器故障
- 网络故障
- 机房空调故障
微服务架构中电信的稳定性治理功能
- 限流
- 熔断
- 过载保护
- 降级
总结
当今微服务架构已然是绝对的主流,通过微服务架构模式我们可以将问题拆分为足够小的应用,使得我们更容易控制,通过学习微服务架构的基本原理,更有助于我们对其的使用和理解,同时结合微服务治理平台,能帮助我们更好的解决实际应用中的问题。