微服务概述
微服务越来越火,我也不自觉得加入到微服务的队伍里来了,可是对于微服务的具体概念好像还没有一个统一的定义,这里基于自己的理解,说说到底什么是微服务。
什么是微服务
首先微服务是相对于传统的单体系统而言,所谓的微,即为细小,粒度细小,需要参与的人员细小;服务,即为独立的功能单元,是用户感知的最小的功能集。
所谓的微服务架构也就是说把以前的独立、单一、巨大的系统拆分成粒度更小的多个或者多组服务,每个服务运行在自己的进程中,并使用轻量级机制通信(通常是HTTP API),这些服务基于业务能力构建,并能够通过自动化部署机制来独立部署,这些服务使用不同的编程语言实现,以及不同数据存储技术,并保持最低限度的集中式管理,并可以协调管理这些服务。
为什么需要微服务?
既然微服务是相对于传统类型的系统,那么为什么需要微服务,当然也是源于单体系统架构带来的问题。
单体架构在规模比较小的情况下工作情况良好,但是随着系统规模的扩大,它暴露出来的问题也越来越多,主要有以下几点:
- 复杂性逐渐变高
比如有的项目有几十万行代码,各个模块之间区别比较模糊,逻辑比较混乱,代码越多复杂性越高,越难解决遇到的问题。 - 技术债务逐渐上升
人员流动导致代码留下来很多坑,由于单体项目代码量庞大的惊人,留下的坑很难被发觉,由于系统耦合在一起导致后期坑很难填平,也就是所谓的技术债务越来越多。 - 部署速度逐渐变慢
代码多了,自然部署要慢 - 高度集中式管理
由于高度集中式管理,导致技术栈固定,老项目的改造成本会非常之大,比如某个项目使用struts2写的,由于各个模块之间有着千丝万缕的联系,代码量大,逻辑不够清楚,如果现在想用spring mvc来重构这个项目将是非常困难的。 - 无法按需伸缩
比如说电影模块是CPU密集型的模块,而订单模块是IO密集型的模块,假如我们要提升订单模块的性能,比如加大内存、增加硬盘,但是由于所有的模块都在一个架构下,因此我们在扩展订单模块的性能时不得不考虑其它模块的因素,因为我们不能因为扩展某个模块的性能而损害其它模块的性能,从而无法按需进行伸缩。
微服务与单体架构区别
- 单体架构所有的模块全都耦合在一块,代码量大,维护困难,微服务每个模块就相当于一个单独的项目,代码量明显减少,遇到问题也相对来说比较好解决。
- 单体架构所有的模块都共用一个数据库,存储方式比较单一,微服务每个模块都可以使用不同的存储方式(比如有的用redis,有的用mysql等),数据库也是单个模块对应自己的数据库。
- 单体架构所有的模块开发所使用的技术一样,微服务每个模块都可以使用不同的开发技术,开发模式更灵活。
简单的讲,就是降低了集中式管理和减少模块间的代码耦合。
微服务本质
有效的拆分应用,实现敏捷开发和部署 。
微服务缺点
- 运维要求较高
- 分布式的复杂性
- 接口调整成本高
微服务需要考虑的问题
客户端如何访问(Api Gateway)
一般情况我们去访问微服务都会通过多个层次结构,最终才能到达服务本身。这其中要经过路由、负载、api聚合、流控等一系列操作。
我们在这之间,通常会提供一个代理层(api gateway),它的作用包括:
- 提供统一服务入口,让微服务对前台透明
- 聚合后台的服务,节省流量,提升性能
- 提供安全,过滤,流控等API管理功能
这么多服务怎么查找?(服务注册中心)
在微服务架构中,存在着众多的服务,如果这些信息保存在每个客户端,则信息量庞大,不利于维护,如果有服务上线下线,则每个客户端都需要被感知,并做出响应(比如重启)。这样在生产中,几乎是不可能的。
所以基本上在架构中,都会有个注册中心,用于提供服务的注册于发现,并通过心跳维持服务在注册中心的状态。
服务之间如何通信?(服务调用)
- REST(JAX-RS,Spring Boot)
- RPC(Thrift, Dubbo)
- 异步消息调用(Kafka, Notify)
服务挂了怎么办?(容错)
当我们的系统是由一系列的服务调用链组成的时候,我们必须确保任一环节出问题都不至于影响整体链路。相应的手段有很多:
- 重试机制
- 限流
- 熔断机制
- 负载均衡
- 降级
负载均衡
常见策略如下:
- 随机
- 轮询
- 加权轮询
- IP Hash
- 最少连接数
容错策略
- 快速失败
服务只发起一次待用,失败立即报错。通常用于非幂等下性的写操作 - 失效切换
服务发起调用,当出现失败后,重试其他服务器。通常用于读操作,但重试会带来更长时间的延迟。重试的次数通常是可以设置的 - 失败安全
失败安全, 当服务调用出现异常时,直接忽略。通常用于写入日志等操作。 - 失败自动恢复
当服务调用出现异常时,记录失败请求,定时重发。通常用于消息通知。 - forking Cluster
并行调用多个服务器,只要有一个成功,即返回。通常用于实时性较高的读操作。可以通过forks=n来设置最大并行数。 - 广播调用
广播调用所有提供者,逐个调用,任何一台失败则失败。通常用于通知所有提供者更新缓存或日志等本地资源信息。
限流和降级
保证核心服务的稳定性。为了保证核心服务的稳定性,随着访问量的不断增加,需要为系统能够处理的服务数量设置一个极限阀值,超过这个阀值的请求则直接拒绝。同时,为了保证核心服务的可用,可以对否些非核心服务进行降级,通过限制服务的最大访问量进行限流,通过管理控制台对单个微服务进行人工降级
还没有评论,来说两句吧...