什么是微服务架构?
微服务框架是将某个应用程序开发划分为许多独立小型服务,实现敏捷开发和部署,这些服务一般围绕业务规则进行构建,可以用不同的语言开发,使用不同的数据存储,最终使得每个服务运行在自己的行程中。并且它们之间采用轻量级通信机制进行通信。
微服务的特点:
- 单一职责:微服务中每一个服务都对应唯一的业务能力,做到单一职责
- 应用粒度:微服务的服务拆分粒度很小,例如一个用户管理就可以作为一个服务。每个服务虽小,但“五脏俱全”。
- 面向服务:每个服务都要对外暴露Rest风格服务接口API。各种终端都可以调用,不关心语言、平台限制,也不关心服务的技术实现,只要提供Rest的接口即可。
- 前后端分离:采用前后端分离开发,提供统一Rest接口,后端不用再为PC、移动段开发不同接口
- 自治能力:所有的微服务都能运行在自己的进程中,服务间之间互相独立,互不干扰
- 团队独立:每个服务都是一个独立的开发团队,
- 技术独立:Rest接口通信,不关心使用技术
- 部署独立,服务间虽然有调用,但要做到服务重启不影响其它服务。有利于持续集成和持续交付。每个服务都是独立的组件,可复用,可替换,降低耦合,易维护
缺点:
- 可用性降低:微服务之间通过远程调用实现协作,而远程调用相对来说不稳定,需要用有效的方案来解决处理。
- 分布式事务困难:当一个用户请求的业务设计多个微服务时,需要解决保障数据的一致性的问题
- 全能对象(God Classes)阻止业务拆分,每个业务都有可能存在一个或多个全能对象,比如说商城项目中的订单对象,它几乎会涉及电商应用中的每一个业务,阻止你进行业务拆分
架构的演进
集中式架构(ORM) | 垂直拆分(MVC) | 分布式服务(RPC) |
---|---|---|
程序被放到一起,然后发布到一台服务器上 | 应用拆分成互不干扰的几个应用,以提升效率、分散流量压力 | 将核心业务以及公共应用程序抽取出来,作为一个稳定的服务中心 |
耦合度高,开发维护困难,无法水平扩展,单点容错率低,并发能力差 | 系统拆分分担的流量,解决了并发问题,可以针对不同模块进行优化方便水平扩展,但是代码量大,系统可靠性差,开发维护困难切成本高,不易团队合作 | 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率,但是:服务配置困难,服务间的依赖关系复杂,可能出现小服务资源浪费等问题 |
![]() |
![]() |
![]() |
CAP理论
- Consistency(一致性):更新操作成功并返回客户端后,所有节点在同数据完全一致。对于客户端来说,一致性指的是并发访问时更新过的数据如何获取的问题。从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。
- Availability(可用性):即服务一直可用,而且是正常晌应时间。系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。
- Partition Tolerance(分区容错性):分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。分区容错性要求能够使应用虽然是一个分布式系统,而看上去却好像是在一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其他剩下的机器还能够正常运转满足系统需求,对于用户而言并没有什么体验上的影响。
CP(高可用)和AP:分区容错是必须保证的,当发生网络分区的时候,如果要继续服务,那么强一致性和可用性只能二选一。
BASE理论
BASE是 Basically Available(基本可用)、 Soft state(状态)和 Eventually consistent(最终一致性)
BASE理论是对CAP中一致性和可用性权衡的结果,其来源于对大规模互联网系统分布式实践的总结,是基于CAP
定理逐步演化而来的。BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点
采用适当的方式来使系统达到最终一致性。
- 基本可用
①晌应时间上的损失:正常情况下,处理用户请求需要0.55返回结果,但是由于系统出现故障,处理用户请求的时间变为3s。
②系统功能上的损失:正常情况下,用户可以使用系统的全部功能,但是由于系统访问量突然剧增,系统的部分非核心功能无法使用 - 软状态:数据同步允许一定的延迟
- 最终一致性:系统中所有的数据副本,在经过一段时间的同步后,最终能够达到个一致的状态,不要求实时
分布式下Session共享的方案
- 采用无状态服务,抛弃 session
- 存入 cookie(有安全风险)
- 服务器之间进行 Session同步,这样可以保证每个服务器上都有全部的 Session信息,不过当服务器数量比较多的时候,同步是会有延迟甚至同步失败
- IP绑定策略:使用 Nginx中的IP绑定策略,同一个IP只能在指定的同—个机器访问,但是这样做失去了负载均衡的意义,当挂掉一台服务器的时候,会影晌一批用户的使用,风险很大;
- 使用 Redis存储:把 Session放到Reds中存储,虽然架构上变得复杂,并且需要多访问一次 Redis,但是这种方案带来的好处也是很大的(实现了 Session共享、可以水平扩展、服务器重启 Session不丢失、不仅可以跨服务器 Session共享,甚至可以跨平台)
分布式id生成策略
UUID:当前日期和时间(时间戳) + 时钟序列(计数器)+ 全局唯一的IEEE机器识别号
优点:代码简单,性能好(本地生成,没有网络消耗),保证唯一(相对而言,重复概率极低可以忽略)
缺点:
- 生成的ID都是无序的字符串,而且不是全数字
- UUID长度过长,不适用于存储,耗费数据库性能
- UUID无一定业务含义,可读性差
- 有信息安全问题,有可能泄露mac地址
数据库自增模式
单机模式:
优点:实现简单、成本低、ID是自增的数字、有一定的可读性
缺点:
- 强依赖DB,存在单点问题,如果数据库宕机,则业务不可用
- DB生成ID性能有限,单点数据压力大,不适合高并发场景
- 信息安全问题:比如暴露订单量,有可能查到别人的订单
数据库高可用:多主模式做负载,基于序列的起始值和步长设置,不同的初始值,相同的步长,步长大于节点数
优点:解决了ID生成的单点问题,同时平衡了负载
缺点:
系统扩容困难:系统定义好步长之后,增加机器之后调整步长困难
数据库压力大:每次获取一个ID都必频读写一次数据库
Leaf- segmen
采用每次获取一个ID区间段的方式来解决,区间段用完之后再去数据库获取新的号段,这样一来可以大大减轻数据库的压力
优点:
扩张灵活,性能强能够撑起大部分业务场景
ID号码是趋势递增的,满足数据库存储和查询性能要求
可用性高,即使ID生成服务器不可用,也能够使得业务在短时间内可用,为排查问题争取时间。
缺点:
可能存在多个节点同时请求ID区间的情况,依赖DB
基于redis、mongodb、zk等中间件生成
雪花算法:生成一个64bit的整性数字:第一位符号位固定为0,41位时间戳,10位workId,12位序列号位数可以有不同实现
优点:
每个毫秒值包含的ID值很多,不够可以变动位数来增加,性能佳(依赖work工d的实现)
时间戳值在高位,中间是固定的机器码,自增的序列在低位,整个ID是趋势递增的
能够根据业务场景数据库节点布置灵活挑战bit位划分,灵活度高
缺点:
强依赖于机器时钟,如果时钟回拨,会导致重复的ID生成,所以一般基于此的算法发现时钟回拨,都会抛异常处
理,阻止ID生成,这可能导致服务不可用
如何实现分布式锁?
分布式锁:锁独立于每一个服务之外的锁
- 数据库:利用主键沖冲突控制一次只有一个线程能获取锁,非阻塞、不可重入、
- Zookeeper分布式锁:zk通过临时节点,解决了死锁的问题,一旦客户端获取到锁之后突然挂掉( session连接断开),那么这个临时节点就会自动删除掉,其他客户端自动获取锁。临时顺序节点解决惊群效应
- Redis分布式锁:setnx,单线程处理网络请求,不需要考虑并发安全性
实现方式:setnx、radisson、redlock
setnx:指定的 key 不存在时,才能操作成功,为 key 设置指定的值
设置锁:给所有服务节点设置相同的key,返回为0、则锁获取失败(防止锁被别人所释放可以设置一个线程的唯一标识)
删除锁:判断线程唯一标志,再删除
问题:
实现的Redis分布式锁,其实不具有可重入性
存在任务超时问题,锁自动释放(key过期),导致并发问题
Redis没有实现可重入性及锁续期,可以通过 radisson解决(类似AQS的实现,看门狗监听机制)
redis多节点数据同步问题:
redlock:意思的机制都只操作单节点、即使Redis通过 sentinel保证高可用,如果这个 master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况( redis同步设置可能数据丢失)。 redlock从多个节点申请锁,当一半以上节点获取成功、锁才算获取成功,redission有相应的实现
如何实现分布式事务?
两阶段协议:
第一阶段( prepare):每个参与者执行本地事务但不提交,进入 ready状态,并通知协调者已经准备就绪。
第二阶段( commit):当协调者确认每个参与者都 ready后,通知参与者进行 commit操作;如果有参与者fail则发送 rollback命令,各参与者做回滚。
存在的问题:
- 单点故障:一旦事务管理器出现故障,整个系统不可用(参与者都会阻塞住)
- 数据不一致:在阶段二,如果事务管理器只发送了部分 commit消息,此时网络发生异常,那么只有部分参与者接收到commit消息,也就是说只有部分参与者提交了事务,使得系统数据不—致
- 晌应时间较长:参与者和协调者资源都被锁住,提交或者回滚之后才能释放
- 不确定性:当协事务管理器发送 commit之后,并且此时只有一个参与者收到了 commit,那么当该参与者与事务管理器同时宕机之后,重新选举的事务管理器无法确定该条消息是否提交成功。
三阶段协议:
针对两阶段进行优化,引入了超时机制解决参与者阻塞的问题,超时后本地提交,解决了2PC单点故障问题,但性能问题和不一致问题仍然没有根本解决。(2PC只有协调者有超时机制)
超时机制:如果PreCommit消息执行成功,如果一定时间内还未收到DoCommit消息,则认为TM挂了,自动执行DoCommit
- 第一阶段: Cancommit阶段,协调者询问事务参与者,是否有能力完成此次事务,如果都返回yes,则进入第二阶段。有一个返回no或等待响应超时,则中断事务,并向所有参与者发送abort请求
- 第二阶段:Recommit阶段,此时协调者会向所有的参与者发送 Recommit请求,参与者收到后开始执行事务操作。参与者执行完事务操作后(此时属于未提交事务的状态),就会向协调者反馈
Ack
表示我已经准备好提交了,并等待协调者的下一步指令。- 第三阶段: Docommit阶段,在阶段二中如果所有的参与者节点都返回了
Ack
,那么协调者就会从“预提交状态转变为提交状态”。然后向所有的参与者节点发送 “docommit’'请求,参与者节点在收到提交请求后就会各自执行事务提交操作,并向协调者节点反馈Ack
消息,协调者收到所有参与者的Ack
消息后完成事务。相反,如果有一个参与者节点未完成 Recommit的反馈或者反馈超时,那么协调者都会向所有的参与者节点发送abort请求,从而中断事务。
TCC 是业务层面的分布式事务
TCC(补偿事务):Try(操作做业务检查及资源预留)、 Confirm(业务确认)、 Cancel(回滚操作)
针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作,TM首先发起所有的分支事务的Try操作,任何—个分支事务的Try操作执行失败,TM将会发起所有分支事务的 Cancel操作,若Try操作全部成功,TM将会发起所有分支事务的 Confirm操作,其中 Confirm/ Cancel操作若执行失败,TM会进行重试。
TCC模型对业务的侵入性较强,改造的难度较每个操作都需要有try、confirm、cancel三个接口实现,confirm和 cancel接口还必须实现幂等性。
图片来源:https://blog.csdn.net/leilei107/article/details/105738301
消息队列的事务消息
发送 prepare消息到消息中间件,发送成功后,执行本地事务:
如果事务执行成功,则 commit,消息中间件将消息下发至消费端( commit前,消息不会被消费)
如果事务执行失败,则回滚,消息中间件将这条 prepare消息删除消费端接收到消息进行消费,如果消费失败,则不断重试。
如何设计一套API接口
考虑到API接口的分类可以将API接口分为开发API接口和内网API接口,内网API接口用于局域网,为内部服务器提供服务。开放API接口用于对外部合作单位提供接口调用,需要遵循Oauth2.0权限认证协议。同时还需要考虑安全性、幂等性等问题。
如何实现接口的幂等性:
- 唯—id:每次操作,都根据操作和内容生成唯一的id,在执行之前先判断id是否存在,如果不存在则执行后续操作,并且保存到数据库或者 redis等。
- 服务端提供发送 token的接口,业务调用接口前先获取token,然后调用业务接口请求时,把 token携带过去,务器判断token是否存在 redis中,存在表示第一次请求,可以继续执行业务,执行业务完成后,最后需要把redis中的 token删除。
- 建去重表:将业务中有唯一标识的字段保存到去重表,如果表中存在,则表示已经处理过了
- 版本控制:增加版本号,当版本号符合时,才能更新数据
- 状态控制:例如订单有状态已支付,未支付,支付中支付失败,当处于未支付的时候才分许修改为为支付中等
秒杀系统如何设计?
基于SpringCloud构建秒杀抢购活动,如何才能支持百万级级别以上访问 ?
设计原则:前台请求尽量少,后台数据尽量少,调用链路尽量短,尽量不要有单点
秒杀系统解决方案:
- nginx:校验恶意请求,转发请求,负载均衡;
- 网关:安全过滤(拦截恶意请求)、幂等、高并发、限流、用户频率设计
- 业务层:分布式集群,多台机器处理,提高并发能力
- Hystrix:对秒杀接口实现服务隔离防止雪崩效应
- Ribbon:负载均衡,优化资源使用,防止资源的过载
- 前端:页面资源静态化,按钮控制,使用答题校验码可以防止秒杀器的干扰,让更多用户有机会抢到
- redis:实现分布式锁对用户频率限制,集群搭建保证高可用,持久化数据;缓存热点数据(库存);
- MQ:异步形式,实现对商品的库存修改,削峰限流,MQ堆积订单,保护订单处理层的负载,
- 数据库:读写分离,拆分事务提高并发度,使用乐观锁机制(版本号)+库存>0判断防止库存超卖问题
Spring Cloud 是什么?
- Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
- Spring Cloud将各家公司开发的比较成熟的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
优点:低耦合,配置简单,面向服务,前后端分离,团队独立,技术独立,独立部署
缺点:部署困难,数据管理困难(数据库分离)、系统集成测试比较麻烦 、性能的监控比较麻烦
SpringBoot和SpringCloud的区别?
SpringBoot只是一个快速开发框架,可以独立使用开发项目,SpringCloud是一系列框架的集合,开发时依赖于SpringBoot框架。
- SpringBoot可以用来快速、方便的开发单个微服务个体。
- SpringCloud关注全局的服务治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、决策竞选、分布式会话等集成服务。
Spring Cloud和 Dubbo的区别?
- 底层协议: springcloud基于http协议,dubbo基于Tcp协议,决定了 dubbo的性能相对会比较好
- 服务调用方式:springcloud是基于RestApi,dubbo基于RPC
- 注册中心: Spring Cloud使用的 eureka,dubbo推荐使用 zookeeper
- 模型定义: dubbo将一个接口定义为—个服务, Spring Cloud则是将一个应用定义为一个服务
- Spring Cloud是一个生态,而 Dubbo是 Springcloud生态中关于服务调用一种解决方案(服务治理)
分布式微服务开发时的问题?
- 系统开销:网络问题,延迟开销,带宽问题,安全问题。
- 性能问题:由于各种运营开销导致的性能问题
- 服务发现:服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。
- 冗余问题:分布式系统中的冗余问题。
- 负载均衡:负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机集群,网络链路,中央处理单元,或磁盘驱动器的分布。
SpringCloud由什么组成?
- Spring Cloud Eureka:服务注册与发现,包含服务注册中心,服务注册与发现机制的实现。
- Spring Cloud Zuul:服务网关,提供智能路由,访问过滤功能
- Spring Cloud Ribbon:客户端负载均衡的服务调用组件
- Spring Cloud Feign:服务调用,给予Ribbon和Hystrix的声明式服务调用组件
- Spring Cloud Hystrix:容错管理组件,实现断路器模式,帮助服务依赖中出现的延迟和为故障提供强大的容错能力。(熔断、断路器,容错)
- Spring Cloud Config:分布式统一配置管理
什么是Eureka?
Eureka服务注册中心,专注于微服务的服务注册与发现。
- 服务注册:每个服务都向 Eureka登记自己提供服务的元数据(服务的jp地址、端口号、版本号、通信协议等)。Eureka将各个服务维护在了一个服务清单中(双层Map,
Map<服务名,Map<实例名,服务地址+端口>>
)。同时对服务维持心跳,剔除不可用的服务, Eureka集群各节点相互注册每个实例中都有一样的服务清单。 - 服务发现:Eureka注册的服务之间调用不需要指定服务地址,而是通过服务名向注册中心咨询,并获取所有服务实例清单(缓存到本地),然后实现服务的请求访问。
Eureka集群(实现高可用AP),注册多个Eureka节点,然后把SpringCloud服务互相注册,客户端从Eureka获取信息时,按照Eureka的顺序来访问。这些节点都是平等的,当客户端向某一个节点注册时如果发现连接失败,会自动切换到其他节点。只要还有一台节点存在,服务就能正常工作(高可用),但是可能查询的信息不是最新的(不保证强一致性)。
Eureka的自我保护模式:
- Eureka的客户端将其连接到Eureka的服务端中,并且保持心跳,这样工作人员可以通过Eureka的服务端来监控各个微服务是否运行正常。如果Eureka Server在一定时间内没有接收到某个微服务实例的心跳,Eureka Server将会注销该实例(默认90秒)。
- 当Eureka发现85%以上的服务都没有心跳的话,Eureka 服务端就会认为自己的网络出问题了,进入自我保护模式,在该模式下Eureka 服务端会保护服务注册表中的信息,不在删除注册表中的数据,当网络故障恢复后,Eureka 服务端节点会自动退出自我保护模式(期间Eureka的客户端也会缓存服务信息)。
Eureka和ZooKeeper提供服务注册与发现功能的区别
- ZooKeeper中的节点服务挂了就要选举,在选举期间注册服务瘫痪,虽然服务最终会恢复,但是选举期间不可用的, 选举就是改微服务做了集群,必须有一台主其他的都是从。
- Eureka各个节点是平等关系,服务器挂了没关系,只要有一台Eureka就可以保证服务可用,数据都是最新的。 如果查询到的数据并不是最新的,就是因为Eureka的自我保护模式导致的
- Eureka本质上是一个工程,而ZooKeeper只是一个进程
- Eureka可以很好的应对因网络故障导致部分节点失去联系的情况,而不会像ZooKeeper 一样使得整个注册系统瘫痪
- ZooKeeper保证的是CP(强一致性),Eureka保证的是AP(高可用)
什么是Ribbon负载均衡?
当服务间发起请求的时候,通过负载均衡算法(轮询法、随机法等)从一个服务的多台机器中选择一台, Ribbon也是通过发起http请求来进行的调用,只不过是通过调用服务名的地址来实现的。
负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源的过载。
Ribbon底层实现原理:
Ribbon使用DiscoveryClient从注册中心读取目标服务信息,对同一接口请求进行计数,使用%取余算法获取目标服务集群索引,返回获取到的目标服务信息。
@LoadBalanced注解:开启客户端负载均衡。
DiscoveryClient的作用:可以从注册中心中根据服务别名获取注册的服务器信息。
Nginx与Ribbon的区别?
Nginx是反向代理同时可以实现负载均衡,Nginx拦截客户端请求采用负载均衡策略根据upstream配置进行转发,相当于请求通过nginx服务器进行转发。Ribbon是客户端负载均衡,从注册中心读取目标服务器信息,然后客户端采用轮询策略对服务直接访问,全程在客户端操作。
负载均衡算法有哪些?
- 轮询法:将请求按顺序轮流地分配到后端服务器上
- 随机法:通过系统的随机算法,根据后端服务器旳的列表大小值来随机选取其中的台服务器进行访问。
- 源地址哈希法:根据获取客户端的IP地址,通过哈希函数计算得到的个数值,用该数值对服务器列表的大小
进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同IP地址的客户端,后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。 - 加权轮询法:不同的后端服务器机器的配置和当前系统的负载并不相同,抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。
- 加权随机法:加权随机法也根据后端机器的配置,系统的负载分配不同的权重。按照权重随机请求后端服务器,而非顺序。
- 最小连接数法:最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服努器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。
断路器
当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)
断路器有三种状态:
- 打开状态:一段时间内 达到一定的次数无法调用 并且多次监测没有恢复的迹象断路器完全打开 那么下次请求就不会请求到该服务
- 半开状态:短时间内 有恢复迹象断路器会将部分请求发给该服务,正常调用时断路器关闭
- 关闭状态:当服务一直处于正常状态能正常调用
什么是 Hystrix?
Hystrix:容错管理组件,实现断路器模式,发起请求都会通过 Hystrⅸ的线程池,不同的服务走不同的线程池,实现了不同服务调用的隔离,通过统计接口超时次数返回默认值,实现服务降级,服务熔断,服务隔离,监控等功能,防止雪崩。
- 服务降级:接口调用失败时,防止客户端一直等待,就调用本地的方法返回一个友好的提示
- 服务熔断:当在一个统计时间范围内的请求失败数量达到设定值时开启断路,之后的请求直接走fallback方法,在设定时间后尝试恢复(在服务降级的基础上更直接的一种保护方式)
- 服务隔离:为隔离的服务开启一个独立的线程池,防止隔离服务之间相互影响
- 服务监控:在服务发生调用时,会将每秒请求数、成功请求数等运行指标记录下来。
服务降级底层是如何实现的?
Hystrix实现服务降级的功能是通过重写HystrixCommand中的getFallback()方法,当Hystrix的run方法或construct执行发生错误时转而执行getFallback()方法。
雪崩效应是在大型互联网项目中,当某个服务发生宕机时,调用这个服务的其他服务也会发生宕机,大型项目的微服务之间的调用是互通的,这样就会将服务的不可用逐步扩大到各个其他服务中,从而使整个项目的服务宕机崩溃。
发生雪崩效应的原因有以下几点:
- 单个服务的代码存在bug
- 请求访问量激增导致服务发生崩溃(如大型商城的枪红包,秒杀功能)
- 服务器的硬件故障也会导致部分服务不可用
在微服务中,使用Hystrix框架,实现服务隔离来避免出现服务的雪崩效应,从而达到保护服务的效果。
什么是Feign?
Feign:是一个声明web服务客户端,他基于 Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求,简化服务间的调用,在 Ribbon的基础上进行了进一步的封装。单独抽出了一个组件,就是 Spring Cloud Feign。在引入 Springoud Feign后,我们只需要创建一个接口并用注解的方式来配置它,即可完成对服务提供方的接口绑定。调用远程就像调用本地服务一样。
Ribbon和Feign调用服务的区别?
调用方式同:Ribbon需要我们自己构建Http请求,模拟Http请求然后通过RestTemplate发给其他服务,步骤相当繁琐。而Feign则是在Ribbon的基础上进行了一次改进,采用接口的形式,将我们需要调用的服务方法定义成抽象方法保存在本地就可以了,不需要自己构建Http请求了,直接调用接口就行了,不过要注意,调用方法要和本地抽象方法的签名完全一致。
RPC:在本地调用远程的函数,远程过程调用,可以跨语言实现HttpClient
RMI:远程方法调用,java中用于实现RPC的一种机制
Zuul网关
网关相当于一个网络服务架构的入口,所有网络请求必须通过网关转发到具体的服务。网关用来统一管理微服务请求,权限控制、负载均衡、路由转发、监控、安全控制黑名单和白名单等。
什么是Spring Cloud Zuul(服务网关)
Zuul根据请求的路径不同,定位到指定的微服务,并代理请求到不同的微服务接口,他对外隐蔽了微服务的真正接口地址。 三个重要概念:动态路由表,路由定位,反向代理:
- 动态路由表:Zuul支持Eureka路由,手动配置路由,这俩种都支持自动更新
- 路由定位:根据请求路径,Zuul有自己的一套定位服务规则以及路由表达式匹配
- 反向代理:客户端请求到路由网关,网关受理之后,在对目标发送请求,拿到响应之后在 给
Zuul的应用场景:对外暴露,权限校验,服务聚合,日志审计等
网关与过滤器有什么区别:网关是对所有服务的请求进行分析过滤,过滤器是对单个服务而言。
ZuulFilter常用的方法:
Run():过滤器的具体业务逻辑
shouldFilter():判断过滤器是否有效
filterOrder():过滤器执行顺序
filterType():过滤器拦截位置
如何实现动态Zuul网关路由转发?
通过path配置拦截请求,通过ServiceId到配置中心获取转发的服务列表,Zuul内部使用Ribbon实现本地负载均衡和转发。
Zuul与Nginx有什么区别?
Zuul是java语言实现的,主要为java服务提供网关服务,尤其在微服务架构中可以更加灵活的对网关进行操作。Nginx是使用C语言实现,性能高于Zuul,但是实现自定义操作需要熟悉lua语言,对程序员要求较高,可以使用Nginx做Zuul集群。