从小白的角度去理解微服务框架 微服务技术
  • 创建时间:2023-02-27 / 最新修改时间:2023-02-27 09:30:40
  • 143744
  • 0
转载请注明本文出处:http://limpire.cn/artifact/programming/java/216.html


从小白的角度去理解微服务框架

微服务是什么

维基上对其定义为:一种软件开发技术- 面向服务的体系结构(SOA)架构样式的一种变体,将应用程序构造为一组松散耦合的服务。在微服务体系结构中,服务是细粒度的,协议是轻量级的。 微服务(或微服务架构)是一种云原生架构方法,其中单个应用程序由许多松散耦合且可独立部署的较小组件或服务组成。这些服务通常》

上面是在百度百科找的开场白。

微服务在离不开集群,而集群最大的作用就是高可用。 用通俗的语言来说就是

一台机器干不了的活分给2台机器或更多的机器去干,而挂了其中一台,活也能干出来。

从简单的家庭组网开始

一般来说,家里的网络设备都不会少,一般我们都会用一个路由器来组建我们的家庭网络。如下图: 图片.png

好,现在开始融入一个故事。 大雄家也是这样组网的。 大雄和静香结婚了,他们就这样天天享受着生活

某种角度上看服务

某天,哆啦A梦提出,想把家里变成一间创业的小公司,进行一些小买卖。 现在是信息时代,当然少不了电子产品的配合运营。 于是他们把设备这么分配使用。 图片.png

  • 简单采购流程 用电脑C2采购产品 -> 采购回来后用手机P2做入库记录 图片.png
  • 简单销售流程 接到订单 -> C1开销售订单 -> P2找到对应产品出库 -> 如果产生售后则用手机P1进行售后 图片.png

在这个过程中,4台设备都产生了信息之间的交流.

创业起步-数据只需要简单地共享execel文件

假设他们各自都用一个EXECEL表格去记录自己的信息。 ~~(注意,这里假设他们的execel表的数据都是各自独立的,也就是一个execel文件只记录一个范畴的数据。如果不是独立的,那么就没有所谓的“去中心化”。)~~ 例如: C1 记录销售的数据:金额,价格,客户,订购数量等等。 P2 记录个物品出入库记录,在库数量,出口数量等等。

现在用最简单的共享execel文件方法来做到各自数据的通讯。 已采购流程为例: 大雄从C2电脑中打开execel录入采购信息后,如何去更新仓库数量? 这里有2个方法:

  1. 找到P2手机,打开对应的execel录入刚才采购的物品的信息。
  2. 直接在C2中打开P2手机共享execel表,修改对应的数据。

当然99%的人都选择方式2,那么打开P2的共享需要有一个地址,假如是 ftp://192.168.1.3/1.xls 这里可以把这个地址理解成数据通讯的一个接口。 而完成这个采购业务需求的C2需要依赖P2才能完成。

需求增大

经过一段时间的经营,大雄家的生意越来越好,问题也出现了: 1.人手不够 2.一个设备挂掉导致工作无法开展 解决方法 请更多的员工,买配备更多的设备。 从此自己也成为了一个管理者。 图片.png

把他们看成服务

提升一个维度来看,我们分别可以把这些设备(正确来说就是程序+设备的组合)看成不同的服务,他们都是用来服务公司的运营的,公司运营都离不开这些服务:

  • C1 负责销售服务
  • C2 负责采购服务
  • P1 负责售后服务
  • P2 负责仓库服务

于是可以变成这样的关系: 图片.png

随着业务量的增大,变成了这样: 图片.png

精简模型

假设,大雄或其他员工出差了,需要远程下单。那么这图是不是可以变成: 图片.png

甚至可以概括为: 图片.png

现在请记住这两幅图的模型。

简单认识 SpringColud 微服务框架

SpringColud主要涉及的组件有:

  • Eureka:注册中心
  • Spring Cloud Gateway:服务网关
  • Ribbon:负载均衡
  • Feign:服务调用
  • Hystrix:熔断器

先抛开他们怎么用这个问题不讨论,先来看看他们各自的位置在哪里和扮演着什么样的角色。

Eureka 注册中心

试想一下,如果C1.1的服务当机了,工作如果自动切换给C1.2服务去做呢? 例如,大雄出差在外想使用公司内部的系统,如果他是直接连接C1.1这台IP,而C1.1当机了,怎么办?当然可以手动连接C1.2的机子,但是能不能有一个东西能自动帮大雄找到没有当机的设备呢? 如果把图片改变一下: 图片.png 我们把图片拆分来说明一下工作流程:

注册服务

图片.png 总体来说注册中心主要是为了知道某种服务的存在和知道它们的存活状态。

使用服务

使用这个服务可以是用户,也可以是其他服务(就像一开始说的,采购服务要依赖出入库服务一样),一般我们称为消费者。 在这个例子中,消费者是 大雄图片.png 得到订单地址的服务后,用户就可以直接连接这个地址。 图片.png (当然如果这个服务有UI层那么看到的就是一个界面,如果没有对于SpringCloud来说这可能就只是一个JSON.这是后话。)

失效剔除和自我保护

这是注册中心可以配置的两个功能

  • 失效剔除指的是把掉线的服务从注册中心剔除
  • 自我保护 就是再剔除服务之前等待一段时间,防止网络延时误杀。

具体放到下一章来说。这章不讨论这个,知道一下概念就行。

Ribbon 负载均衡

如图,有2个订单服务注册到 Eureka(当然两个订单服务都是做同一件事件) ,且它们俩都是存活的。 当我们使用这个服务的时候,假如有10个消费者使用订单服务。那么如何分配给这两个服务呢?

  • 平均分?一个服务去服务5个消费者。
  • 随机分?把10个消费者随机分给那2个订单服务。
  • 其他。。。

怎么分,那么就取决于均衡负载的策略了。这里不讨论策略,只讨论它们的位置和角色。 那么Ribbon就是做分配工作的这个角色。

举个例子: 采购服务依赖仓库服务,因为采购完后需要入库处理。 所以采购服务变成了消费者,而仓库服务变成了服务提供者图片.png 那么问题来了。我是用仓库服务1,还是仓库服务2? 如果我需要调用仓库服务10次,那么全部给仓库服务1,还是对半分? 当采购服务在迷惑的时候,Ribbon 在采购服务1的脑海中出现了。 图片.png 没错,Ribbon其实是安装配置在每个消费者中的。它就像军事一样能按照一定策略去指导消费者如何负载均衡的调用其他服务。

一开始,我以为因该由Eureka告诉消费者如何均衡调用服务,后来我明白了,Eureka只是注册中心,它没有提供均衡负载的思想给消费者(并不代表他自己没有,他只是不提供给别人这种思想)。 而每个作为消费者的服务都应该有自己的一套“均衡负载思想”。所以为什么Ribbon配置在消费者身上。 这种均衡负载更像是 主动式 而不是 被动式。

Spring Cloud Gateway:服务网关

上面很多图中,我都尽量保留了 路由器 这块图。 图中的路由器如果按一般组网设备来说,他就是一个物理路由器。 图片.png

于是我们可以把图分开两部分来看: 图片.png

那为什么我一直把路由器这部分保留呢?

  • 因为接下来我所说的 Spring Cloud Gateway 服务网关 他跟物理路由器很相似,都是一种属于对外网络的总出入口的一个东西。 图片.png

现在大雄的系统中添加了 Spring Cloud Gateway 服务网关

图片.png

服务网关也是一个服务,只不过它的角色地位显得比较前,可以把他看成是一个软路由,一个前端过滤器。跟物理路由一样,他主要是对外的,就是互联网的用户连接的时候总是先通过路由再通过我们的主机一样。 他的定位就是一个大型过滤器,软路由。

  • 地址的映射:例如把 http://192.168.1.1/user 映射到 http://192.168.1.2/user 这跟物理路由的端口映射很像。
  • 过滤器:例如请求参数的过滤,消息头的过滤等等。这些都是可以实现接口自定义过滤器的。

Spring Cloud Gateway 高可用

Spring Cloud Gateway 是一个服务,所以他也支持集群,支持高可用。 当多个服务网关注册到Eureka时就自动开启均衡负载Ribbon。但是这是对内的均衡负载。 例如:采购服务1 -> 服务网关-> 注册中心 -> 仓库服务X。 Gateway更多是外部访问,PC端、移动端等。它们无法通过Eureka进行负载均衡,那么该怎么办? 此时,可以使用其它的服务网关,来对Gateway进行代理。 比如:Nginx. 可以了解一下反向代理。

服务网关和Eureka的区别

服务网关和Eureka 都有一个相同的功能,就是映射地址。

  • Eureka 只是把地址告诉消费者,而不参与它们的数据转发。
  • 服务网关扮演着消费者和服务提供者直接的转发器,它们的数据交流总是经过网关服务的,从而达到映射地址的功能。
  • Eureka 更倾向于内部服务的互相调用
  • Spring Cloud Gateway 服务网关更倾向于外部访问。
  • Spring Cloud Gateway 是一个服务,它依赖Eureka,因为它也需要注册到Eureka。 图片.png

Hystrix:熔断器

跟均衡负载Ribbon一样,如果把服务看作一个实体,那么熔断器和均衡负载就是这个实体拥有的一种思想。 图片.png 如图:如果采购服务依赖的仓库服务都挂了,它该怎么办?

  • 如果一直等待是不是会造成阻塞,知道自己挂了。还是有个等待的时间?
  • 如果超过等待的时候我该怎么处理?

这就是 熔断器 做的事情的。 熔断器围绕3个概念来开展工作:

  • 线程隔离
  • 服务降级
  • 服务熔断

线程隔离:

Hystrix为每个依赖服务调用分配一个小的线程池,如果线程池已满调用将被立即拒绝,默认不采用排队,加速失败判定时间。 用户的请求将不再直接访问服务,而是通过线程池中的空闲线程来访问服务,如果线程池已满,或者请求超时,则会进行降级处理,即是服务降级。

服务降级

用户的请求故障时,不会被阻塞,更不会无休止的等待或者看到系统崩溃,至少可以看到一个执行结果(例如返回友好的提示信息) 。 服务降级虽然会导致请求失败,但是不会导致阻塞,而且最多会影响这个依赖服务对应的线程池中的资源,对其它服务没有响应。 触发Hystrix服务降级的情况:

  • 线程池已满
  • 请求超时

服务降级,我们可以先理解为:

try{
//调用其他服务超时或失败,或线程满了.
}
catch{
// 这里的代码就是服务降级的处理代码
}

只不过我们不用try。。。cath 去写服务降级,而是把服务降级的处理逻辑重构成一个函数出来而已。这样方便其他控制器也能公用这降级逻辑。

举个例子: 采购服务调用仓库服务。而仓库服务2台设备都挂掉了。如果采购服务的一个 降级方法就是 返回给消费者说,网络繁忙。 图片.png

  • 服务熔断 服务熔断比服务降级的范围要大,如果服务降级处理的是服务中的一个方法。那么服务熔断就是指整个服务的所有方法都别降级了。 假如仓库服务中有一个环节(方法)叫 入库,有一个叫 出库。 如果熔断服务检测到使用入库功能经常卡死或者超时,那么他会把出库功能也自动降级,然后慢慢地尝试恢复的这样一个机制。
  • 如果有电路基础的人就觉得 服务熔断 就像 自恢复保险丝。 在服务熔断中,使用的熔断器,也叫断路器,其英文单词为:Circuit Breaker 熔断机制与家里使用的电路熔断原理类似;当如果电路发生短路的时候能立刻熔断电路,避免发生灾难。在分布式系统中应用服务熔断后;服务调用方可以自己进行判断哪些服务反应慢或存在大量超时,可以针对这些服务进行主动熔断,防止整个系统被拖垮。 Hystrix的服务熔断机制,可以实现弹性容错;当服务请求情况好转之后,可以自动重连。通过断路的方式,将后续 请求直接拒绝,一段时间(默认5秒)之后允许部分请求通过,如果调用成功则回到断路器关闭状态,否则继续打 开,拒绝请求的服务。

看一张模型图: 图片.png

状态机有3个状态:

  • Closed:关闭状态(断路器关闭),所有请求都正常访问。
  • Open:打开状态(断路器打开),所有请求都会被降级。Hystrix会对请求情况计数,当一定时间内失败请求百分比达到阈值,则触发熔断,断路器会完全打开。默认失败比例的阈值是50%,请求次数最少不低于20次。
  • Half Open:半开状态,不是永久的,断路器打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放部分请求通过,若这些请求都是健康的,则会关闭断路器,否则继续保持打开,再次进行休眠计时。

图片.png

Feign 服务调用

这个像是一个工具类。主要用于内部的消费者从注册中心得到服务提供者的地址时,那么就可以使用Feign这个工具类去调用这个服务。 其实就是为这个远程方法创建了一个服务代理。 由于是工具类,只能留着下一章结合实际再说明。

Duboo 和 SpringCloud

Duboo也是微服务的一个框架。 先来看看它们之间的区别 图片.png Duboo 各种组件的作用跟SpringCloud差不多,只是实现和整合的方式不同。

Duboo的注册中心 Zookeeper

Duboo官方推荐使用Zookeeper做注册中心的组件。 注册中心的作用跟SpringCloud的Eureka一样。都是充当”电话本“使用。 Zookeeper之所以可以做成注册中心,并不是他本身的定位,它不是为做注册中心而生产出来的,只不过基于它的一些特性可以实现注册中心这个场景而已。

具体的 Duboo 将放到下一章介绍。

总结

无论是 SpringCloud 和 Duboo 也好,只要我们理解好微服务的大致模型,那么剩下的也就是配置和使用的问题了。

微服务优缺点

图片.png

架构说明:

  • 将系统服务层完全独立出来,抽取为一个一个的微服务。
  • 抽取的粒度更细,遵循单一原则。
  • 采用轻量级框架协议传输。

架构优点:

  • 服务拆分粒度更细,有利于提高开发效率。
  • 可以针对不同服务制定对应的优化方案。
  • 适用于互联网时代,产品迭代周期更短。

架构缺点:

  • 粒度太细导致服务太多,维护成本高。
  • 分布式系统开发的技术成本高,对团队的挑战大

从解决问题的角度去看微服务因该是这样的: 集群和高可用解决了 性能不足的问题。 微服务 解决了集群之间副作用,那就是如何做到松散组合,降低他们之间的耦合。且可控的颗粒度更小。


请说:

昵称 Email

评论:

2023-02-27 10:20:02

写得不错,学习了

不羁的风

***ifengde@163.com

吃不起海鲜就买海鲜味的酱油

回车换行很爽,代表着一个段落或者一个小结的完成,打印出来之后就是一个可触摸的成品.围着这种意境,一起来技术性打酱油.

文章列表
分类目录
友情链接