当前位置: 首页 > news >正文

失败的面试经历二(ʘ̥∧ʘ̥)

之前面试是线上面试面的都是技术方面的东西,而这次面试的主要内容是对项目进行提问,少部分问了技术,我的项目就是一个非常大众的电商项目,还有一个酒店管理,在这个电商系统当中,有一些业务场景是需要一些技术来实现的,此次面试就是围绕这个话题开始的。

真拿我当日本人整啊,boss上说招后端,到了之后告诉我招全栈了,然后就开2k。

下面是我整理的面试题:

一,RocketMQ的原理

RocketMQ 是一款高吞吐量、高可扩展性的分布式消息中间件,其架构设计与内部机制确保了在大规模分布式系统中高效、可靠地进行消息传递。以下从工作原理、架构设计和消息流转机制三个方面进行解析。

1.架构设计
RocketMQ 的整体架构由四个核心组件组成:Producer(生产者)、Consumer(消费者)、Broker(消息服务器) 和 NameServer(命名服务)。

  • Producer负责将消息发送到 Broker。
  • Consumer 从 Broker 拉取消息并进行消费。
  • Broker 是消息的存储中心,负责接收来自 Producer 的消息并将其持久化,同时向 Consumer 提供消息读取服务。
  • NameServer 是一个轻量级的服务发现组件,负责管理 Broker 的路由信息,并提供给 Producer 和 Consumer 使用。

2.工作原理
RocketMQ 的工作流程主要包含以下几个步骤:

  1. 消息发送:Producer 向 NameServer 查询目标 Topic 对应的 Broker 地址列表,选择其中一个Broker 并发送消息。
  2. 消息存储:Broker 接收到消息后,将其追加写入本地磁盘的日志文件中(CommitLog),并通过异步刷盘或同步刷盘方式保证消息持久化。
  3. 消息索引:为了提高查询效率,Broker 还会为每条消息建立基于 Topic 和队列(Queue)的消息索引(ConsumeQueue),以及基于键值的消息索引(IndexFile)。
  4. 消息拉取:Consumer 定期向 Broker 发起拉取请求,获取待消费的消息,并通过 Offset(偏移量)记录消费进度,实现消息的顺序性和幂等性控制。

3.消息流转机制
消息在 RocketMQ 中的流转主要包括以下环节:

  • Topic 与队列:消息按照 Topic 分类,每个 Topic 被划分为多个队列(MessageQueue),分布在不同的 Broker 上,以实现水平扩展。
  • 负载均衡:Consumer 实例启动时,会与 Broker 协调分配 MessageQueue,确保每个队列被且仅被一个 Consumer 实例消费,从而实现负载均衡。
  • 顺序消息支持:对于需要保证顺序的消息,RocketMQ 通过将同一类消息绑定到同一个 MessageQueue,并由单个线程串行处理来保障顺序性。
  • 事务消息:RocketMQ 支持事务消息机制,允许 Producer 在提交事务前暂存消息,在业务逻辑执行成功后才真正提交消息,否则回滚,从而实现本地事务与消息发送的原子性。

二,RocketMQ的订阅模式

  1. 启动NameServer,NameServer起来后监听端口,等待Broker、Producer、Consumer连上来,相当于一个路由控制中心。
  2. Broker启动,跟所有的NameServer保持长连接,定时发送心跳包。心跳包中包含当前Broker信息(IP+端口等)以及存储所有Topic信息。注册成功后,NameServer集群中就有Topic跟Broker的映射关系。
  3. 收发消息前,先创建Topic,创建Topic时需要指定该Topic要存储在哪些Broker上,也可以在发送消息时自动创建Topic。
  4. Producer发送消息,启动时先跟NameServer集群中的其中一台建立长连接,并从NameServer中获取当前发送的Topic存在哪些Broker上,轮询从队列列表中选择一个队列,然后与队列所在的Broker建立长连接从而向Broker发消息。
     

三,使用RocketMQ技术实现订单超时问题

1.消息提供者:

public class Producer {//演示消息同步发送public static void main(String[] args) throws InterruptedException, RemotingException, MQClientException, MQBrokerException {//生产者DefaultMQProducer producer = new DefaultMQProducer("syn-producerGroup-delay");//设置name server地址producer.setNamesrvAddr("127.0.0.1:9876");//启动producer.start();for (long i = 0 ; i < 4 ; i++){Order order = new Order(i,"订单"+i,"创建");//添加内容byte[] bytes = (JSON.toJSONString(order)).getBytes(CharsetUtil.UTF_8);Message message = new Message("topic-order-delay","product-order-delay",bytes);
//延迟级别 3,代表 10s延迟message.setDelayTimeLevel(3);message.setKeys("key-"+i);//执行发送SendResult result = producer.send(message);System.out.println("发送时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));System.out.println(result);}producer.shutdown();}
}

2.消息消费者:

public class Consumer {public static void main(String[] args) throws MQClientException {//创建消费者DefaultMQPushConsumer defaultMQPushConsumer = new DefaultMQPushConsumer("syn-consumerGroup-delay");//设置name server 地址defaultMQPushConsumer.setNamesrvAddr("127.0.0.1:9876");//从开始位置消费defaultMQPushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);//订阅defaultMQPushConsumer.subscribe("topic-order-delay","product-order-delay");defaultMQPushConsumer.registerMessageListener(new MessageListenerConcurrently() {@Overridepublic ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {list.forEach(message->{System.out.println("消费时间:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));System.out.println(message+" ; "+new String(message.getBody(), CharsetUtil.UTF_8));});return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;}});defaultMQPushConsumer.start();}
}

四,创建线程的方法

具体请看我这篇博客,其中就有创建线程的三个方法

失败的面试经历(ʘ̥∧ʘ̥)-CSDN博客https://blog.csdn.net/2302_80464795/article/details/146266266?spm=1001.2014.3001.5501

五,springcloud有哪些组件

1.注册中心组件(Eureka)

  • Spring Cloud 提供了多种注册中心的支持,如:Eureka、Consul、ZooKeeper 等,Netflix Eureka 本身是一个基于 REST 的服务,包含两个组件:Eureka Server 和 Eureka Client;

作用:

  • Eureka Server 提供服务注册服务,各个节点启动后,会在 Eureka Server 中进行注册,这样 Eureka Server 的服务注册表将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到;
  • Eureka Server 之间通过复制的方式完成数据的同步,Eureka 还提供了客户端缓存机制,即使所有的 Eureka Server 都挂掉,客户端依然可以利用缓存中的信息消费其他服务的 API;
  • Eureka Client:生产者或消费者;
  • 在应用启动后,Eureka Client 将会向 Eureka Server 发送心跳,默认周期为 30 秒,如果 Eureka Server 在多个心跳周期内(默认 90 秒)没有接收到某个节点的心跳,Eureka Server 将会进入自我保护机制;

2.负载均衡组件(Ribbon)

  • 适用于 Spring Cloud 2020 之前的版本;

  • Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起,Ribbon 客户端组件提供一系列完善的配置项如连接超时,重试等,

  • 简单的说,就是在配置文件中列出 Load Balancer 后面所有的机器,Ribbon 会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器,我们也很容易使用 Ribbon 实现自定义的负载均衡算法;

  • 作用:Ribbon,主要提供客户侧的软件负载均衡算法。

  • 简介:Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡的服务调用。

负载均衡策略:

  • RoundRobinRule ---- 轮询、默认;
  • RandomRule ---- 随机;
  • RetryRule ---- 重试机制;
  • BestAvailableRule ---- 选择最小并发 server;
  • AvailabilityFilteringRule ---- 过滤高并发、失败 server;
  • WeightedResponseTimeRule ---- 根据响应时长比重选择中间值;
  • ZoneAvoidanceRule ---- 判断 server 性能;
  • 查看 com.netflix.loadbalancer.IRule 接口;

3.熔断器组件(Resilience4j)

简介:

  • 推荐 Spring Cloud 2020 之后版本使用;
  • Resilience4j 是 Spring Cloud G 版本推荐的容错方案,是一个轻量级的容错库,专为 Java 8 和函数式编程而设计,借鉴了 Hystrix 的设计,提供了断路器(CircuitBreaker)、并发调用隔离(Bulkhead)、限流(RateLimiter)、重试(Retry)、超时(Timeout) 等功能;
  • 断路器 CircuitBreaker
  • 断路器一般通过 3 个有限状态机来实现:CLOSED、OPEN、HALF_OPEN,此外,还有 2 个特殊的状态机:DISABLED 和 FORCED_OPEN,状态的存储更新必须是线程安全的,即只有一个线程能够在某个时间点更新状态;

  • 关闭 ----> 打开:当故障率等于或大于可配置的阈值时,CircuitBreaker 的状态将从“关闭”更改为“打开”。
  • 打开 ----> 半开:当 CircuitBreaker 打开时,它会拒绝带有 CallNotPermittedException 的调用,经过一段等待时间后,CircuitBreaker 状态从 OPEN 变为 HALF_OPEN,并允许可配置数量的服务调用是否仍然不可用或再次变为可用,用 CallNotPermittedException 拒绝其他调用,直到所有允许的调用完成,如果故障率或慢呼叫率等于或大于配置的阈值,则状态会变回 OPEN;
  • 半开 ----> 关闭:如果故障率和慢呼叫率低于阈值,则状态将变回“已关闭”;
  • DISABLED:始终拒绝调用;
  • FORCED_OPEN:始终允许调用;

并发调用隔离 Bulkhead

  • 在系统设计中,需要预期故障的发生,将应用程序拆分成多个组件,通过资源隔离确保一个组件的故障不会影响其他的组件,就像轮船用隔板(Bulkhead)分成多个小隔间,每个隔间都被隔板密封,这样可以防止进洪水时整艘船沉没;
  • 两个服务 A 和服务 B,A 的某些 API 依赖 B,当服务 B 运行速度非常慢的时候,A 调用 B 的请求变多时,A 的性能会受到影响,服务 A 中那些不依赖于服务 B 的功能也无法处理,因此,需要隔离 A 中依赖 B 的请求,Resilience4j 提供了 SemaphoreBulkhead 和 FixedThreadPoolBulkhead 来实现 Bulkhead;

限流 RateLimiter

  • 微服务在给定的时间内设置可以处置的最大请求数,控制吞吐量来帮助保护服务器免于过载;

重试 Retry

  • 微服务体系中,多个服务互相依赖,当被依赖的服务出现问题而无法按预期响应时,就会级联到下游服务,导致不良的用户体验,通常我们会为每个微服务部署多个实例,如果其中一个实例有问题,无法响应我们的请求,我们则重试该请求,负载均衡器可以将请求发送到运行状况良好的节点并正确获得响应,通过重试,有更多机会获得正确的响应;

超时 Timeout

  • 在微服务体系中,微服务相互依赖,可能因为网络的原因,导致消费者阻塞,在设计时需要设置超时来应对服务缓慢 、不可用性问题;

4.网关服务组件(Zuul)

  • 将权限控制、日志收集从服务单元中抽离出去,最适合的地方是服务集群的最外端,我们需要一个功能更强大的负载均衡器,网关服务;
  • 网关服务是微服务架构中不可或缺的一部分,它具备统一向外提供 Rest Api、服务路由、负载均衡、权限控制等功能,为微服务架构提供了门前保护,除了安全之外,还能让服务集群具备高可用性和测试性;
  • Zuul 是 NetFlix 开源的微服务网关,可以和 Eureka、Ribbon、Hystrix 等组件配合使用,其核心是一系列的过滤器; 
  • 身份认证和安全:识别每个资源的验证要求,拒绝不符合要求的请求;
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图;
  • 动态路由:动态地将请求路由到不同的后端服务集群;
  • 压力测试:逐渐增加指向集群的流量;
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求;
  • 静态响应处理:在边缘位置直接建立部分响应,从而避免其转发到集群内部;
  • 多区域弹性:跨越 AWS Region 进行请求路由,实现 ELB(AWS Elastic Load Balancing ---- 负载均衡服务)使用的多样化,以及让系统的边缘更贴近系统的使用者;

  • 客户端请求微服务时,先经过 Zuul,再调用微服务集群,这样对于校验、负载均衡等功能移到了 Zuul 中实现,而微服务只需关注自身的业务逻辑则可;

5.配置中心组件(Spring Cloud Config)

  • Spring Cloud Config 为分布式系统外部化配置提供了服务端和客户端的支持,它包含 Config Server 和 Config Client 两个部分,实现了 Spring Environment  和 PropertySource 抽象的映射,非常适合 Spring 应用程序;
  • Config Server 是一个可横向扩展、集中式的配置服务器,它用于集中管理应用程序各个环境下的配置,支持 Git、SVN、本地文件存储,默认使用 Git;
  • Config Client 是 Config Server 的客户端,用于操作存储在 Config Server 中的配置内容,微服务在启动时会请求 Config Server 获取配置文件的内容,请求到后再启动容器;

1.Config Server

  • 创建仓库
  • 创建 Git 远程仓库,并将微服务所有配置文件上传到仓库中,配置文件命名规则:
  • 环境配置:application-{profile}.properties;
  • 配置中心:{application}-{profile}.profiles;
  • 创建工程,选择 Eureka Discovery Client、Config Server 组件;
  • 导入pom,配置文件以及启动类配置
  • 启动测试

2.Config Client

  •  加入bootstrap支持,pom
  • 创建bootstrap.properties
  • 拆分application.properties,本地 application.properties 中的配置分成两个部分
  • 注册部分,Eureka 相关配置、引入的其余配置文件配置(比如 logback.xml),移植到 bootstrap.properties 配置文件中,注册微服务
  • 其余配置项,移植到远程配置仓库中对应的配置文件中;
  • 删除 application.properties 配置(我对之进行重命名备份);
  • 微服务启动,到注册中心中去注册,才能获取配置中心提供的功能,去读取git仓库中的配置文件
  • 注册中心配置,就需要从application.properties移到bootstrap.properties;
  • 配置加载顺序:
  • 读本地 bootstrap.properties
  • 到注册中心注册服务
  • 连接 Config Server,加载远程配置 applicationTest-dev.properties
  • 加载本地 application.properties;

六,若依框架是什么

若依框架是一个基于Spring Boot和Spring Cloud的企业级快速开发平台。它集成了多种常用的技术栈和中间件,旨在帮助企业快速构建稳定、高效的应用系统。以下是关于RuoYi框架的详细介绍和基本使用教程,涵盖了从环境搭建到核心功能的使用。

http://www.dtcms.com/a/276179.html

相关文章:

  • 【赵渝强老师】国产数据库TiDB的代理路由:TiProxy
  • K3S滚动发布Jar
  • TCP详解——各标志位
  • 字母异位词分组
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十一课——图像均值滤波的FPGA实现
  • 家用智能摄像机PRV文件删除的恢复方法
  • 牛客网50题
  • word转pdf、pdf转word在线工具分享
  • C#调用Matlab生成的DLL
  • C#枚举:从基础到高级的全方位解析
  • NLP分词notes
  • 用一张“冰裂纹”石墨烯薄膜,让被动散热也能做 AI 推理——基于亚波长裂纹等离激元的零功耗温度-逻辑门
  • 深度学习图像分类数据集—铜片划痕识别分类
  • 创客匠人:解析创始人 IP 打造对知识变现的深层赋能
  • position: fixed和sticky的区别
  • 子数组最大平均数 I
  • Dataset类代码实战
  • 【LeetCode 热题 100】25. K 个一组翻转链表——迭代+哨兵
  • Spring AOP 是如何生效的(入口源码级解析)?
  • SpringBootloggers未授权访问漏洞处理
  • Flink创建执行环境的三种方式,也是Flink搭建程序的第一步
  • [特殊字符] 实时数据洪流突围战:Flink+Paimon实现毫秒级分析的架构革命(附压测报告)——日均百亿级数据处理成本降低60%的工业级方案
  • Java应用全链路故障排查实战指南:从系统资源到JVM深度诊断
  • WebSocket:构建实时交互的 Web 应用
  • C# VB.NET多进程-管道通信,命名管道(Named Pipes)
  • C语言结构体
  • C++---<cctype>
  • 2025科大讯飞AI大赛<大模型技术方向>(Datawhale AI 夏令营)
  • 解决bash终端的路径名称乱码问题
  • Redis渗透思路总结