微服务学习笔记

微服务架构与SOA(service oriented architecture)面向服务架构的关系?
两者都是将业务系统拆分成各个服务并通过合适的技术完成服务的集成。微服务架构和SOA的最主要区别在于架构面向的目标。SOA通常面向的目标是企业级应用,通过SOA我们寄希望于将多个系统整合在一起,从而消除信息孤岛。而微服务架构则更多地关注于一个独立系统的架构,可以认为是传统模块化技术的一种替代方案。

微服务架构的设计:
一、基础性功能组件:(API网关和配置管理是微服务架构区别于一般分布式系统的特有组件)
1.服务通信
1)网络连接:基于TCP的网络连接(连接建立三次握手,释放连接四次握手),有两种方式:短连接(客户端与服务端完成一次读写后,关闭连接),长连接(客户端和服务器端完成一次读写之后,连接不会主动关闭,可以连续发送多个数据包)。
2)IO模型
3)可靠性
常见的网络通信保障手段包括
a.链路有效性检测(通用做法:心跳检测。有两种技术来实现:在TCP层通过建立长连接在发 送和接收方之间传递心跳信息;在应用层,心跳信息根据系统要求可能包含一定的业务逻辑)
b.短线之后的重连(发送方检测到通信中断后,在事先约定好的重连间隔时间之后发起重连操作,如果重连失败,则周期性使用该间隔时间进行重连直至重连成功)。
4)同步与异步
a.同步调用(服务线程发送请求到IO线程之后就一直处于等待阶段,直到IO线程完成与网络的读写操作之后被主动唤醒)。
b.异步调用(JDK为我们提供了Future模式实现异步调用)。
2.事件驱动
3.负载均衡
1)服务器端负载均衡(例Nginx)
在客户端和各个微服务实例之间架设集中式的负载均衡器,。负载均衡器运行在一台独立的服务器上并充当代理(Proxy)的作用,。所有请求都需要通过负载均衡器的转发才能实现服务调用。
2)客户端负载均衡(在客户端程序中,自己设定一个调度算法,在向服务器发请求时,先执行调度算法计算出目标服务器的地址)。
优势:不会出现集中式负载均衡所产生的瓶颈问题,因为每个客户端都有自己的负载均衡器。
缺点:由于所有运行时的信息都需要在多个负载均衡器之间进行服务配置信息的传递,会在一定程度上加重网络流量负载。
3)负载均衡算法(不论是服务端负载均衡还是客户端负载均衡,运行时的分发策略在软件负载均衡中体现为一组分发算法,有两大类)。
a.静态负载均衡算法(代表是随机(random)和轮询(round robin)算法)
使用JDK自带的random随机算法就可以指定服务提供者的地址。随机算法的改进:加权随机算法,为了使集群中性能较优的服务器响应更多的请求,通过加权随机算法来提升这些服务器的权重。
b.动态负载均衡算法(上述静态负载均衡算法中的权重在运行过程中动态更新)
类似的动态算法:最少连接数(Least Connection,对传入的请求根据每台服务器当前打开的连接数来分配)、服务调用时延(Service Invoke Delay,服务消费者缓存计算所有服务提供者的服务调用时延,根据服务调用和平均时延的差值动态调整权重)。
4.服务路由(客户端请求到达集群,如何确定由某一台服务器进行响应就是服务路由问题,负载均衡也算是一种路由方案)
1)直接路由(服务的消费者需要感知服务提供者地址信息。服务消费者通过配置中心或数据库来获取服务提供者地址,当服务消费者需要调用某个服务,基于配置中心或数据库中存储的目标服务的具体地址来构建链路完成调用)
缺点:消费者直接依赖提供者的具体地址,一旦运行时提供者改变地址无法第一时间通知消费者;创建和维护配置中心或数据库持久化操作同样需要成本。
2)间接路由(解耦思想,发布-订阅模式Publish-Subscribe。实现简介路由的组件一般称为服务注册中心。服务提供者发布服务到服务注册中心,服务消费者订阅感兴趣的服务。服务消费者只需要知道有哪些服务,不需要知道服务的地址,从而实现间接路由。提供者地址发生变化,注册中心推送服务变化到消费者确保消费者使用最新的地址路由信息。同时,为了提高路由的效率和容错性,消费者可以配备缓存机制以加速服务路由,当服务注册中心不能用的时候,服务消费者利用本地缓存路由实现对现有服务的调用。)
3)路由规则(黑白名单、条件脚本)
5.API网关(本质是一种外观模式(设计模式中的一种,为子系统中的一组接口提供一个一致的入口,这个入口使得这一子系统更加容易使用)的具体实现,是一种服务器端应用程序并作为系统访问的唯一入口。API网关封装了系统内部架构,为每个客户端提供一个定制的API。在微服务中,所有的客户端和消费端都通过统一的网关接入微服务,在网管层处理所有的非业务功能)。
1)网关的作用:
a.解耦
b.API优化(API网关为每个客户端提供最优的API)
c.简化调用过程(例如API网关使得客户端可以在一次请求中向多个服务拉取数据)
2)网关的功能(挖掘其具备的核心功能来实现上述的作用)
a.NIO接入和异步接出
b.报文格式转换
c.安全性控制
d.访问控制
e.业务路由支持
6.配置管理(微服务引入配置中心的设计思想和相关工具)
1)配置中心模型
配置中心(一种统一管理各种应用配置的基础服务组件)
2)分布式协调机制
配置中心在是线上需要满足:高效获取、实时感知、分布式访问。为达到以上要求就需要依赖分布式协调机制,业界主流分布式协调框架Zookeeper。Zookeeper对每个节点都可以设置监听器,当某一个节点的信息有变动,监听该节点的其他节点就可以实时获取通知,并作出响应。对于配置中心而言,所有服务就是Zookeeper的客户端,这些服务通过监听包含了配置信息的zookeeper节点就能获取配置信息的更新内容
二、架构实现上的关键要素(保证微服务架构高效、稳定以及正确运行的问题)
1.服务治理(如何提升服务架构的可拓展性,如何进行服务监控和故障定位,如何实现对服务的有效划分和路由。服务治理是应对这些挑战的统一方法。在技术实现上,服务治理一般表现为服务发布与订阅机制以及实现该机制的服务注册中心)
1)服务注册中心(服务注册中心是路由信息的存储仓库,也是服务提供者和服务消费者进行交互的媒介,充当着服务注册者和发现服务器的作用)。
a.注册中心核心功能:发布-订阅功能、高可用性(意味着注册中心本身需要构建对等集群,即集群中所有的服务器都提供同样的服务。)、作为注册中的客户端程序,一般会嵌入在服务提供者和服务消费者的应用程序中。(服务提供者的注册中心客户端程序会向注册中心注册自身提供的服务,消费端会查询订阅的服务并周期性刷新服务状态)。
b.注册中心实现策略
2)服务发布与注册(服务发布的目的是为了暴露服务访问入口)
发布启动器->动态代理->发布管理器->协议服务端
3)服务发现与调用(服务的调用是一个导入的过程)
调用启动器->动态代理->调用管理器->协议客户端
4)服务监控
2.服务数据一致性
1)分布式事务
3.服务可靠性
在分布式环境中,我们经常使用服务容错来确保服务调用的可靠性。但除去服务容错还应该有服务隔离、服务限流和服务降级

1)服务访问失败的原因
a.硬件失败
b.分布式环境的固有原因
c.服务自身失败
d.服务依赖失败
重点(服务访问雪崩效应):A服务是提供者,B服务是消费者,首先A服务发生不可用,然后B服务重试加大流量,最后导致B服务自身也不可用。
2)服务失败的应对策略(对服务提供者而言,自身服务发生错误,应快速返回合理的处理结果;对服务消费者,重点关注不要被服务提供者所产生的错误影响到自身服务的可用性)。
a.超时(调用服务的操作可以配置为执行超时,如果服务未能在这个时间内响应,将恢复一个失败消息)
b.重试
c.异步耦合(使用一些中间件系统来实现服务提供者和消费者之间的异步解耦)
3)服务容错(容错机制的基本思想是冗余和重试,即当一个服务器出现问题时不妨试试其他服务器,集群满足了冗余,所以围绕重试介绍集中集群容错策略)
a.Failover:失效转移,就是当发生服务调用异常时,重新在集群中查找下一个可用的服务提供者。.
b.Failback:失败通知,服务调用失败时直接将远程调用异常通知给消费者
c.Failsafe:失败安全,当获取服务调用异常时,直接忽略。可以理解为一种简单的熔断机制
d.Failfast:快速失败,获取服务调用异常时,立即报错。放弃了重试,等同于没有容错。
e.Forking:分支机制,并行调用多个服务器,一个成功就返回
f.Broadcast:广播机制,逐个调用所有提供者,任意一台报错则报错。
4)服务隔离(本质上是对系统或资源进行分割,发生故障后只有出问题的服务不可用,其他的服务仍然可用)
a.线程隔离:主要通过线程池进行隔离。把业务进行分类交给不同的线程池进行处理
b.进程隔离:将系统拆分为多个子系统来实现物理隔离,各个子系统运行在独立的容器和JVM中。
c.集群隔离:将某些服务单独部署成集群,某个集群出现问题之后不会影响其他集群。
d.机房隔离:多机房部署
e.读写隔离:当读取操作的服务器出现故障时,写服务器照常可以运行,反之也一样。
5)服务限流
a.计数器法:通过限制某个服务在单位时间内的调用量来进行限流,实现简单,但有临界问题
b.滑动窗口法:
c.漏桶算法:不管突然流量有多大,漏桶都保证了流量的常速率输出。
d.令牌桶算法:原理是系统会以一个恒定的速度往桶里放入令牌,如果请求需要被处理,需要先从桶里获得一个令牌,当桶里没有令牌可取时,拒绝服务。
漏桶算法和令牌桶算法的区别是漏桶算法能够强行限制数据的传输速率,而令牌桶算法在限制传输速率的同时还允许某种程度的突发传输。
6)服务降级(在服务器压力剧增时,根据当前业务情况及流量对一些服务有策略的降级,以此释放服务器资源以保证核心任务的正常运行)
a.服务分级:对每个服务进行等级管理之后,降级一般是从最外围、等级最低的服务开始。
b.服务熔断:熔断器三种状态:Closed(熔断器关闭,不对服务调用进行限制,但是对调用失败的次数进行限制,到了阈值或一定比例启动熔断机制)、Open(熔断器开启,此时对下游的调用内部直接返回错误,不走真正的网络调用。同时熔断器设计了一个时钟选项,时钟达到了一定时间,进入半熔断状态)、Half-Open(半熔断状态,允许定量的服务请求,如果都调用成功或达到一定比例,则关闭熔断器,否则认为链路还是存在问题,回到熔断器打开状态)
服务熔断和服务降级的区别:首先两者触发条件不同,服务熔断是某个下游服务出现故障所导致,而服务降级一般是从整理负荷考虑;其次,管理目标的层次也不同,熔断是一个框架级的处理,每个微服务都需要,无层级之分,而降级一般需要对业务有层级之分,比如降级一般是从最外围的服务开始。
三、微服务架构实现技术
1.实现技术选型
1)核心组件完备性(微服务的核心组件由服务通信、事件驱动、负载均衡、服务路由、API网关和配置管理组成)。
2)微服务实现框架对比
a.Dubbo(RPC架构,包括高性能通信、多协议集成、服务注册与发现、服务路由、负载均衡、服务治理等核心功能。但API网关、服务熔断器等核心组件并没有)
b.Spring Cloud(功能比Dubbo完备,并且微服务架构推崇基于协议HTTP的RESTful风格实现服务间通信,Spring Cloud就是使用这种方法,而Dubbo的服务调用通过RPC实现。采用RPC方式会导致服务提供方和调用接口方产生较强依赖。)
在这里插入图片描述
2.Spring Boot
1)Spring Boot核心原理
@SpringBootApplication(@Configuration(提供JavaConfig配置类实现)、@ComponentScan(扫描@Component等注解)、@EnableAutoConfiguration)
@EnableAutoConfiguration(@Import(value=EnableAutoConfigurationImportSelector.class)
EnableAutoConfigurationImportSelector类依赖的最关键组件是SpringFactoriesLoader。要想理解SpringFactoriesLoader类,首先需要了解JDK中的SPI(service provider interface,服务提供者接口)机制。JDK提供了服务实现查找的一个工具类java.util.ServiceLoader来实现SPI机制。
EnableAutoConfiguration中包括了各式各样的配置项,这些配置项在Spring Boot启动过程中都能够通过 SpringFactoriesLoader加载到运行时环境,从而实现自动化配置。
Spring Boot为我们提供了数据访问、消息传递以及内置的监控系统等功能。但是,服务注册和发现机制、外围服务监控、服务熔断和服务治理等功能是Spring Cloud提供的。
3.Spring Cloud
1)Spring Cloud Netflix Eureka基本架构(一个基于REST的服务注册中心,用于定位服务以及提供中间层服务器的故障转移)
1.1)该架构由三个逻辑角色组成:Eureka Server(提供服务注册与发现)、Service Provider(服务提供方,将自身服务注册带Eureka,从而使服务消费者能找到)、Service Consumer(服务消费方,从Eureka获取注册服务列表,从而实现消费服务)。
在这里插入图片描述

首先Service Provider会向Eureka Server提交服务管理相关操作;而Eureka Server之间会做注册服务的同步,从而保证状态一致;同时,Service Consumer会向Eureka Server获取注册服务列表,并消费服务。
Register:服务注册,当Eureka客户端向Eureka Server注册时,它提供自身的元数据,如IP地址、端口号、运行状况指示符URL等信息。
Renew:服务续约,Eureka客户端会每隔30秒发送一次心跳来进行服务续约。通过续约来告知Eureka Server该客户端仍然存在,希望服务器端不要剔除自己。
Cancel:服务下线,Eureka客户端在程序关闭时向Eureka服务器发送取消请求。发送请求后,该客户端实例信息将从服务器的实例注册列表中删除。
Eviction:服务剔除,默认情况下,Eureka客户端联系90秒没有向Eureka服务端发送服务续约心跳,该服务实例就被自动删除。
Fetch Registries:获取服务注册列表信息。
从注册中心服务器、服务提供者、服务消费者三个角色出发,分析他们之间的交互细节
a.注册中心服务器:在Eureka中使用两层Hash Map来达到服务存储的效果。第一层HashMap的key是App Name(应用名字),第二层HashMap的key是Instance Name(实例名字)。面向服务注册中心的操作主要包括服务注册、服务续约和服务下线。注册中心服务器的另一个核心功能是提供服务列表,为了提高性能,服务列表在Eureka Server会缓存一份,同时每30秒更新一次。
b.服务提供者:相对注册中心服务器,服务提供者是客户端,所以它可以使用服务器提供的RESTful API完成服务注册、服务续约和服务下线等功能。
c.服务消费者:服务消费者和服务提供者本质上是同一个客户端。服务消费者在本地有一份缓存,所以需要定期更新缓存。
1.2)Netflix Eureka 高可用
服务注册中心虽然是一个侧重服务治理的辅助性组件,同样也需要确保可用性。Eureka Server的高可用性实际上就是将自己作为服务向其他服务注册中心注册自己,这样就形成了一组服务注册中心,以实现服务列表的互相同步,达到高可用的效果。replicateToPeers操作用来实现服务器结点间的状态同步。任意一个Eureka Server获取来自客户端的通知之后就会保证在所有的Eureka Server中得到更新。
1.3)Netflix Eureka区域亲和性
就是指服务消费者在选择服务的时候会选择和该服务消费者在同一个Zone(机房)的服务,这样做的目的是减少服务调用的延迟。
在这里插入图片描述
2)Spring Cloud Netflix Ribbon与负载均衡
Spring Cloud Netflix Ribbon是一个基于HTTP和TCP协议的客户端负载均衡工具,基于Netflix Ribbon实现。同时通过Spring Cloud的封装,可以将基于Spring自带的RestTemplate请求自动转换为客户端负载均衡的服务调用。
2.1)Netflix Ribbon基本架构
作为客户端负载均衡,要做的事:a.服务器列表中有哪些服务 b.如何从这些列表中选择一个进行调用?Netflix Ribbon的核心接口ILoaderBalancer就是围绕这两个问题设计的,包括如下方法:addServers(配置后端接口);chooseServer(选择一个后端接口);markServerDown(标记一个服务不可用);getServerList(获取后端服务列表)。ILoaderBalancer接口最基本的实现类是BaseLoadBalancer,负载均衡的核心功能都在这个类中实现:IRule(提供各种适用的负载均衡算法)。对于问题a通过上面Eureka里服务注册中心中得到所有服务列表,通过DynamicServerListLoadBalancer类实现。对于问题b通过IRule接口中的实现类得到,不同的接口实现类提供不同的负载均衡算法。
2.2)Spring Cloud Netflix Ribbon功能
Netflix Ribbon本质只是一个工具,不是一套完整的解决方案。所以Spring Cloud Netflix Ribbon做了封装。
实现客户端负载均衡功能有两种方法,一种是使用@RibbonClient注解命名化客户端,另一种是注入RestTemplate时自动使用Ribbon。
3)Spring Cloud Netflix Hystrix 与服务容错
Hystrix中HystrixCommand是重中之重。使用HystrixCommand时需要提供它的子类,子类要实现两个方法run()实现微服务之间的调用,getFallBack()实现服务降级处理逻辑。Spring Cloud内部集成了Netflix Hystrix框架,提供@EnableCircuitBreaker注解构建Hystrix客户端。
3.1)Hystrix服务隔离(针对服务隔离,Hystrix组件提供了两种解决方案,线程池隔离和信号量隔离,两种隔离方式都限制对共享资源的并发访问量)
a.线程池隔离(不同的服务提供了独立的线程池),通过HystrixPoolProperties来配置线程池参数,缺点增加了计算开销
b.信号量隔离:与线程池隔离的主要区别就是线程池方式下业务请求线程和执行依赖服务的线程不是同一个线程,而信号量方式下的业务请求线程和执行依赖服务的线程是同一个线程。
3.2)Hystix服务降级和熔断
a.服务降级:Hystrix在服务调用失败时执行getFallback函数。
b.服务熔断:Hystrix提供了熔断实现,熔断后自动降级。Command首先调用HystrixCircuitBreaker的allowRequest判断是否熔断,如没熔断,执行run()正常运行,如熔断,执行getFallback()直接进行降级处理。失败总数与访问总数的对比决定失败率,失败率决定allowRequest判断是否成立,当失败率超过一个阈值就进入熔断器打开状态,打开后不能一直熔断,需要在一个时间窗口后进行重试,这种状态就是半打开,Hsytrix允许一次重试,重试成功则熔断器关闭,否则熔断器打开。
3.3)Hystrix基本原理分析
4)Spring Cloud Netflix Zuul与API网关
4.1)Netflix Zuul路由机制(对于API网关而言,最重要的功能就是服务路由)
4.2)Netflix Zuu过滤器机制(ZuulFilter是Zuul中的核心组件,通过继承该抽象类,覆写几个关键方法就能达到自定义调度请求的效果)。Zuul中定义了四种标准过滤器类型,这些过滤器类型对应于一个请求到达API网关直到返回请求结果的典型生命周期:PRE(这种过滤器在请求到达目标服务器之前调用)、ROUTING(这种过滤器把用户请求发送给目标服务器,用户请求在这类过滤器中被重新构建,使用Apache HttpClient或Netflix Ribbon发送给目标服务器)、POST(这种过滤器在用户请求从目标服务器返回以后执行)、ERROR(在其他阶段发生错误的时候执行该过滤器)。
在这里插入图片描述
Zuul的路由映射和请求转发都是由几个内置的过滤器实现,路由映射主要通过PRE类型过滤器完成,它将请求路由与配置的路由规划进行匹配以找到需要转发的目标地址;而请求转发部分是由ROUTING过滤器完成,对PRE类型过滤器获取的路由地址进行转发,所以过滤器是Zuul实现API网关功能最为核心的组件。
5)Spring Cloud Config与配置中心(与前面的组件不同,这是Spring Cloud家族自己研发的高可用、分布式派至中心)
5.1)Spring Cloud Config应用方式
Spring Cloud中配置中心的设计理念就是通过一个配置服务器来对散落在系统中的各种配置文件进行集中化管理。Spring Cloud Config组件中分两个角色:Config Server、Config Client。集中式配置服务器的创建通过@EnableConfigServer注解实现,配置服务器可以将存放在仓库中的配置文件信息转化为REST接口数据,供应用服务在分布式环境下使用。
5.2)Spring Cloud Config基本架构
a.Spring Cloud Config对比Zookeeper
区别:配置的存储方式不同(Zookeeper是把配置信息保存在Zookeeper自身的文件系统中,而Spring Cloud Config则是把配置信息保存在Git/SVN上)、配置的管理方式不同(Spring Cloud Config把配置当作源码来看待并通过Git管理。Git的管理界面就是配置的管理界面。而基于Zookeeper的实现方案一般需要自己去开发管理界面)、配置变化的通知机制不同(Zookeeper中配置变化依赖自身的事件Watcher机制来通知应用,而Spring Cloud Config是依赖Git每次push之后触发的webhook回调并发送事件到Spring Cloud Bus消息总栈,然后消息总栈通知相关应用)。
b.Spring Cloud Config高可用(Spring Cloud Config实现高可用有两种方式)
传统模式(所有配置服务器统一指向同一个Git仓库,配置内容就通过基于Git的共享文件系统进行维护。客户端在指定配置服务器地址时,只需要设置配置服务器上的负载均衡器即可)、服务模式(Spring Cloud Config服务本身就是一个微服务,可以注册到Eureka Server上,让其他服务提供者和服务消费者通过注册中心进行配置发现和获取。)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值