1.什么是RPC和HTTP,有什么区别
一、 知识点讲解
RPC 的全称是 Remote Procedure Call(远程过程调用)。
它的核心设计目标是:让程序员像调用本地函数一样,去调用远程服务器上的函数。
你写代码时是 result = service.add(a, b),完全不需要关心这行代码怎么打包、怎么发给 B 机器、B 机器怎么解包、怎么传回来。
而 HTTP(这里主要指 RESTful API)是一种基于资源的通信模式,你需要关心 URL、Method(GET/POST)、Header、Body 等协议细节。
RPC 的机制
RPC 之所以能让你感觉在调本地函数,是因为它在客户端和服务端都安插了“桩”。
Client Stub:负责把你的参数(
a, b)序列化成二进制,通过网络发出去。Server Stub: 负责收到二进制,反序列化回参数,真正去执行方法,把结果再打包发回去。
这个过程对开发者是透明的。
载荷与传输
数据包大小(序列化):
HTTP (JSON):为了可读性,包含大量冗余字符(如
{ "name": "user" })。RPC (Protobuf/Thrift):二进制压缩。同样的数据,可能只需要几个字节,没有字段名,只有位置信息。更小,传输更快。
传输协议:
HTTP:通常基于 HTTP/1.1,文本协议,Header 很重(User-Agent, Cookie 等一大堆元数据)。
RPC:通常直接基于 TCP(如 Dubbo 协议)或者 HTTP/2(如 gRPC)。它可以自定义精简的头部,去除无用的元数据。更轻,解析更快。
为什么要有 RPC?
既然 HTTP 通用性这么强,浏览器、手机都能用,为什么后端微服务之间还要搞一套 RPC?
答案是效率和契约。
效率:内部服务调用频次极高(甚至上亿次),哪怕每次调用节省 0.1ms 的序列化时间和 1KB 的带宽,累积起来也是巨大的成本节省。
契约(强类型):RPC 框架通常有 IDL 文件(如
.proto),强制约束了入参出参类型。不像 HTTP JSON 那样松散,这在大型团队协作中能减少很多“参数传错”的 Bug。
二、 面试标准回答
RPC(远程过程调用)和 HTTP(超文本传输协议)在分布式系统中都是节点间通信的方式。
严格来说,它们不在同一个维度:RPC 是一种调用远程服务的方法论/技术,而 HTTP 是一个具体的传输协议。事实上,很多现代 RPC(如 gRPC)底层就是基于 HTTP/2 实现的。
在实际开发和对比中,我们通常是指 “基于 TCP/二进制协议的 RPC” 与 “基于 HTTP/JSON 的 RESTful API” 之间的区别。
第一,设计初衷与使用体验不同。
RPC的核心目标是透明性。它让开发者像调用本地方法一样调用远程服务,屏蔽了网络细节。
HTTP (REST)的核心是标准化。它强调资源的通用交互,使用统一的接口。
第二,传输效率与协议开销不同。
序列化:HTTP 通常使用 JSON,是基于文本的,可读性好但体积大,解析慢。RPC 通常使用 Protobuf、Thrift 或 Hessian 等二进制序列化协议,体积极其紧凑,CPU 解析效率极高。
报文头:HTTP/1.1 携带了大量 Header(Cookie、User-Agent 等),对于微服务内部的高频调用,这些是纯粹的带宽浪费。RPC 通常使用自定义的 TCP 协议(如 Dubbo 协议),报文头极精简,专为服务间通信设计。
第三,连接模型不同。
传统的 HTTP/1.1 是短连接(虽然有 Keep-Alive 但仍有队头阻塞问题)。
RPC 框架通常基于TCP 长连接,并利用IO 多路复用技术,实现连接池管理和真正的并发复用,更适合内部高并发场景。
第四,应用场景不同。
RPC:主要用于公司内部微服务之间的通信。因为内部网络环境可控,我们更追求极致的性能和强类型的接口约束。
HTTP:主要用于对外接口,比如提供给前端、App 或第三方。因为 HTTP 协议是互联网通用的,兼容性最好,没有任何技术门槛。
2.什么是spring框架
Spring 不仅仅是一个框架,更是一个生态。它的核心理念是通过 IoC 和 AOP 来解耦,从而简化企业级应用的开发复杂度。
一、 核心维度深度解析
核心定位:容器与管理
- **传统方式:** 我们需要自己 `new` 对象,自己管理对象的生命周期,自己处理依赖关系(比如 A 依赖 B,B 依赖 C)。 - **Spring 方式:** Spring 就是一个**容器**。你把对象(Bean)交给它,它帮你创建、初始化、销毁,并自动把依赖注入进去。 - **本质:****非侵入式**的。你的业务代码不需要继承 Spring 的特定类,甚至不需要依赖 Spring 的包(在最纯粹的 POJO 模式下)。
两大基石:IoC 和 AOP
- IoC (控制反转): 解决的是对象之间耦合的问题。 - **AOP**** (****面向切面编程****):** 解决的是**业务逻辑与系统服务****耦合**的问题。 * 比如日志、事务、权限检查。这些代码到处都是,Spring 把它们抽离出来,动态地“织入”到业务方法中。
现代演进:从框架到全家桶
- 早期的 Spring 是一堆 XML 配置,很繁琐。 - 现在的 Spring 指的是 **全家桶**。 * **Spring Boot:** 约定优于配置,快速启动。 * **Spring Cloud:** 微服务治理。 * **Spring Security:** 安全框架。
二、 面试标准回答
Spring 是 Java 企业级开发事实上的标准。它不仅仅是一个框架,更是一个庞大的技术生态。它的核心使命只有一句话:简化 Java 开发。
具体可以从三个维度来理解:
第一,核心层面:
这是 Spring 最根本的两大基石。
IoC(控制反转):Spring 作为一个容器,接管了对象的创建和管理权。它通过依赖注入(DI),让我们不需要手动
new对象,而是由容器自动组装。这极大地降低了组件之间的耦合度。AOP(面向切面编程):它允许我们将日志、事务、权限等“非业务逻辑”从核心业务代码中剥离出来,统一管理。其中最经典的应用就是声明式事务,让我们只需加一个注解就能控制事务,而不用写繁琐的 try-catch 代码。
第二,特性层面:
Spring 是一个非侵入式的框架,它被被称为 Java 界的“胶水”。它可以非常轻松地集成各种第三方框架,比如 MyBatis、Redis、RabbitMQ 等,让这些技术能无缝地协同工作。
第三,生态层面:
现在的 Spring 已经发展为一个全家桶。
Spring Boot通过“约定优于配置”,让我们可以零配置快速启动项目。
Spring Cloud则提供了完整的微服务解决方案。
总结一下:
Spring 本质上是一个管理 Bean 的容器,它通过 IoC 和 AOP 实现了代码的解耦,并以此为基础衍生出了 Spring Boot 等强大的生态,极大地提高了我们的开发效率。
3.什么是zookeeper?有什么应用场景
一、 知识点讲解
Zookeeper本质上是一个为分布式应用提供协调服务的中间件。你可以把它理解为一个高可用的分布式文件系统,加上了一套事件监听机制。它主要解决的是分布式系统中的“一致性”和“管理”问题,而不是用来存大量业务数据的。
数据模型
ZK 的数据结构是一棵树,跟 Linux 文件系统很像。每个节点叫 ZNode,可以存少量数据(比如配置信息、状态标记)。
关键点:ZNode 分为持久节点、临时节点(客户端断开就删除了)、顺序节点。这是实现分布式锁等功能的基础。
监听机制(Watcher):
这是 ZK 的灵魂。客户端可以在某个 ZNode 上注册一个 Watcher。当这个节点的数据变了,或者节点被删了,ZK 会主动通知客户端。
作用:这实现了“发布/订阅”模式,比如配置改了,所有服务器立马收到通知。
一致性协议(ZAB):
ZK 保证的是 CP。通过 ZAB 协议,保证了集群中 Leader 和 Follower 之间数据的强一致性。写操作必须走 Leader,读操作可以走任意节点。
应用场景
第一,统一配置管理
这是最常用的场景。在分布式系统中,很多服务的配置是一样的。我们把配置信息放在 ZK 的某个节点上,让所有服务去监听这个节点。一旦我们需要修改配置,只需要改 ZK 里的这一处,ZK 就会立刻通知所有连接的服务去同步更新,不需要重启服务器,实现了配置的热更新。
第二,统一命名服务
这其实就是服务发现。就像 Dubbo 这类 RPC 框架,服务提供者启动时,把自己注册到 ZK 上(创建节点);服务消费者启动时,去 ZK 订阅自己需要的服务列表。这样,当服务上线或下线时,消费者能实时感知到,动态调整调用列表。
第三,分布式锁
这是为了解决多节点并发修改数据的问题。利用 ZK 的临时顺序节点特性:多个客户端同时去创建一个节点,谁创建成功(或者序号最小)谁就拿到锁。业务处理完后删除节点释放锁;如果持有锁的客户端宕机了,因为是“临时”节点,节点会自动删除,锁也就释放了,避免了死锁问题。
第四,集群管理与 Master 选举。
比如 HDFS 的 NameNode 高可用,或者 Kafka 的 Controller 选举。大家去 ZK 抢着建立同一个临时节点,谁建成了谁就是 Master。其他节点监听这个 Master 节点,一旦 Master 挂了,节点消失,其他节点收到通知立马再次发起选举,保证集群时刻有主节点在工作。
二、 面试标准回答
Zookeeper 是一个开源的分布式协调服务,它主要用来解决分布式系统中的一致性问题。简单来说,它提供了一个类似文件系统的目录树结构,配合一套高效的 Watcher 监听机制,来统一管理分布式系统中的状态和元数据。
它的应用场景主要为以下四点:
统一配置管理
将公共配置集中存储在 ZK 节点上,服务统一监听。配置变更时,ZK 实时通知各服务同步更新,实现配置热更新,无需重启。
统一命名服务(服务发现)
服务提供者向 ZK 注册,服务消费者订阅服务列表。服务上下线时,消费者可实时感知并动态调整调用关系。
分布式锁
利用临时顺序节点实现锁竞争,序号最小者获得锁;客户端宕机时临时节点自动删除,避免死锁。
集群管理与 Master 选举
通过竞争创建临时节点选举 Master,其他节点监听该节点;Master 挂掉后自动触发重新选举,保证集群高可用。
4.消息队列有什么作用
一、 知识点讲解
在单体应用或简单的微服务架构中,系统间通常使用 HTTP/RPC 进行同步调用。这就像是“打电话”,你必须等对方接通并说完话才能挂断。
MQ 的引入,把通信方式变成了“发微信”。你发完消息就去忙别的了(异步),对方什么时候看、什么时候回都可以(解耦),哪怕由于太忙暂时没回,消息也存在服务器里丢不了(削峰填谷)。
异步处理
- **场景:** 用户注册成功后,需要发注册邮件、发短信验证码、初始化积分账户。 - **痛点:** 如果串行执行,注册接口耗时 = 写入数据库(50ms) + 发邮件(100ms) + 发短信(100ms) = 250ms。用户体验很差,且受限于最慢的那个服务。 - **MQ**** 方案:** 主流程只做核心的“写入数据库”,然后往 MQ 扔一条消息“用户注册了”,直接返回成功。耗时仅需 55ms。发邮件、发短信的服务去消费这条消息即可。
系统**解耦**
- **场景:** 订单系统下单后,需要通知库存系统扣减、物流系统发货、营销系统发券。 - **痛点:** 如果直接由订单系统调用下游接口,每当新增一个下游业务(比如新增大数据分析),订单系统都要改代码、重新部署。如果下游某个系统挂了,订单系统也会报错回滚,导致无法下单。 - **MQ 方案:** 订单系统只负责把“订单已创建”这个事件发布到 MQ。谁关心这个事件,谁就自己去订阅。订单系统完全不需要知道下游有哪些人,也不受下游故障的影响。
流量削峰
- **场景:** 秒杀活动,瞬间涌入 10万 QPS,但后端数据库只能抗住 2000 QPS。 - **痛点:** 如果请求直接打到数据库,数据库瞬间宕机,整个系统瘫痪(雪崩)。 - **MQ 方案:** 所有请求先进入 MQ 排队。后端服务按照自己的处理能力(比如每秒拉取 2000 条)慢慢消费。虽然用户可能会感到一点点延迟(排队中),但系统活下来了。MQ 在这里充当了一个巨大的蓄水池。
二、 面试标准回答
在后端架构中,消息队列主要解决了三个核心问题:解耦、异步和削峰。它通过引入异步通信机制,提升了系统的扩展性和稳定性。
第一,系统解耦
这是微服务架构中最重要的作用。通过 MQ,生产者(如订单服务)只需要将业务事件发布出去,不需要关心下游有哪些消费者(如库存、物流)。这打破了强依赖,使得下游服务的变更或新增不会影响上游核心链路,同时也防止了下游故障导致上游级联失败。
第二,异步处理
我们将非核心链路的业务逻辑(如发送通知、生成报表)从主流程中剥离出来,放入 MQ 异步执行。这极大地减少了核心接口的响应时间(RT),提升了用户体验和系统的整体吞吐量。
第三,流量削峰填谷
在秒杀或大促场景下,MQ 充当了缓冲区的角色。它将瞬时的高并发流量拦截在 MQ 中,让下游系统根据自身的处理能力(如数据库连接数限制)平滑地消费消息。这避免了数据库被瞬间流量打垮,保证了系统的可用性。
5.怎么理解微服务
微服务是一种架构风格,它把一个庞大的单体应用拆分成了一组小的、独立的服务。每个服务只关注单一的业务功能,独立部署、独立维护数据。而 Spring Cloud 就是为了解决这些服务拆分后带来的通信、治理和运维难题而存在的。
一、 核心概念深度解析
我们可以把架构演进比作“开餐厅”:
1. 单体架构 —— 也就是“大排档”
模式:老板、厨师、收银、服务员都在一个大通铺里。
代码:所有的业务模块(用户、订单、支付、库存)都打包在一个
war包里,跑在一个 Tomcat 上。痛点:
牵一发而动全身:只是改了“支付”模块的一行代码,整个系统都得重新打包部署。
扩展性差:双 11 只有“订单”模块压力大,但你必须把整个庞大的系统都扩容,非常浪费资源。
代码**耦合:** 几年下来,模块之间互相调用,乱成一锅粥,没人敢动
2. 微服务架构 —— 也就是“美食城”
模式:把大排档拆成了独立的小档口。卖面的只管卖面,卖饮料的只管卖饮料。
拆分原则:**按业务领域拆分**
用户服务:只管用户注册登录。
订单服务:只管下单。
库存服务:只管扣减库存。
特征:
独立部署:订单服务挂了,不影响用户服务查资料。
3. Spring Cloud 的角色 —— 美食城物业管理
拆分成了 100 个服务后,麻烦来了:
怎么知道每个档口在哪?(注册中心 - Nacos/Eureka)
档口之间怎么传话?(RPC 调用 - Feign/Dubbo)
某个档口着火了怎么办?(熔断 - Sentinel/Hystrix)
大门怎么管理?(网关 - Gateway)
二、 面试标准回答
简单来说,微服务就是一种将单体应用“化整为零”的架构风格。
具体可以从三个维度来阐述:
第一,从“拆分”的角度:
以前的单体应用,所有的业务模块(比如用户、订单、库存)都耦合在一个项目中,打成一个包部署。
而微服务主张按照“业务领域”将系统拆分成一个个独立的、松耦合的小服务。每个服务只关注单一的业务功能。
第二,从“运行”的角度:
拆分后的每个微服务,都是一个独立的进程。
它们可以独立部署和升级,不需要为了改一个模块而重启整个系统。
它们可以独立扩展,比如订单服务压力大,我只需要给订单服务增加节点,而不需要扩容整个系统。
第三,从“代价”的角度:
微服务虽然解决了耦合和扩展性问题,但也带来了巨大的分布式复杂性。
比如服务之间如何发现?网络通信失败了怎么办?分布式事务怎么处理?
这就是Spring Cloud存在的意义。它提供了一整套治理工具(如 Nacos、Feign、Gateway、Sentinel),帮我们屏蔽了这些分布式系统的复杂性,让我们能像开发单体应用一样开发微服务。