一、单体架构存在的问题
缺点:
1、难以维护:当单体应用业务不断迭代后代码量非常臃肿,模整个项目非常复杂,每次更改代码都可能带来新的bug;
2、部署项目麻烦:庞大之后项目部署效率低,每次升级都需要全部构建打包部署;
3、扩展能力受限:集群只能复制整个系统,即使是某个模块压力很大,无法根据业务模块需要进行伸缩,计算密集型和IO密集型只能部署在一起,硬件成本加大;
4、技术选型受限:只能采用同一种语言,很难根据不同业务需求开发不同的模块;
综上,随着业务需求的发展,功能的不断增加,单体架构很难满足互联网时代业务快速变化的需要,为了解决这些问题,所以微服务架构开始变得流行了。
二、微服务架构
什么是微服务
国外架构师Martin Fowler在他的博客中这样描述微服务:
https://martinfowler.com/microservices/
微服务架构的特点:
1、每个小型服务都跑在独立的进程中;
2、可通过自动部署机制进行独立部署;
3、服务是松散耦合的,服务被拆分后,服务之间没有很强的依赖关系;
4、服务之间采用轻量级通信(通常有文本协议:http+json数据格式,更轻的二进制协议:grpc+protocol buffer);
微服务架构的优点:
1、易于开发和维护:一个服务只会关注一个特定的业务,业务依赖减少,代码量较少;
2、部署容易:某个业务的修改只需要重新部署这个服务;
3、扩展性提高:可以根据业务需求进行细粒度扩展,比如某个业务访问量加大只需要升级这个微服务的服务器性能或者增加新的节点;
4、技术栈比较灵活:可以根据不同业务选用不同的语言或数据库,比如面对并发比较高的业务可以选用go语言提供服务;
综上所述,在面对业务变化很大,系统越来越庞大的时候,单体架构表现的全是缺点,而微服务都是优点。
微服务架构带来的问题:
使用微服务构建的是分布式系统,带来了很多问题,例如跟踪、测试、部署、分布式事务、服务治理等,增加了开发难度和运维成本
三、微服务架构中重要的组件
API网关
为什么需要API网关:
1、客户端如果直接请求后端微服务,后端服务是十分松散的,这样会增加客户端的调用复杂度,所以需要API网关把后端服务的接口统一起来;
2、API网关的路由转发功能可以把客户端对后端服务调用完全解耦,后端服务变化不用调整客户端;
3、API网关有统一认证、负载均衡、流量限制等这些功能,可以有效的保护后端服务;
4、在面向不同客户端时,可以增加不同的API网关,而不需要调整微服务;
API网关一般会具备的功能:权限认证、流量控制、路由转发、负载均衡、熔断保护、缓存、日志记录等。
下图是API网关与后端微服务的工作流程:
下图是API网关面向不同客户端的调用:
服务注册与发现
在微服务架构中,每个服务都有自己的IP、Port信息和上线下线状态,这就需要一个服务治理中心来管理这些服务。 服务注册与发现组件就是系统内部的DNS服务,服务调用者通过服务名称从注册中心解析到IP和Port再完成服务直接调用。 每个服务一上线就会注册到服务治理中心,同时服务治理中心也会通过心跳检查每个服务的健康状态。
服务注册与发现组件有很多,例如Euraka、Consul、ZooKeeper、Etcd等。下图是基于Consul的注册与发现架构图:
上面就是注册与发现的架构图,从上图中会发现几个问题,
1、每次请求都要请求Consul服务器性能并不高,可以在请求时对注册表做缓存,由定时器定时去拉取注册表来更新缓存,这样即解决了性能问题也保证高可用的注册与发现服务真的不可用也不影响服务之间的调用;
2、由于加了缓存,就会出现缓存更新不及时的情况,这样就会请求到下线的服务器导致请求失败,这就需要容错组件了,当请求到不可用的服务时需要做出超时、失败转移、重试等这些策略。
容错组件
为什么需要容错组件:
微服务架构的应用系统都是通过网络进行通信,网络往往会有不可靠性,所以微服务之间的调用并不是100%可用,而微服务之间难免会存在依赖关系,一旦发生某个服务不可用都有可能引发级联故障,导致整个应用不可用,这个就是“雪崩效应“”。
为了防止雪崩效应,所以我们必须有一套强大的容错机制,容错组件应该包含以下几点:
1、网络超时:当网络请求达到设定的超时时间时,让资源尽快释放;
2、熔断器:当请求异常次数达到设定值时打开熔断器,让请求直接返回失败,这样有效提高服务的响应效率也能保证别的服务不受影响,当熔断时间一过自动关闭熔断器让服务恢复正常使用;
3、重试机制:在网络调用中有时会存在部分服务提供者不可用的情况,当第一次请求失败时再重试时又能恢复正常,这样保证接口成功率,减少用户请求,也可以设置重试其他节点服务以实现失败转移效果;
4、服务降级:当部分服务不可用时为了不影响用户正常使用可能会降级返回设定好的结果,以提升用户体验;
比较有伸缩性的容错策略为:网络超时->熔断->重试。
具体实现的组件java有Hystrix,.net core有Polly。
熔断器就像是生活中的保险丝,保护用电安全,下图是熔断器的调用过程图:
统一配置中心
对于传统的单体应用,通常使用配置文件来保存所有配置,如果有多套环境,可以设定多个配置文件不同环境启用不同的配置文件,而在微服务架构中,由于服务特别的多,一旦配置发生变化,修改配置是件很麻烦的事情而而且手动修改很容易出现漏改的现象,这就需要集中管理配置。
统一配置中心需要满足如下需求:
1、系统运行期间可以动态调整而不用停止微服务;
2、配置更新后可以自动更新到各个微服务中去;
配置中心架构图:
具体实现配置中心可以使用ZooKeeper、Redis、RabbitMQ等。
服务跟踪与监控
为什么需要服务跟踪:
服务之间通过网络进行通信,由于会存在网络不可靠和网络延迟等网络问题,我们的服务调用就会因为网络问题引发很多异常,为了能跟踪每个请求,了解请求经过哪些微服务、请求耗费时间、网络延迟、业务处理时间等指标,那么就能更好的分析系统性能和瓶颈、解决系统问题。
服务跟踪的实现:
所有请求在进入API网关请求头就带上一个traceid,用来标识请求并记录请求开始处理时间和转发时间等,在服务调用之间也会带上traceid并记录所有的请求时间和信息,这样所有经过的服务都会记录到到请求,最后通过可视化工具提供服务跟踪查询。
服务监控:
一个正在运行的系统少不了监控系统的存在,当我们的服务器出现CPU、内存负荷高或者我们的业务代码出现警告或异常记录时,通过采集完整的服务器和微服务运行日志来监控每个微服务的运行状态,设置一定策略实现提前预警。