Java面试八股文--分布式与微服务Nginx面试题
Java面试八股文--分布式与微服务Nginx面试题
SpringCloud 分布式相关
什么是SpringCloud
Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序,提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架,用于快速构建执行有限数据处理的应用程序。
什么是微服务
微服务架构是一种架构模式或者说是一种架构风格,它提倡将单一应用程序划分为一组小的服务,每个服务运行在其独立的自己的进程中,服务之间相互协调、互相配合,为用户提供最终价值。服务之间采用轻量级的通信机制互相沟通(通常是基于HTTP的RESTful API)。每个服务都围绕着具体业务进行构建,并且能够被独立地部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中式的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构建,可以有一个非常轻量级的集中式管理来协调这些服务,可以使用不同的语言来编写服务,也可以使用不同的数据存储。
SpringBoot和SpringCloud的区别?
SpringBoot专注于快速方便的开发单个个体微服务。
SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等集成服务
SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系.
SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。
负载平衡的意义什么?
在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最大化吞吐量,最小化响应时间并避免任何单一资源 的过载。使用多个组件进行负载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉及专用软件或硬件,例如多层交换机或域名系统服务器进程
什么是CAP理论
CAP理论是分布式领域中⾮常重要的⼀个指导理论,C(Consistency)表示强⼀致性,A(Availability)表示可⽤性,P(Partition Tolerance)表示分区容错性,CAP理论指出在⽬前的硬件条件下,⼀个分布式系统是必须要保证分区容错性的,⽽在这个前提下,分布式系统要么保证CP,要么保证AP,⽆法同时保证CAP。
Consistency(一致性):在分布式系统中的所有数据备份,在同一时刻是否同样的值。对于数据分布在不同节点上的数据来说,如果在某个节点更新了数据,那么在其他节点如果都能读取到这个最新的数据,那么就称为强一致,如果有某个节点没有读取到,那就是分布式不一致。
Availability(可用性):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(要求数据需要备份)
Partition tolerance(分区容忍性):大多数分布式系统都分布在多个子网络。每个子网络就叫做一个区(partition)。分区容错的意思是,区间通信可能失败。
分布式ID是什么?有哪些解决⽅案?
在开发中,我们通常会需要⼀个唯⼀ID来标识数据,如果是单体架构,我们可以通过数据库的主键,或直接在内存中维护⼀个⾃增数字来作为ID都是可以的,但对于⼀个分布式系统,就会有可能会出现ID冲突,此时有以下解决⽅案:
1. uuid,这种⽅案复杂度最低,但是会影响存储空间和性能
2. 利⽤单机数据库的⾃增主键,作为分布式ID的⽣成器,复杂度适中,ID⻓度较之uuid更短,但是受到单机数据库性能的限制,并发量⼤的时候,此⽅案也不是最优⽅案
3. 利⽤redis、zookeeper的特性来⽣成id,⽐如redis的⾃增命令、zookeeper的顺序节点,这种⽅案和单机数据库(mysql)相⽐,性能有所提⾼,可以适当选⽤
4. 雪花算法,⼀切问题如果能直接⽤算法解决,那就是最合适的,利⽤雪花算法也可以⽣成分布式ID,底层原理就是通过某台机器在某⼀毫秒内对某⼀个数字⾃增,这种⽅案也能保证分布式架构中的系统id唯⼀,但是只能保证趋势递增。业界存在tinyid、leaf等开源中间件实现了雪花算法。
分布式锁的使⽤场景是什么?有哪些实现⽅案?
在单体架构中,多个线程都是属于同⼀个进程的,所以在线程并发执⾏时,遇到资源竞争时,可以利⽤ReentrantLock、synchronized等技术来作为锁,来控制共享资源的使⽤。
⽽在分布式架构中,多个线程是可能处于不同进程中的,⽽这些线程并发执⾏遇到资源竞争时,利⽤ReentrantLock、synchronized等技术是没办法来控制多个进程中的线程的,所以需要分布式锁,意思就是,需要⼀个分布式锁⽣成器,分布式系统中的应⽤程序都可以来使⽤这个⽣成器所提供的锁,从⽽达到多个进程中的线程使⽤同⼀把锁。
什么是分布式事务?有哪些实现⽅案?
在分布式系统中,⼀次业务处理可能需要多个应⽤来实现,⽐如⽤户发送⼀次下单请求,就涉及到订单系统创建订单、库存系统减库存,⽽对于⼀次下单,订单创建与减库存应该是要同时成功或同时失败的,但在分布式系统中,如果不做处理,就很有可能出现订单创建成功,但是减库存失败,那么解决这类问题,就需要⽤到分布式事务。常⽤解决⽅案有:
1. 本地消息表:创建订单时,将减库存消息加⼊在本地事务中,⼀起提交到数据库存⼊本地消息表,然后调⽤库存系统,如果调⽤成功则修改本地消息状态为成功,如果调⽤库存系统失败,则由后台定时任务从本地消息表中取出未成功的消息,重试调⽤库存系统
2. 消息队列:⽬前RocketMQ中⽀持事务消息,它的⼯作原理是:
a. ⽣产者订单系统先发送⼀条half消息到Broker,half消息对消费者⽽⾔是不可⻅的
b. 再创建订单,根据创建订单成功与否,向Broker发送commit或rollback
c. 并且⽣产者订单系统还可以提供Broker回调接⼝,当Broker发现⼀段时间half消息没有收到任何操作命令,则会主动调此接⼝来查询订单是否创建成功
d. ⼀旦half消息commit了,消费者库存系统就会来消费,如果消费成功,则消息销毁,分布式事务成功结束
e. 如果消费失败,则根据重试策略进⾏重试,最后还失败则进⼊死信队列,等待进⼀步处理
3. Seata:阿⾥开源的分布式事务框架,⽀持AT、TCC等多种模式,底层都是基于两阶段提交理论来实现的
如何实现分库分表
将原本存储于单个数据库上的数据拆分到多个数据库,把原来存储在单张数据表的数据拆分到多张数据
表中,实现数据切分,从⽽提升数据库操作性能。分库分表的实现可以分为两种⽅式:垂直切分和⽔平
切分。
⽔平:将数据分散到多张表,涉及分区键,
分库:每个库结构⼀样,数据不⼀样,没有交集。库多了可以缓解io和cpu压⼒
分表:每个表结构⼀样,数据不⼀样,没有交集。表数量减少可以提⾼sql执⾏效率、减轻cpu压⼒
垂直:将字段拆分为多张表,需要⼀定的重构
分库:每个库结构、数据都不⼀样,所有库的并集为全量数据
分表:每个表结构、数据不⼀样,⾄少有⼀列交集,⽤于关联数据,所有表的并集为全量数据
Spring Cloud有哪些常⽤组件,作⽤是什么?
Nacos:注册中⼼、配置中⼼
Feign/OpenFeign:RPC调⽤
服务之间的调用
1.当调用的方法有参数时,参数一定要使用某种注解,否则可能不能有效传参(路径传参或者是@RequestParam("twoId")传统注解传参,对象就用@RequestBody)
2.设置访问超时
3.R统一封装数据,存取用R统一封装
Gateway:服务⽹关 (负载均衡也可以做)
负责请求转发、合成和协议转换。所有来自客户端的请求都要先经过 API Gateway,然后路由这些请求到对应的微服务。
1. Eureka:注册中⼼
2. Nacos:注册中⼼、配置中⼼
3. Consul:注册中⼼、配置中⼼
4. Spring Cloud Config:配置中⼼
5. Feign/OpenFeign:RPC调⽤
6. Kong:服务⽹关
7. Zuul:服务⽹关
8. Spring Cloud Gateway:服务⽹关
9. Ribbon:负载均衡
10. Spring CLoud Sleuth:链路追踪
11. Zipkin:链路追踪
12. Seata:分布式事务
13. Dubbo:RPC调⽤
14. Sentinel:服务熔断
15. Hystrix:服务熔断
什么是RPC
RPC,表示远程过程调⽤,对于Java这种⾯试对象语⾔,也可以理解为远程⽅法调⽤,RPC调⽤和HTTP调⽤是有区别的,RPC表示的是⼀种调⽤远程⽅法的⽅式,可以使⽤HTTP协议、或直接基于TCP协议来实现RPC,在Java中,我们可以通过直接使⽤某个服务接⼝的代理对象来执⾏⽅法,⽽底层则通过构造HTTP请求来调⽤远端的⽅法,所以,有⼀种说法是RPC协议是HTTP协议之上的⼀种协议,也是可以理解的。
Kafka
Kafka是什么
Kafka 是⼀种⾼吞吐量、分布式、基于发布/订阅的消息系统,最初由 LinkedIn 公司开发,使⽤Scala
语⾔编写,⽬前是 Apache 的开源项⽬。broker:Kafka 服务器,负责消息存储和转发topic:消息类
别, Kafka 按照 topic 来分类消息partition:topic 的分区,⼀个 topic 可以包含多个 partition,
topic 消息保存在各个partition
为什么要使用 kafka,为什么要使用消息队列
缓冲和削峰:上游数据时有突发流量,下游可能扛不住,或者下游没有足够多的机器来保证冗余,kafka在中间可以起到一个缓冲的作用,把消息暂存在kafka中,下游服务就可以按照自己的节奏进行慢慢处理。
解耦和扩展性:项目开始的时候,并不能确定具体需求。消息队列可以作为一个接口层,解耦重要的业务流程。只需要遵守约定,针对数据编程即可获取扩展能力。
冗余:可以采用一对多的方式,一个生产者发布消息,可以被多个订阅topic的服务消费到,供多个毫无关联的业务使用。
健壮性:消息队列可以堆积请求,所以消费端业务即使短时间死掉,也不会影响主要业务的正常进行。
异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
Nginx
什么是Nginx
Nginx是一个web服务器和方向代理服务器,用于HTTP、HTTPS、SMTP、POP3和IMAP协议。因
它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。
反向代理
是对于来自外界的请求,先通过nginx统一接受,然后按需转发给内网中的服务器,并且把处理请求返回给外界客户端,此时代理服务器对外表现的就是一个web服务器,客户端根本不知道“上游服务器”的存在。
动静分离
前后分离中,前端项目的运行是不需要用Tomcat、Apache等服务器环境的,因此可以直接用nginx来作为静态服务器。把静态文件都放到nginx中
正向代理
客户端无法主动或者不打算完成主动去向某服务器发起请求,而是委托了nginx代理服务器去向服务器发起请求,并且获得处理结果,返回给客户端。
负载均衡
将服务器接收到的请求按照规则分发的过程,称为负载均衡。
当请求到nginx服务器时,nginx就可以根据设置好的负载信息,把请求分配到不同的服务器,服务器处理完毕后,nginx获取处理结果返回给客户端,这样,用nginx的反向代理,即可实现了负载均衡。
负载均衡算法
1.轮询(默认):
每个请求按时间顺序逐一分配到不同的后端服务器,也是nginx的默认模式。如果后端服务器down掉,能自动剔除。轮询模式的配置很简单,只需要把服务器列表加入到upstream模块中即可。
2.ip_hash:
每个请求按访问IP的hash结果分配,同一个IP客户端固定访问一个后端服务器。可以保证来自同一ip的请求被打到固定的机器上,可以解决session问题。
下面的配置是指:负载中有三台服务器,当请求到达时,nginx优先按照ip_hash的结果进行分配,也就是同一个IP的请求固定在某一台服务器上,其它则按时间顺序把请求分配给三台服务器处理。
3.url_hash:
按访问url的hash结果来分配请求,相同的url固定转发到同一个后端服务器处理, 后端服务器为缓存时比较有效。
4.fair 公平: /fer/
按后端服务器的响应时间来分配请求,响应时间短的优先分配。使用这个算法需要安装nginx-upstream-fair这个库。
更多推荐
所有评论(0)