《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。
一、本文面试题目录
111. 什么是Spring Cloud?它和Spring Boot的关系是什么?
原理说明
- Spring Cloud 是基于Spring Boot的微服务架构开发工具集,提供了一套完整的微服务解决方案,涵盖服务注册与发现、配置管理、负载均衡、熔断降级、API网关等核心功能。
- 它利用Spring Boot的自动配置特性,简化了微服务组件的集成和开发,使开发者能够快速构建分布式系统。
与Spring Boot的关系
- 基础与扩展:Spring Boot是Spring Cloud的基础,Spring Cloud依赖Spring Boot实现服务的快速开发和部署;Spring Cloud是Spring Boot在分布式场景下的扩展,解决微服务架构中的跨服务问题。
- 功能互补:Spring Boot专注于单个服务的快速开发(如自动配置、嵌入式服务器);Spring Cloud专注于服务间的协作(如服务发现、负载均衡)。
- 版本兼容:Spring Cloud与Spring Boot存在版本对应关系(如Spring Cloud Hoxton对应Spring Boot 2.2.x/2.3.x),需匹配使用以避免兼容性问题。
示例
一个典型的微服务架构中,每个服务用Spring Boot开发(独立运行),通过Spring Cloud组件(如Eureka、Feign)实现服务注册和调用。
112. Spring Cloud的核心组件有哪些?各自的作用是什么?
Spring Cloud包含多个核心组件,分别解决微服务架构中的不同问题:
-
服务注册与发现
- Eureka:***flix开源的服务注册中心,支持服务注册、发现和高可用。
- Consul:HashiCorp开源的工具,提供服务注册、配置管理和分布式一致性保障。
- Nacos:阿里巴巴开源的动态服务发现、配置管理和服务管理平台。
-
负载均衡
- Ribbon:客户端负载均衡工具,根据规则(如轮询、随机)分发请求到多个服务实例。
- Feign:基于Ribbon的声明式HTTP客户端,简化服务间调用(通过接口+注解)。
-
熔断与降级
- Hystrix:防止服务雪崩的熔断组件,当依赖服务故障时快速失败并返回降级响应。
- Resilience4j:轻量级熔断组件,替代Hystrix(Hystrix已停止维护)。
-
API网关
- Spring Cloud Gateway:基于***ty的响应式网关,提供路由、过滤、负载均衡等功能。
- Zuul:***flix开源的网关(1.x基于Servlet,2.x基于***ty,逐渐被Gateway替代)。
-
配置中心
- Spring Cloud Config:集中式配置管理工具,支持配置文件的版本控制和动态刷新。
- Spring Cloud Alibaba Nacos:同时支持服务发现和配置管理。
-
服务链路追踪
- Spring Cloud Sleuth:生成服务调用链路的追踪ID和跨度ID,标记请求流转路径。
- Zipkin:可视化展示链路追踪数据,分析服务调用耗时和依赖关系。
-
服务安全
- Spring Cloud Security:基于Spring Security的微服务安全解决方案,支持OAuth2、JWT等认证授权。
113. 什么是服务注册与发现?Spring Cloud中如何实现?(如Eureka、Consul、Nacos)
原理说明
-
服务注册与发现是微服务架构的核心机制:
- 服务注册:服务启动时将自身信息(IP、端口、服务名)注册到注册中心。
- 服务发现:客户端从注册中心获取服务实例列表,通过负载均衡选择一个实例进行调用。
实现方式
1. Eureka
-
组件:Eureka Server(注册中心)和Eureka Client(服务端/客户端)。
-
配置步骤:
- 搭建Eureka Server:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-***flix-eureka-server</artifactId> </dependency>@EnableEurekaServer // 启用Eureka Server @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }# application.yml eureka: client: register-with-eureka: false # 不注册自身 fetch-registry: false # 不获取服务列表 server: enable-self-preservation: false # 关闭自我保护(开发环境)- 服务注册(Eureka Client):
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-***flix-eureka-client</artifactId> </dependency>@SpringBootApplication @EnableDiscoveryClient // 启用服务发现 public class UserServiceApplication { ... }eureka: client: service-url: defaultZone: http://localhost:8761/eureka/ # 注册中心地址 spring: application: name: user-service # 服务名
2. Nacos
- 特点:同时支持服务发现和配置管理,部署简单。
-
配置步骤:
- 启动Nacos Server(下载安装包并启动)。
- 服务注册:
<dependency> <groupId>***.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>spring: cloud: nacos: discovery: server-addr: localhost:8848 # Nacos地址 application: name: order-service
114. Eureka的自我保护机制是什么?
原理说明
- Eureka的自我保护机制是一种容错策略,当Eureka Server在短时间内丢失过多服务实例的心跳(通常是网络分区故障导致),它会进入自我保护模式,不再删除注册表中的服务实例。
核心逻辑
- 触发条件:Eureka Server在15分钟内收到的心跳数低于预期阈值(默认阈值=服务实例数×85%)。
-
保护行为:
- 不再从注册表中移除因心跳超时未续约的服务。
- 仍然接收新服务的注册和查询请求,但不会同步到其他节点(保证当前节点可用)。
- 退出条件:当网络恢复,服务实例心跳正常发送后,Eureka Server自动退出自我保护模式。
配置
eureka:
server:
enable-self-preservation: true # 开启自我保护(默认开启)
# 开发环境可关闭,避免服务下线后仍被发现
# enable-self-preservation: false
作用
- 防止因网络临时故障(如分区)导致健康服务被误删,提高注册中心的可用性。
- 缺点:可能保留已下线的服务实例,客户端可能调用到无效服务(需配合熔断机制)。
115. 什么是负载均衡?Spring Cloud中如何实现?(如Ribbon、Feign)
原理说明
- 负载均衡是将请求分发到多个服务实例,避免单实例过载,提高系统可用性和吞吐量。
- Spring Cloud提供客户端负载均衡(请求发出前在客户端决定目标实例)。
实现方式
1. Ribbon
-
特点:***flix开源的客户端负载均衡器,支持多种策略(轮询、随机、权重等)。
-
使用步骤:
- 引入依赖(通常已被其他组件如Eureka Client包含):
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-***flix-ribbon</artifactId> </dependency>- 配置RestTemplate并开启负载均衡:
@Configuration public class RestConfig { @Bean @LoadBalanced // 启用Ribbon负载均衡 public RestTemplate restTemplate() { return new RestTemplate(); } }- 调用服务(通过服务名而非IP):
@Service public class OrderService { @Autowired private RestTemplate restTemplate; public User getUser(Long userId) { // 调用user-service服务的/{userId}接口 return restTemplate.getForObject("http://user-service/" + userId, User.class); } }- 配置负载均衡策略:
user-service: # 服务名 ribbon: NFLoadBalancerRuleClassName: ***.***flix.loadbalancer.RandomRule # 随机策略
2. Feign
-
特点:基于Ribbon的声明式HTTP客户端,通过接口+注解简化服务调用。
-
使用步骤:
- 引入依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>- 启用Feign:
@SpringBootApplication @EnableFeignClients // 启用Feign客户端 public class OrderServiceApplication { ... }- 定义Feign接口:
@FeignClient(name = "user-service") // 绑定服务名 public interface UserFeignClient { @GetMapping("/{id}") // 映射服务接口 User getUserById(@PathVariable("id") Long id); }- 调用服务:
@Service public class OrderService { @Autowired private UserFeignClient userFeignClient; public User getUser(Long userId) { return userFeignClient.getUserById(userId); // 调用Feign接口 } }
116. Ribbon和Feign的区别是什么?
| 特性 | Ribbon | Feign |
|---|---|---|
| 本质 | 客户端负载均衡器(底层工具)。 | 基于Ribbon的声明式HTTP客户端(上层封装)。 |
| 使用方式 | 通过RestTemplate手动发起HTTP请求。 |
通过接口+注解定义请求,自动生成实现类。 |
| 代码侵入性 | 较高(需编写URL和参数拼接逻辑)。 | 较低(仅需定义接口,符合面向接口编程)。 |
| 功能扩展 | 需手动集成熔断(如Hystrix)。 | 内置支持Hystrix熔断(通过fallback属性)。 |
| 可读性 | 较差(URL和参数分散在代码中)。 | 较好(接口定义清晰,与服务端API对应)。 |
| 依赖 | spring-cloud-starter-***flix-ribbon |
spring-cloud-starter-openfeign |
示例对比
-
Ribbon调用:
restTemplate.getForObject("http://user-service/users/" + id, User.class); -
Feign调用:
// 接口定义 @FeignClient(name = "user-service") public interface UserClient { @GetMapping("/users/{id}") User getById(@PathVariable Long id); } // 调用 userClient.getById(id);
总结:Feign是Ribbon的封装,简化了服务调用代码,推荐在实际开发中使用Feign。
117. 什么是熔断器?Hystrix的作用是什么?
原理说明
- 熔断器是防止微服务架构中“服务雪崩”的组件。当某个服务因故障响应缓慢或不可用,熔断器会快速失败并返回降级响应,避免请求堆积导致整个调用链崩溃。
Hystrix的作用
-
熔断机制:
- 当服务调用失败率超过阈值(默认50%),熔断器从“关闭”状态转为“打开”状态,直接拒绝新请求。
- 经过一段时间(默认5秒)后进入“半打开”状态,允许部分请求尝试调用,若成功则恢复“关闭”状态,否则继续“打开”。
-
降级策略:
- 熔断打开或服务超时后,执行预设的降级方法(如返回缓存数据、默认值),保证调用方不被阻塞。
-
资源隔离:
- 通过线程池或信号量隔离不同服务的调用,避免单个服务故障耗尽系统资源。
-
请求缓存与合并:
- 缓存重复请求结果,合并短时间内的多次相同请求,减少服务压力。
Hystrix使用示例(结合Feign)
- 引入依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-***flix-hystrix</artifactId>
</dependency>
- 启用Hystrix:
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker // 启用熔断器
public class OrderServiceApplication { ... }
- 定义Feign降级类:
@***ponent
public class UserFeignFallback implements UserFeignClient {
@Override
public User getUserById(Long id) {
// 降级逻辑:返回默认用户
User defaultUser = new User();
defaultUser.setId(-1L);
defaultUser.setName("默认用户");
return defaultUser;
}
}
- 配置Feign使用降级:
@FeignClient(
name = "user-service",
fallback = UserFeignFallback.class // 指定降级类
)
public interface UserFeignClient {
@GetMapping("/{id}")
User getUserById(@PathVariable("id") Long id);
}
118. Spring Cloud Gateway的作用是什么?它和Zuul有什么区别?
原理说明
- Spring Cloud Gateway是Spring官方推出的API网关,基于***ty和WebFlux实现,提供路由转发、负载均衡、熔断、限流等功能,用于统一管理微服务的入口请求。
主要作用
- 路由转发:根据请求路径、方法等规则将请求转发到对应的微服务。
- 过滤器链:通过前置/后置过滤器实现认证授权、日志记录、请求转换等。
- 负载均衡:集成Ribbon,自动从注册中心获取服务实例并分发请求。
- 熔断降级:结合Hystrix/Resilience4j,当后端服务故障时返回降级响应。
- 限流:限制请求速率,防止服务过载。
与Zuul的区别
| 特性 | Spring Cloud Gateway | Zuul 1.x | Zuul 2.x |
|---|---|---|---|
| 底层框架 | 基于***ty和WebFlux(响应式编程)。 | 基于Servlet(阻塞IO)。 | 基于***ty(非阻塞IO)。 |
| 性能 | 高(非阻塞,支持异步)。 | 较低(阻塞IO,线程池易耗尽)。 | 较高(非阻塞)。 |
| 功能 | 支持动态路由、限流、熔断等。 | 基础路由、过滤,需扩展实现高级功能。 | 支持非阻塞,但生态不如Gateway成熟。 |
| 集成性 | 与Spring Cloud生态无缝集成(如Spring Security)。 | 需手动集成Spring Cloud组件。 | 集成性一般。 |
| 开发活跃度 | 持续更新,为Spring Cloud推荐网关。 | 已停止维护。 | 活跃度低。 |
Gateway配置示例
spring:
cloud:
gateway:
routes:
- id: user-service-route # 路由ID
uri: lb://user-service # 转发到user-service(lb表示负载均衡)
predicates: # 路由条件
- Path=/users/** # 匹配路径
filters: # 过滤器
- StripPrefix=1 # 移除路径前缀(/users/1 → /1)
- name: RequestRateLimiter # 限流过滤器
args:
redis-rate-limiter.replenishRate: 10 # 令牌桶填充速率
redis-rate-limiter.burstCapacity: 20 # 令牌桶容量
119. 什么是分布式配置中心?Spring Cloud Config的作用是什么?
原理说明
- 分布式配置中心是集中管理多个微服务配置的系统,解决分布式环境中配置分散、更新繁琐、环境不一致等问题。
- 核心功能:集中存储配置、支持多环境、配置动态刷新、版本控制。
Spring Cloud Config的作用
- 集中管理配置:将所有服务的配置文件(如application.yml)存储在Git、SVN或本地文件系统,统一维护。
-
多环境支持:通过
{application}-{profile}.yml区分环境(如user-service-dev.yml)。 -
配置动态刷新:服务无需重启即可获取最新配置(配合
@RefreshScope)。 - 安全性:支持配置加密解密,保护敏感信息(如数据库密码)。
实现步骤
1. 搭建Config Server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
@EnableConfigServer // 启用配置服务器
@SpringBootApplication
public class ConfigServerApplication { ... }
# 配置Git仓库地址
spring:
cloud:
config:
server:
git:
uri: https://github.***/example/config-repo.git # 配置仓库
search-paths: configs # 配置文件存放目录
application:
name: config-server
server:
port: 8888
2. 配置Config Client(微服务)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
# bootstrap.yml(优先于application.yml加载)
spring:
cloud:
config:
uri: http://localhost:8888 # Config Server地址
name: user-service # 配置文件名前缀
profile: dev # 环境
application:
name: user-service
3. 动态刷新配置
@RestController
@RefreshScope // 启用配置刷新
public class ConfigController {
@Value("${app.version}") // 注入配置
private String appVersion;
@GetMapping("/version")
public String getVersion() {
return appVersion;
}
}
- 修改Git仓库配置后,发送POST请求
http://localhost:8080/actuator/refresh触发刷新。
120. 什么是服务链路追踪?Spring Cloud Sleuth和Zipkin如何配合使用?
原理说明
- 服务链路追踪用于监控微服务调用链,记录请求从客户端到各个服务的流转路径、耗时和状态,帮助排查跨服务问题(如延迟、故障点)。
核心概念
- Trace ID:全局唯一标识,贯穿整个请求链路。
- Span ID:每个服务调用的局部标识,父子Span形成调用关系。
- Annotation:标记Span的状态(如请求开始、结束)。
Sleuth与Zipkin的配合
- Spring Cloud Sleuth:生成Trace ID和Span ID,在日志中标记调用链路,但不提供可视化界面。
- Zipkin:收集Sleuth生成的追踪数据,提供Web界面展示链路拓扑、耗时分析等。
使用步骤
- 引入依赖:
<!-- 服务端和客户端都需引入 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
- 配置Zipkin地址:
spring:
zipkin:
base-url: http://localhost:9411 # Zipkin Server地址
sleuth:
sampler:
probability: 1.0 # 采样率(1.0表示全部采样,生产环境可设0.1)
- 启动Zipkin Server:
java -jar zipkin-server-2.23.0-exec.jar
- 访问Zipkin界面:
打开http://localhost:9411,可查看服务调用链路、每个Span的耗时等信息。
效果
- 调用链路示例:
客户端 → Gateway → 订单服务 → 用户服务,Zipkin会展示完整路径及各环节耗时。
121. Spring Cloud中如何实现分布式锁?
原理说明
- 分布式锁用于解决分布式系统中多个服务实例竞争共享资源的问题(如库存扣减、订单创建),保证操作的原子性。
- 常见实现方式:基于Redis、ZooKeeper或数据库。
基于Redis实现分布式锁(Redisson)
- 引入依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.16.4</version>
</dependency>
- 配置Redis:
spring:
redis:
host: localhost
port: 6379
- 使用分布式锁:
@Service
public class InventoryService {
@Autowired
private RedissonClient redissonClient;
@Autowired
private InventoryMapper inventoryMapper;
public void deductStock(Long productId) {
// 获取锁(锁名称需唯一,如"inventory:"+productId)
RLock lock = redissonClient.getLock("inventory:" + productId);
try {
// 尝试加锁,最多等待10秒,上锁后10秒自动释放
boolean locked = lock.tryLock(10, 10, TimeUnit.SECONDS);
if (locked) {
// 执行业务逻辑(扣减库存)
Inventory inventory = inventoryMapper.selectById(productId);
if (inventory.getStock() > 0) {
inventory.setStock(inventory.getStock() - 1);
inventoryMapper.updateById(inventory);
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
// 释放锁(仅持有锁的线程可释放)
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
核心特性
- 自动续期:Redisson会自动延长锁的有效期,避免业务未完成锁过期。
- 公平锁:支持公平锁机制,防止线程饥饿。
- 可重入:同一线程可多次获取同一把锁。
122. 什么是API网关?它的主要功能有哪些?
原理说明
- API网关是微服务架构的入口层,统一接收客户端请求并转发到对应的微服务,集中处理跨服务的共性需求。
主要功能
-
路由转发:根据请求路径、域名等规则将请求分发到目标服务(如
/api/users/*转发到用户服务)。 - 认证授权:集中验证用户身份(如JWT令牌校验),拒绝未授权请求。
- 限流熔断:限制请求速率(防止过载),当服务故障时返回降级响应。
- 日志监控:记录所有请求的详细信息(路径、耗时、状态),便于问题排查。
- 协议转换:将客户端的HTTP请求转换为服务间的内部协议(如gRPC)。
- 请求/响应转换:修改请求参数或响应数据(如添加统一响应格式)。
- 缓存:缓存高频请求结果,减少后端服务压力。
典型场景
- 移动端、Web端通过网关访问微服务,无需关心服务实例的IP和端口。
- 网关拦截恶意请求,保护后端服务安全。
- 对不同客户端(如APP、小程序)提供差异化的API版本。
123. Spring Cloud Alibaba包含哪些组件?
Spring Cloud Alibaba是阿里巴巴开源的微服务解决方案,兼容Spring Cloud标准,提供了更贴合国内场景的组件:
-
服务注册与发现
- Nacos:动态服务发现、配置管理和服务元数据管理,替代Eureka和Config。
-
服务熔断与降级
- Sentinel:流量控制、熔断降级、系统负载保护,替代Hystrix。
-
分布式事务
- Seata:高性能分布式事务解决方案,支持AT、T***等模式。
-
消息队列
- RocketMQ:低延迟、高可靠的分布式消息系统,支持事务消息。
-
分布式配置
- Nacos:同时支持配置管理,动态推送配置变更。
-
API网关
- Spring Cloud Alibaba Gateway:基于Spring Cloud Gateway,集成Nacos、Sentinel等组件。
-
服务治理
- Dubbo:高性能RPC框架,支持服务注册、负载均衡(与Spring Cloud集成)。
优势
- 组件国产化,文档丰富,适配国内云环境(如阿里云)。
- 各组件兼容性好,开箱即用(如Nacos同时解决服务发现和配置问题)。
124. 什么是服务熔断和服务降级?它们的区别是什么?
概念定义
- 服务熔断:当服务调用失败率超过阈值,熔断器快速失败并阻止新请求访问该服务,避免故障扩散(类似电路保险丝)。
- 服务降级:当系统负载过高或服务不可用时,返回简化的响应(如缓存数据、默认值),牺牲非核心功能保证核心功能可用。
区别对比
| 特性 | 服务熔断 | 服务降级 |
|---|---|---|
| 触发条件 | 服务调用失败率高(如超时、异常)。 | 系统负载高(如CPU/内存满)、非核心服务降级。 |
| 目的 | 防止故障扩散,保护调用方。 | 保证核心服务可用,牺牲非核心功能。 |
| 执行时机 | 调用前判断(熔断器状态)。 | 通常在调用时或资源不足时触发。 |
| 恢复机制 | 熔断器自动尝试恢复(半开状态)。 | 需手动或按计划恢复(如负载降低后)。 |
| 示例 | 用户服务故障,订单服务调用时直接熔断。 | 秒杀活动时,关闭商品详情页的评论功能。 |
联系
- 两者都是保障系统稳定性的手段,常结合使用(如熔断后自动触发降级)。
- 最终效果都是让调用方获得非预期但可控的响应。
125. 如何设计一个高可用的微服务架构?Spring Cloud有哪些支持?
高可用设计原则
- 服务无状态:服务实例可随时替换,避免依赖本地存储(使用Redis、数据库共享状态)。
- 服务集群化:每个服务部署多个实例,通过负载均衡(Ribbon)分散请求。
- 故障隔离:通过熔断器(Hystrix)、线程池隔离防止单个服务故障影响全局。
- 限流降级:对入口流量(Gateway)和服务间调用限流,非核心服务降级。
- 数据一致性:使用分布式事务(Seata)或最终一致性方案(事件驱动)。
- 监控告警:通过Actuator、Sleuth+Zipkin监控服务状态,及时发现故障。
- 自动扩缩容:结合Kuber***es等容器平台,根据负载自动调整服务实例数量。
- 多区域部署:跨机房/地域部署,避免单点故障。
Spring Cloud的支持
-
服务高可用:
- Eureka集群(多节点注册中心)、Nacos集群保证服务发现高可用。
- Ribbon/Feign负载均衡分发请求到多个服务实例。
-
容错机制:
- Hystrix/Resilience4j实现熔断降级,防止服务雪崩。
- Spring Cloud Gateway限流保护后端服务。
-
配置可靠性:
- Spring Cloud Config/Nacos配置中心集群,支持配置持久化和动态刷新。
-
监控与诊断:
- Actuator暴露健康检查和metrics端点。
- Sleuth+Zipkin追踪服务调用链路,快速定位问题。
-
安全保障:
- Spring Cloud Security提供统一认证授权,防止未授权访问。
通过以上设计和工具,可构建一个弹性强、故障自愈能力高的微服务架构。
二、125道Spring面试题目录列表
| 文章序号 | Spring面试题125道 |
|---|---|
| 1 | Spring面试题及详细答案125道(01-15) |
| 2 | Spring面试题及详细答案125道(16-25) |
| 3 | Spring面试题及详细答案125道(26-45) |
| 4 | Spring面试题及详细答案125道(46-65) |
| 5 | Spring面试题及详细答案125道(66-75) |
| 6 | Spring面试题及详细答案125道(76-90) |
| 7 | Spring面试题及详细答案125道(91-110) |
| 8 | Spring面试题及详细答案125道(111-125) |