这是我参与「第五届青训营 」伴学笔记创作活动的第 5 天
微服务架构介绍
为什么系统架构需要演进?
- 互联网的爆炸性发展
- 硬件设施的快速发展
- 需求复杂性的多样化
- 开发人员的急剧增加
- 计算机理论及技术的发展
系统架构演变历史
-
单体架构
-
垂直应用架构
-
分布式架构
重点是抽出来的服务层(多了一层和业务无关的服务层)
但是单个服务bug会导致全部使用该服务部分崩溃
抽象了服务,但是不同服务之间的冗余无法去除(意思是说服务之间共通的部分?)
-
SOA架构
从SOA开始更加强调服务的概念
和上面其他的显著区别是多了一个服务注册中心,通过服务注册中心进行解耦
缺点是这样的结构还是中心化从上至下的,这样的设计在后期有重构需要的时候很麻烦,因为是从上至下设计的
-
微服务架构
微服务架构特点在于彻底的服务化。
和SOA的一个显著区别就是微服务架构是自下而上设计的,即我们设计单个服务的时候不会考虑上层调用方,而是先把服务搭建起来。
这样会有很高的开发效率,而且由于微服务架构服务粒度拆分很细,所以能起到故障隔离的效果。
微服务架构的缺点:由于微服务架构本身是一个拆分得很细的分布式系统,所以会有分布式系统对应的问题。
微服务架构核心要素
-
服务治理
- 服务注册
- 服务发现
- 负载均衡
- 扩缩容
- 流量治理
- 稳定性治理
- ......
-
可观测性
- 日志采集
- 日志分析
- 监控打点
- 监控大盘
- 异常报警
- 链路追踪
- ......
-
安全
- 身份验证
- 认证授权
- 访问令牌
- 审计
- 传输加密
- 黑产攻击
- ......
微服务架构原理及特征
基本概念
-
服务(service) 一组具有相同逻辑的运行实体。
(相同逻辑更通俗来说就是 代码是一样的,运行同一份代码;服务就是运行同一份代码的多个实例)
-
实例(instance) 一个服务中,每个运行实体即为一个实例。
-
实例与进程的关系 实例与进程之间没有必然对应关系,可以一个 实例可以对应一个或多个进程(反之不常见)。
-
集群(cluster) 通常指服务内部的逻辑划分,包含多个实例。
-
常见的实例承载形式 进程、VM、k8s pod .....”
-
有状态/无状态服务 服务的实例是否存储了可持久化的数据 (例如磁盘文件)
对应就是可不可以持久化,可以持久化的就是有状态的,而如果是作为代理形式的服务那往往就是无状态的
服务间通信上:
- 对于单体服务,不同模块通信只是简单的函数调用。
- 对于微服务,服务间通信意味着网络传输。
服务注册与发现
问题:在代码层面,如何指定调用一个目标服务的地址(ip:port) ?
-
第一种方法,直接代码中写死一个固定地址
缺点是:
-
对应地址可能会动态变化
-
实际上服务可能对应有多个地址
-
-
第二种方法,使用DNS
做法就是注册一个域名,然后DNS根据域名去查询对应的地址,这样就能过对应到多个地址了(一个域名可以有多个IP),地址也能够进行一定的动态变化,但缺点是:
- 本地DNS存在缓存,导致延时。
- 负载均衡问题。(应该就是DNS查询域名的时候并没有起到负载均衡的效果)
- 不支持服务实例的探活检查。(域名的IP挂掉了检查不出来)
- 域名无法配置端口。(域名对应的是IP,没有对应到port)
-
第三种方法:服务注册中心
解决思路:新增一个统一- 的服务注册中心,用于存储服务名到服务实例的映射。(简单说就是一个哈希表或者map)
相比前面方法的优点是:
- 服务注册的时候,注册的地址能够具体到端口了
- 代码调用的时候,只需要给到服务中心的地址
- 服务中心可以提供负载均衡的实现
服务实例上线及下线过程
假设有这样一个场景,有serviceA和B有一个三对三点服务调用关系(分别有三个实例,然后A中每一个实例调用B中的每一个实例)
此时在serviceB中,我们要对其中一个实例进行下线操作(比如出问题要下线)
如果此时实例直接下线,那么此时前面serviceA中调用过来的流量就直接失败了,这样是不行的,会导致线上场景的故障。
这里最好基于服务发现来操作,也就是在服务发现中心将要下线的实例地址去掉,这样后面的流量会转到其他两个实例中,等过了一定时间延迟后,再下线对应实例。
同理,在实例上线的时候,我们先进行实例添加和health check等操作,最后再于服务中心中进行对应地址的映射。
流量特征
- 统一网关入口
- 内网通信多数采用RPC
- 网状调用链路