互联网架构设计漫谈 (5)-搞清SpringCloud

微服务发展至今有许多公司都提供了架构来协助搭建微服务平台,比较著名的有 Dubbo,DubboX,Spring Cloud。今天带大家来了解一下Spring Cloud是如何搭建微服务平台的。

要点:

组件的分工协作

API网关: Zuul

服务负载:Ribbon

安全认证:Spring security

服务注册与发现: Eureka

链路跟踪:Sletuh与Zipkin

集群容错: Hystrix

网络调用:Feign

配置管理:Spring Config


组件的分工协作

  • 用户请求会最新发送给Zuul,Zuul是用来做API 网关的。由于,微服务会存在多个实例,所以请求被分发到哪个实例需要通过Zuul过滤器来完成。
  • 同时Zuul自带Robbin,其负责微服务集群的负载均衡工作。
  • 每个微服务的注册/注销操作通知Eureka,作为服务发现和注册中心,一方面记录服务的注册以及健康情况,一方面会协同Zuul做好服务访问的工作。
  • 服务如果自身出现问题,例如:业务异常,网络异常等等。需要通过断路器Hystrix来实现具体的处理操作,比如通知注册中心服务异常,比如对服务进行降级处理。这个时候服务注册发现中心会标记服务异常,再有请求过来就不会发送到有异常的服务上去了。同时服务发现注册中心也会定期检查服务的状态,一旦服务恢复状态又把其放到访问队列中。
  • 微服务之间是存在网络通讯的,需要把数据打包发送,接受以后也需要解包读取信息。这里可以使用Feign作为服务通讯的组件,配合Ribbon完成通信工作。
  • 微服务的数量随着业务的增常也会随之增长,用Sleuth可以做服务追踪,告诉服务管理者服务之间的调用关系。同时可以通过Zipkin UI界面查询到服务之间的关系。
  • 由于微服务众多,很多沟通方式都是通过发送和接受消息事件来完成的,所以RabbitMQ 就登场了,当然了市面上还有其他种类的MQ产品也可以替代之。这样的设计是为了让服务之间更好的解耦合。
  • 服务的参数配置需要由Spring Config 协助管理,特别是发布环境的变化,IP端口的控制等等。
  • 微服务多是分布式的,那么服务之间的同步就需要Reids 来协助完成,当然Redis 也可以用来作为分布式缓存。

API网关: Zuul

图片来自网络

Zuul中的请求过程,请求先传给Zuul Servlet,Zuul Servlet会维持一个Request Context,他是用来存储请求的数据并且保持Filter之间沟通的。之后Zuul Servlet 会把请求转发给 ZuulFilter Runner。ZuulRunner中有一个FilterProcessor是来管理所有的Filter,并且按照一定顺序来执行,在这里是支持filter 的热加载的,也就是说如果增加了filter的规则,可以通过加载filter 文件的方式让系统感知到。filter的处理顺序如下:

  1. Pre routing filters:在路由之前执行,在这里可以做鉴权,选择路由器,以及限流的操作,有些静态资源的响应也可以放在这里。
  2. Routing filters: 请求路由的实体。
  3. Post routing filters:在路由之后发生,用来做流量统计,监控,记录请求日志。

服务负载:Ribbon

Ribbon用来做负载均衡,一般会和Zuul配合使用,在服务之间调用的时候也会使用,其策略如下:

  • 随机 (Random)
  • 轮询 (RoundRobin)
  • 一致性哈希 (ConsistentHash)
  • 哈希 (Hash)
  • 加权(Weighted)

安全认证:Spring security

Spring security会根据不同的URL建立不同的filter 对其进行鉴权.

用户识别流程,当用户登陆的时候AuthenticationProcessingFilter去拦截请求,调用AuthenticationManager中的ProviderManager来得到用户信息,这个信息来源可以是多样的,比如说来自数据库或者服务。如果验证失败就拒绝访问,如果成功将用户的权限信息保存在User实例并放全局缓存SecurityContextHolder中保存,下次访问的时候可以继续使用。

资源访问权限流程,当请求URL的时候,AbstractSecurityInterceptor会拦截这个请求,他会调用FilterInvocationSecurityMetadataSource来获取被拦截url所需的权限,通过AccessDecisionManager获取Spring的全局缓存SecurityContextHolder的用户权限。

服务注册与发现: Eureka

Eureka用来做服务发现和服务注册,在Application Service(应用服务)上面运行Eureka Client(Eureka客户端)用来做服务的Register(注册),Cancel(取消),Renew(续约),以及Get Registry(获取其他应用服务注册信息)。Eureka Server 可以按照集群的方式来部署,每个Eureka Server 负责自己Zone(区域)的服务注册和发现工作。每个Zone(区域)的应用服务通过Eureka Client(Eureka客户端)来获取其他服务的注册信息。从而实现微服务之间的调用。

链路跟踪:Sleuth与Zipkin

Sleuth提供链路追踪。由于一个请求会涉及到多个服务的互相调用,而这种调用往往成链式结构,经过多次层层调用以后请求才会返回。常常使用Sleuth追踪整个调用过程,方便地理清服务间的调用关系。

每次请求都会生成一个Trace ID,如上图所示这个Trace ID 在整个Request 和Response 过程中都会保持一致,不论经过了多少个服务。这是为了方便记录一次调用的整个生命周期。再看每次请求的时候都会有一个Span ID,这里的Span 是Sleuth服务跟踪的最小单元,每经过一个服务,每次Request 和Response 这个值都会有所不同,这是为了区分不同的调用动作。针对每个调用的动作,Sleuth 都做了标示如下:

  • Server Received 是服务器接受,也就是服务端接受到请求的意思。
  • Client Sent 是客户端发送,也就是这个服务本身不提供响应,需要调用其它的服务提供该响应,所以这个时候是作为客户端发起请求的。
  • Server Sent 是服务端发送,看上图SERVICE 3 收到请求后,由于他是最终的服务提供者,所以作为服务端,他需要发请求发送给调用者。
  • Client Received 是客户端接受,作为发起调用的客户端接受到服务端返回的请求。

实际上Sleuth就是通过上述方式把每次请求记录一个统一的Trace ID,每个请求的详细步骤记作Span ID,每次发起请求或者接受请求的状态分别记录成, Server Received,Client Sent, Server Sent, Client Received 四种状态。来完成这个服务调用链路的跟踪的。

在调用服务的链路上每个被调用的服务节点都会通过Parent ID 来记录发起调用服务的Span ID,由于Span ID 是唯一确认最小服务单元的所以,知道了Parent 的 Span ID 也就知道了谁调用自己的了。

再来看看 Sleuth 和Zipkin 是如何协作,让服务之间的调用呈现给我们的。

Sleuth 会针对每个Trace 也就是每一个调用生成一条Trace 记录通过Instrumented Client 保存到 Instrumented Server,Zipkin 上面配置了Instrumented Server 的信息,通过自身的Collector 收集Trace 的信息,并且保存到本地的数据库。再通过API调用给前端的UI展示给最终用户使用。

集群容错: Hystrix

在分布式环境中,一个用户请求/服务会依赖其他服务,这些服务都有失效的可能。Hystrix通过隔离服务之间的访问,避免单个服务的故障影响到其他服务,并且提供回退和降级提高系统体可靠性。

会由于一个依赖服务的调用问题导致用户请求的调用被阻碍。

这些被用户请求所依赖的点都有可能因为各种原因导致故障。 比故障更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,影响队列,线程和其他系统资源,从而导致整个系统出现更多级联故障。

如果我们把上图修改成下图的模式,用Hystrix 对每个依赖的服务进行包装,让这些依赖想独立于其他的服务。即是某些依赖服务发生了问题也不会影响到其他的服务。同时可以针对异常进行处理。例如:服务无法访问,可以调用本地的缓存代替返回值,还可以用一些兜底数据。或者告诉调用错误代码。甚至可以通知服务注册中心。

网络调用:Feign

Feign 一个Http请求轻量级框架,可以以Java接口注解的方式调用Http请求,而不用像Java中通过封装Http请求报文的方式调用。当我们把对象在客户端和服务器端进行传递的时候都需要面对,填写URL,参数,对象加密,对象界面,请求重试等操作。Feign帮我们把请求模板化,当实际调用的时候,传入参数即可,方便我们的Http调用。

图片来源于网络

基本的工作流程如下:

  1. 生成请求的实现类
  2. 生成具体的请求体
  3. 包装请求
  4. 发送之前对请求进行装饰
  5. 记录发送/接受日志
  6. 请求发送/重试处理

配置管理:Spring Config

为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,您可以为所有环境中的应用程序管理其外部属性。它非常适合spring应用,也可以使用在其他语言的应用上。随着应用程序通过从开发到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。

Spring Cloud Config服务端特性

  • HTTP,为外部配置提供基于资源的API(键值对,或者等价的YAML内容)
  • 属性值的加密和解密(对称加密和非对称加密)
  • 通过使用@EnableConfigServer在Spring boot应用中非常简单的嵌入。

Config客户端的特性(特指Spring应用)

  • 绑定Config服务端,并使用远程的属性源初始化Spring环境。
  • 属性值的加密和解密(对称加密和非对称加密)

总结:

介绍Spring Cloud 落地微服务架构的总体设计,以及每个组件起到的作用。对于网关Zuul,注册中心Eureka,负载均衡Robbin,链路追踪Sleuth,断路器Hystrix的原理做了详细介绍。

互联网架构设计漫谈 (5)-搞清SpringCloud相关推荐

  1. 互联网架构设计漫谈 (6)-90%的架构师都知道的工作流原理

    互联网架构设计漫谈 (6)-90%的架构师都知道的工作流原理 工作流是互联网中常见的应用场景,目前国内有很多厂商提供各种各样的工作流引擎.在国际也有一些知名的工作流引擎,比如:jBPM 和 Activ ...

  2. 互联网架构设计漫谈 (4)-你知道微服务的“分与合”

    互联网架构设计漫谈 (4)-你知道微服务的"分与合" 业务高速发展的今天,单应用已经无法支撑庞大/复杂的业务系统.所以需要根据业务进行拆分,方便业务做扩容,并且增加大系统的团队协作 ...

  3. 互联网架构设计漫谈 (3)

    互联网架构设计漫谈 (3) 中小型互联网公司在并发量不高的情况下可以选用软件负载均衡作为代理层,他们通常和更靠外的"接入层"的硬件负载均衡器合作,为用户提供更好的服务.软件负载均衡 ...

  4. 互联网架构设计漫谈 (2)

    互联网架构设计漫谈 (2) 应用的接入层通常需要承载大量的网络请求,有些互联网企业几十万PV请求,在软件负载均衡无法支撑的情况下会考虑采用硬件负载均衡的技术帮助控制流量,然后再转发给软件负载均衡进行进 ...

  5. 互联网架构设计漫谈 (1)-概述

    互联网架构设计漫谈 (1)-概述 互联网已经在中华大地兴起多年,各种互联网架构也是层出不穷,抱着学习的态度在这里分享一下对互联网架构的一些理解,漫谈互联网架构设计. 系统架构图 上图想必大家都不陌生了 ...

  6. flowable工作流 流程变量_互联网架构设计漫谈 (6)-90%的架构师都知道的工作流原理...

    工作流是互联网中常见的应用场景,目前国内有很多厂商提供各种各样的工作流引擎.在国际也有一些知名的工作流引擎,比如:jBPM 和 Activiti. 他们都老牌的工作流引擎.同时都遵循BPMN 2.0的 ...

  7. 互联网服务架构设计漫谈(一)—设计考量点总览

    互联网服务架构设计漫谈(一)--设计考量点总览 1    概述 本文着重介绍在互联网应用服务器端的架构设计中需要关注的设计考量点,提供一个总览性认知.首先我们需要知道:不同类型的应用.不同用户规模和阶 ...

  8. 大型互联网架构设计踩坑

    下面是我总结的在大型互联网架构设计中实际踩过的坑简单总结,希望能给大家带来思考,避免重复踩坑: •参数未做校验导致内存溢出 •数据库死锁 •数据库/ Redis连接被打满 •数据库事务问题 •Redi ...

  9. 互联网架构设计中的poll和push

    poll方式 poll方式,也称为轮询,是大家都比较熟悉的一种数据同步方式,客户端定期去ping查询服务器,确定是否有需要的数据.例如,软件更新模块,客户端软件需要定期去查询官方网站,判断当前是否有更 ...

最新文章

  1. 20170215学习计划
  2. python多元线性回归模型_python – 使用Tensorflow的多元线性回归模型
  3. python有相关的证书可以考吗-python的证书
  4. Flume的Collector
  5. 【TensorFlow-windows】MobileNet理论概览与实现
  6. Redis之Ubuntu开机启动
  7. 这个城市快递外卖小哥将配电子号牌了,违法2起以上停止派单
  8. Height、offsetWidth、ClientHeight 区别
  9. CIA的海外间谍,要如何完美避开AI的监控?
  10. C#操作ini文件类
  11. [转]BAT 批处理脚本 教程
  12. 捋一捋Python中的数学运算math库之三角函数
  13. 近几个月Github上最热门的Java项目一览
  14. RandomAccess
  15. HECTF 部分wp
  16. 几种下载慢的解决办法
  17. nbsp; ensp; emsp; thinsp;zwnj;zwj; 6种空白空格的区别
  18. SAP所有模块用户出口(User Exits)
  19. 九重鸿蒙浮屠塔,浮图塔测算(浮图塔黄历老黄历)
  20. #yyds干货盘点#DHCP动态分配IP以及静态分配IP

热门文章

  1. 【好文链接】什么是光流
  2. 16位和32位微处理器(4)——Pentium的寄存器及相关机制
  3. (8)Linux内核中的hash与bucket
  4. java Launcher源码_Launcher3源码浅析(5.1)--Launcher.java
  5. centos6 yum源_Centos6安装Zabbix3.4.15注意事项
  6. latex使用记录3
  7. Jenkins系列之-—07 集成JIRA
  8. MySQL数据类型之BLOB与TEXT及其最大存储限制
  9. 数据结构与算法(八)-二叉树(斜二叉树、满二叉树、完全二叉树、线索二叉树)...
  10. Android 平板中 自己定义键盘(popuwindow) 居于屏幕左下方 仿微信的password输入界面...