编程导航微服务话题讨论

微服务

30 参与
分享

快来分享你的内容吧~

点击登录,快来和大家讨论吧~
表情
图片
话题
打卡
综合
交流
文章
问答

关于Python的Langchain系列还是Java的SpringAI

### 个人情况 有后端开发基础,目前想转agent开发 ### 学习内容 有后端Spring系列相关技能,回一些基础的springai 和Langchain ### 学习问题 想学习Agent开发,不知道是以python为主还是java系列, ### 期望帮助 关于目前企业的主流需求,是以python相关的技术栈为主,还是Java的springAI还是Langchain4j呢

《Spring AI Alibaba 1.1.2.0 企业级智能体与多智能体开发实战》

## 课程名称 《Spring AI Alibaba 1.1.2.0 企业级智能体与多智能体开发实战》 基于 Java2AI 官方最新教程 + 阿里云实战案例 ## 一、问题描述(当前用户痛点与概念困惑) 面向 Java 开发者的 AI 课程目前普遍存在以下问题: - 版本滞后,缺少 Spring AI Alibaba 1.1.2.0 最新特性讲解。 - 偏概念或偏 Python,Java 工程落地路径不清晰。 - 少有完整“企业级智能体 + 多智能体协同”项目闭环。 - 对 Agent Skills、Graph 并行条件边、异步工具执行等能力讲解不成体系。 - 缺少“工作流智能体”与低代码编排结合的系统化实战,难以快速服务业务团队。 ## 二、背景信息(技术栈与版本上下文) - 核心框架:Spring AI Alibaba 1.1.2.0(2026 年 2 月发布) - 开发语言:Java(Spring Boot 生态) - 模型平台:DashScope 通义千问 - 实战定位:企业级 OA 智能助手 + 多部门协同系统 - 目标人群:鱼皮受众中的 Java 后端 / Spring 开发者 ## 三、希望解答的核心问题(课程目标导向) 1. 如何基于 Java 原生栈高效落地 Agent Skills,并形成可复用技能库? 2. 多智能体串行 + 并行协作在真实业务中如何设计通信协议和容错机制? 3. Graph 并行条件边、AllOf/AnyOf 聚合、异步工具执行如何落地到可维护工程? 4. 如何把 RAG、权限控制、人在回路整合为企业可上线的 AI 系统? 5. 如何构建支持拖拽式编排的“工作流智能体”平台,让产品和运营也能参与流程配置? ## 四、当前理解与已验证方向(现有判断 + 已尝试路径) - 已确认 Spring AI Alibaba 1.1.2.0 在 Agent Skills、多智能体、Graph 能力上有明显升级,具备课程价值。 - 已对齐官方与社区资料来源,具备权威背书与案例基础。 - 已明确课程主线采用“需求 -> 架构 -> 代码 -> 部署”全流程,避免只讲 API。 - 已完成内容骨架设计,覆盖基础、进阶、企业实战与面试扩展。 - 已规划把“工作流智能体”作为企业级能力重点,覆盖低代码编排、流程版本管理和发布治理。 ## 五、期望提供的课程支持(希望得到的帮助) - 输出一门进阶课程,承接现有 Spring AI 基础课,形成完整学习路径。 - 保持鱼皮实战风格:可运行源码 + 逐步演示 + 作业答疑 + 项目点评。 - 强化工程价值:性能调优、可观测性、权限治理、上线部署与面试复盘。 - 增加“工作流智能体”专章:从节点设计、编排协议到可视化流程发布,形成可复用方案。 ## 六、相关资料与参考示例(便于快速理解与评估) ### 1)课程核心内容模块 | 模块 | 核心知识点 | 实战案例 | | --- | --- | --- | | 基础篇 | Spring AI 1.1.2 核心 API、DashScope 通义千问集成、MCP 注解工具调用 | 10 行代码实现智能聊天机器人 | | Agent Skills 系统 | 技能自动扫描 / 挂载、SkillPromptAugmentAdvisor、技能模块化 | 文件读写 + Shell 执行 + DB 查询技能库 | | 多智能体并行 | SequentialAgent、ParallelAgent、多智能体通信协议 | 合同审核:市场 + 技术 + 财务多智能体协同 | | Graph 高级特性 | 并行条件边、AllOf/AnyOf 聚合、异步工具执行、returnDirect | 电商评价多维度并行分析流程 | | 工作流智能体与低代码编排 | 工作流 DSL、节点抽象(LLM/工具/审批/条件/并行)、流程版本化、可视化编排、运行时监控与回放 | OA 请假审批 + 知识库检索 + 自动通知的一体化智能流程 | | 企业级能力 | Spring AI Alibaba Admin、Prompt 工程、人在回路、RAG | 带权限控制的企业知识库问答平台 | | 项目实战 | 需求分析 -> 架构 -> 编码 -> 优化 -> 部署上线 | 可直接落地的企业级多技能 AI 应用 | ### 2)课程亮点设计 - Skills 技能封装:代码量减少 60%,开发效率提升 3-5 倍,适合企业快速落地。 - Graph 可视化:结合 Spring AI Alibaba Admin 实现 AI 流程可视化编排。 - 工作流智能体:支持低代码拖拽编排、流程模板复用、版本发布与灰度回滚。 - 性能调优:多智能体并行线程池、异步超时、Token 优化。 - 面试向:Spring AI vs LangChain4j 对比、AI 项目面试高频题。 ### 3)适合人群与学习收益 适合人群:Java 后端、Spring 开发者、想转型 AI 应用的工程师(鱼皮核心受众)。 学习收益: - 掌握 Java 生态最前沿 AI 应用开发框架。 - 拥有可写进简历的企业级 AI 项目。 - 把 AI 能力无缝集成到现有 Spring Boot 系统。 - 从“会用 AI”提升到“会设计 AI 系统”。 - 具备“工作流智能体”落地能力,可搭建低代码 AI 流程平台并支持业务自助编排。 ### 4)推荐授课形式 - 视频课时:12-15 节,每节 30-45 分钟(理论 + 代码演示 + 实战)。 - 配套资料:完整源码、接口文档、技能模板、工作流编排模板、部署脚本、面试指南。 - 互动模式:作业批改 + 答疑 + 项目点评(对齐鱼皮现有课程风格)。 ### 5)与现有课程互补性 - 已有 Spring AI 基础课,本课程可作为高级进阶篇。 - 聚焦:最新版本 + 技能系统 + 多智能体并行两大核心升级。 - 形成:基础 -> 实战 -> 高级企业级 的完整学习路径。 ### 6)课程资源渠道 - Java2AI 官网:https://java2ai.com - 阿里云开发者社区:https://developer.aliyun.com - Spring AI Alibaba GitHub:https://github.com/alibaba/spring-ai-alibaba ## 总结 这门课紧跟最新版、纯 Java、强实战、高落地,并新增“工作流智能体 + 低代码编排”核心能力,且提案结构已覆盖“问题-背景-疑问-尝试-期望-资料”六个决策维度,适合直接用于对鱼皮的课程立项沟通。

RuoYi微服务监控与主从复制实现方案

### Bug 描述 关于“RuoYi微服务版”正式环境接口总是出现接口超时问题以及微服务如何进行单个服务进行调试。 ### 复现时机 出现异常是随机出现的,因为我们的云服务是在美国的弗吉尼亚,我们这个业务都是在国内进行访问,因为数据库都是在弗吉尼亚,所以跟随数据库都在弗吉尼亚。 ### 期望结果 1)我希望是可以进行分节点部署、数据库跟业务使用同一些。如果能实现主从复制最好,因为我们的数据库是通过宝塔进行部署的,现在数量量已经非常大了,如何进行主从复制以及数据的迁移。 2)我们想保证国内和国外都可以正常访问,不要出现接口超时情况。 3)微服务项目有监控微服务以及追踪接口的相关插件是否存在。想了解一下用在企业级项目中。 ### 自己的思路和解决方案 我们使用mysql 5.7版本,如何才能实现数据同步。 我已经通过nacos设置了最大连接时间,现在已经设置到45秒了还是偶发接口超时的情况。

centos7上coturn服务启动后无法访问的故障处理

### 提问背景 我正在开发webrtc的视频通话功能,建立P2P的连接需要搭建stun/turn服务器,于是我在阿里云centos7服务器上利用coturn在3478端口启动了该服务,但是在测试时发现服务不可用。 ![微信图片_20251115231728_177_1.png](https://pic.code-nav.cn/post_picture/1989882834701107201/KmWrvmgc8hUm3VTc.webp) ![image.png](https://pic.code-nav.cn/post_picture/1989882834701107201/YeJ3QoLPiAcnMR9G.webp) ### 尝试解决 ##### 一开始,我以为是端口未开放的问题,于是我在安全组设置了入方向和出方向的端口对全部流量进行全部开放,并且关闭了防火墙的限制,但是依然没有用。 ### 详细信息 启动命令 ```js /usr/local/turnserver/bin/turnserver -v -r 47.94.53.126 -a -o -c /usr/local/turnserver/share/examples/turnserver/etc/turnserver.conf ``` 具体配置 ```js listening-port=3478 listening-ip=172.18.61.183 tls-listening-port=5349 # TLS 加密端口 cert=/ssl/cert.pem pkey=/ssl/cert.key external-ip=47.94.53.126 user=user:654321 realm=47.94.53.126 lt-cred-mech relay-ip=0.0.0.0 # 至于为什么配置relay-ip=0.0.0.0 ?? # 因为我尝试填写了内网ip或外网IP,但都无效 min-port=49152 max-port=65535 verbose log-file=/var/log/turnserver.log ``` 部分日志 ```js 696: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 696: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 706: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 706: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 716: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 716: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 726: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 726: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 736: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 736: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet BINDING processed, success 743: session 001000000000000010: refreshed, realm=<47.94.53.126>, username=<user>, lifetime=0 743: session 001000000000000010: realm <47.94.53.126> user <user>: incoming packet REFRESH processed, success 743: session 001000000000000011: refreshed, realm=<47.94.53.126>, username=<user>, lifetime=0 743: session 001000000000000011: realm <47.94.53.126> user <user>: incoming packet REFRESH processed, success 744: session 001000000000000010: usage: realm=<47.94.53.126>, username=<user>, rp=22, rb=1160, sp=22, sb=1888 744: session 001000000000000010: closed (2nd stage), user <user> realm <47.94.53.126> origin <>, local 172.18.61.183:3478, remote 36.112.200.70:30675, reason: allocation timeout 744: session 001000000000000010: delete: realm=<47.94.53.126>, username=<user> 744: session 001000000000000010: peer 172.17.0.1 deleted 744: session 001000000000000010: peer 36.112.200.70 deleted 744: session 001000000000000010: peer 10.24.68.63 deleted 744: session 001000000000000010: peer 47.94.53.126 deleted 744: session 001000000000000011: usage: realm=<47.94.53.126>, username=<user>, rp=22, rb=1160, sp=22, sb=1888 744: session 001000000000000011: closed (2nd stage), user <user> realm <47.94.53.126> origin <>, local 172.18.61.183:3478, remote 36.112.200.70:30676, reason: allocation timeout 744: session 001000000000000011: delete: realm=<47.94.53.126>, username=<user> 744: session 001000000000000011: peer 172.17.0.1 deleted 744: session 001000000000000011: peer 36.112.200.70 deleted 744: session 001000000000000011: peer 10.24.68.63 deleted 744: session 001000000000000011: peer 47.94.53.126 deleted ``` 使用lsof命令查看端口信息 ```js [root@iZ2zeh5hzhg0kgjwdxkm9cZ ~]# lsof -i :3478 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME turnserve 27441 root 17u IPv4 25694475 0t0 TCP iZ2zeh5hzhg0kgjwdxkm9cZ:stun (LISTEN) turnserve 27441 root 20u IPv4 25693882 0t0 TCP iZ2zeh5hzhg0kgjwdxkm9cZ:stun (LISTEN) turnserve 27441 root 22u IPv4 25693885 0t0 UDP iZ2zeh5hzhg0kgjwdxkm9cZ:stun turnserve 27441 root 23u IPv4 25693886 0t0 UDP iZ2zeh5hzhg0kgjwdxkm9cZ:stun ```

微服务入门级学习

本文系统性介绍微服务知识,对微服务理论知识做了一次归纳总结。 下一篇文章会系统介绍消息队列进阶,看看MQ在分布式下的挑战。 ## 微服务概念 ### 什么是微服务? 微服务是一种软件架构风格,它将应用程⁢序构建为一组小型、独立的 服务,每个服务都围绕特定‏的业务功能构建,并通过明؜确定义的 API 进行通信。 为了更好地理解微服务架构的作⁢用,先给大家举个例 子,看看单体架构和‏微服务架构的对比。 单体架构: ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/qBUr7dqvkQnmTSGc.webp) 微服务架构: ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/2NV5UilfE2lSPiE5.webp) 从图中可以看出,单体架构将所有功能模块集⁢中在一个应用中,而微服务架 构将不同的业务功能拆分为独‏立的服务,每个服务都有自己؜的数据存储和业务逻辑。 ### 微服务有哪些作用? 1)**独立部署与运行**:既**去中心化治理,**每个微服⁢务都可以独立开发、 测试、部署和扩展,‏彼此之间互不影响,؜大大降低了系统的耦合度。 举个例子,当我们需要修改用户⁢管理功能时,只需要 重新部署用户服务,‏其他服务完全不受影؜响,可以正常运行。 2)**按业务功能划分服务**:微服务的拆分遵循业务边界,每个服务⁢专注于特定的业务领域,做到高内聚、低耦合。比如用户服务专门负责用户注册、‏登录、权限管理等功能,AI 服务则专؜注于代码生成、模型调用等核心能力。 3)**技术选型灵活**:不同的微服务可以根据自身特点选择最合适的技⁢术栈,**不再受限于统一的技术架构**。用户服务 可以用 MySQL 存储用户信息,应用服‏务可以用 Redis 缓存数据,截图服务؜可以用对象存储保存图片,各取所需。 4)**弹性扩展**:可以根据业务负载情况,针对性地**扩展高压力⁢服务**,实现**资源的精准利用**。比如 AI 代码生成请求量激增时,我们只需要**扩‏展 AI 服务的实例数量**,而不用扩展؜整个应用,既节省成本又提升效率。 5)**故障隔离**:通过合理的容错设计(熔断、⁢重试、超时等机制),即使某个服务出现故障,也不会影响‏其他服务的正常运行,大大提؜升了系统的整体可用性。 6)**数据分离**:这是微服务架构的一条铁律。每个服务都拥有自己**独立的数据库**。例如,“用户服务”有自己的用户数据库,“订单服务”有自己的订单数据库。这彻底避免了服务间因数据库耦合而无法独立部署的问题。 ### 微服务的挑战 注意,微服务架构不是银弹,不⁢是什么时候都适用的 ,它也会带来一些问‏题: 1)**分布式复杂性**:原本简单的本地方⁢法调用变成了跨网络的服 务调用,需要处理网络延‏迟、服务发现、数据一致؜性等分布式系统特有的问题。 2)**运维复杂度提升**:从管理一个应用变⁢成管理多个服务,监控、日 志收集、部署发布等运维工‏作的复杂度成倍增长,需要؜更完善的工具和流程支撑。 3)**服务治理挑战**:需要解决服务注册发⁢现、负载均衡、配置管理、 链路追踪等一系列问题,通‏常需要引入Nacos、网؜关等额外的基础设施组件。 4)**数据一致性难题**:在分布式环境下,⁢如何保证跨服务的数据一致 性是一个技术难点,往往需‏要采用最终一致性方案,增؜加了业务逻辑的复杂性。 而且很多问题的解决都要从单体考虑到分布式场景,比⁢如单机锁 => 分布式锁、单机限流 => 分布式限流、单机定时任‏务 => 分布式定时任务,会增加؜很多的开发成本和复杂任务。 ## 微服务核心理论 ### 服务拆分原则 微服务架构的核心在于将单体应用拆分为多个独立的服务,每个服务围绕特定的业务能力构建。以下是常用的服务拆分原则: #### 1. 领域驱动设计(DDD) DDD 是服务拆分的核心指导思想。通过识别业务领域中的子域,划分限界上下文(Bounded Context),可以有效地将复杂的业务逻辑拆分为多个服务。每个限界上下文代表一个独立的业务模块,内部拥有自己的模型和逻辑,外部通过明确的接口进行交互。 在实际应用中,DDD 强调以下概念: - **实体(Entity)**:具有唯一标识的对象,如用户、订单等。 - **值对象(Value Object)**:没有唯一标识的对象,通常用于描述某些属性,如地址、日期等。 - **聚合根(Aggregate Root)**:聚合内部唯一对外暴露的入口,确保聚合内部的一致性。 - **领域服务(Domain Service)**:封装领域逻辑的服务,通常用于处理复杂的业务规则。 通过 DDD,可以将业务逻辑与技术实现解耦,提高系统的可维护性和扩展性。 #### 2. 单一职责原则(SRP) 每个服务应仅承担一种业务职能,避免多重职责的混合。例如,订单服务应仅处理订单相关的逻辑,而不应涉及支付或库存管理等功能。 #### 3. 数据一致性 相关性强的数据保持在同一服务中,减少跨服务的数据依赖,也就是**高内聚、低耦合**。比如用户信息和用户权限放在同一个服务中,避免跨服务查询。 #### 4. 基于业务能力拆分 将系统按照业务能力进行拆分,如电商系统可以拆分为用户、商品、订单、支付等服务。每个服务负责特定的业务领域,避免跨领域的复杂依赖,**要符合业务的相互隔离才可拆分**,另外能否成功拆分,**还要看拆分后这个服务有没有依赖其它服务(有没有注入其它服务的Bean,new xx()对象, 这都是依赖了其它服务)**,来判断能不能拆,好不好拆,如果强依赖或大量依赖其它服务,你可能需要重新考虑微服务拆分方案。 除了业务上的划分,还可以将**严重耗费计算力的业务**独立出来,便于单独优化和扩展。比如AI代码生成和网页截图都是计算密集型任务,独立部署便于资源优化。 #### 5. 扩展性需求 根据不同模块的扩展需求进行拆分。访问频率高的模块可以独立扩展,不影响其他服务。 ### 服务通信机制 微服务之间的通信方式直接影响系统的性能和可靠性。常见的通信机制包括同步通信和异步通信。 #### 1. 同步通信 参考[Dubbo官方文档](https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/protocols/dubbo/) - **dubbo 协议**: Dubbo 自研的 高性能二进制 RPC 协议,用于在提供者和消费者之间进行远程方法调用。 - T**riple 协议**: Dubbo 3.x 推出的 下一代高性能 RPC 通信协议。它基于 HTTP/2,并且 完全兼容 gRPC——所以跨语言支持。序列化格式: Protobuf / JSON / Hessian 。 - **REST 协议:** 是基于 HTTP/1.1 的一种 Web 风格接口设计规范,使用 URL + HTTP 方法 表达动作(GET、POST、PUT、DELETE) ,跨语言支持。序列化格式: JSON / XML 。 - **gRPC** : 是由 Google 推出的 跨语言高性能 RPC 框架,基于 HTTP/2 + Protocol Buffers。 跨语言支持 。序列化格式: Protobuf 。 落地使用,在配置文件中修改 name 属性值 ```java dubbo: protocol: name: dubbo / tri / rest port: 8080 ``` #### 2. 异步通信 - **消息队列** 如 RabbitMQ、RocketMQ、Kafka 等消息中间件,可实现服务间的解耦、削峰填谷和最终一致性。适用于处理高并发、异步任务等场景。 ### 微服务九大核心组件 本小节参考文章:https://blog.csdn.net/cgk_ALEM/article/details/144664124 #### 1. 服务注册与发现 服务注册与发现是微服务架构的基础设施,主要解决服务如何找到彼此的问题。在微服务架构中,服务实例可能会频繁地启动和停止,因此需要一个服务注册与发现机制来动态地管理和发现服务实例。服务注册中心允许服务在启动时注册自己,并在停止时注销,而服务发现机制则允许其他服务动态地查找和调用这些服务。 工作原理:服务启动时向注册中心注册自己的信息;服务消费者从注册中心获取服务提供者的地址列表;注册中心监控服务实例的健康状态,剔除不健康的实例 落地技术:Nacos、Zookeeper 、Eureka和Consul等 ```java // 落地实现: 需要Dubbo stater 、 Nacos stater 依赖 // Main 主类需要打上 @EnableDubbo // 标记一个类为 Dubbo 服务提供者,由 Dubbo 自动进行注册与暴露。 @DubboService public class UserServiceImpl implements UserService { public User getUserById(Long id) { ... } } // 从注册中心调用上面提供的服务: // 在另一个服务上,启动类加上@Dubbo, // 跟原本注入 Bean 语法相似,@Resource注解换成 @DubboReference,搞定! ``` ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/WHKTLqEh61aAfaN1.jpg) #### 2. API网关 API网关是微服务架构的入口点,它负责处理所有进入系统的请求。作为微服务的前端,API网关提供了一个统一的接口,使得客户端不需要直接与后端的多个服务交互。它不仅简化了客户端的交互,还提供了路由、负载均衡、认证、监控和日志记录等功能。 API网关的核心功能包括: - **请求路由**:根据请求的URL、HTTP方法或其他属性,将请求路由到相应的服务 。 - **负载均衡**:将请求分发到多个服务实例,以提高系统的可用性和响应速度 。 - **安全认证**:集中管理安全策略,如OAuth、JWT等,确保只有经过认证的请求才能访问后端服务 。 - **监控日志**:收集和记录所有通过它的请求的日志,这对于监控系统性能和排查问题至关重要。 网关还可以分为接入层网关(流量网关)和应用层网关(业务网关)。 - 接入层网关:如 nginx , 关注网络流量的分发、路由和基础网络层面的功能,负载均衡、流量控制、反向代理都是接入层网关的职责。 - 应用层网关:如 Spring Cloud Gateway , 更贴近业务逻辑,是业务请求的“**业务处理中心**”包含了**特定业务规则和处理逻辑**,负责将流量网关转发来的请求智能地路由到正确的后端微服务,并在过程中执行必要的业务级处理,(如安全校验,日志等,相当于拦截器)。 ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/LNSrnK3pa5oPAJ31.webp) 落地技术:Spring Cloud Gateway , Higress(阿里巴巴的,基于envoy技术),Kong(跨语言通用) **Higress 翻到文末附录1了解更多。** #### 3. 配置中心 在微服务架构中,通常会有成百上千个服务实例,每个服务可能有多个配置文件(如开发、测试、生产环境)。如果采用传统的静态配置方式,修改一个配置可能需要重新部署整个服务,效率低下且风险高。配置中心能够实现配置的动态管理,在不重启服务的情况下更新配置,大大提高了系统的灵活性和可维护性。 核心功能: - **配置动态更新**:支持配置的实时推送,无需重启应用 。 - **版本管理**:提供配置的版本控制和回滚功能 。 - **灰度发布**:支持配置的灰度发布,先在部分应用实例中验证配置变更是否符合预期,然后再推送到所有应用实例 。 - **权限管理**:提供完善的权限管理机制,适合大型团队协作。 工作原理:服务启动时从配置中心拉取配置;配置中心推送配置变更通知到服务实例;服务实例接收到通知后重新加载配置 落地技术:Nacos 和 Spring Cloud Config ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/Ixgg4R5iC2wvOywo.webp) #### 4. 负载均衡 我们平时说负载均衡一般都是指**服务端负载均衡**,但因为分布式spring cloud分布式框架出现,也出现了**客户端负载均衡**这一概念。 - **服务端负载均衡**:依赖中心化组件(如Nginx)统一分发请求,适用于集中式流量管理,但可能成为单点瓶颈 ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/vtnekUa2vpvFn4hM.webp) - **客户端负载均衡**:我们在使用spring-cloud分布式框架时,同一个service大概率同时启动多个,当一个请求奔过来时,那么这多个service,Ribbon通过策略决定本次请求使用哪个service的方式就是客户端负载均衡。在spring-cloud分布式框架中客户端负载均衡对开发者是透明的,添加@LoadBalanced注解就可以了。 ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/ih0AqaWJeVy0NKXt.webp) 常见的负载均衡策略包括: - **轮询**:按顺序依次分配请求。 - **随机**:随机选择一个服务实例 。 - **加权轮询**:根据服务实例的权重分配请求,权重越高分配的请求越多。 - **最少连接**:选择当前连接数最少的服务实例。 #### 5. 熔断器 我们来看一个问题,在微服务架构中,服务间调用关系错综复杂,一个请求可能需要调用多个微服务接口才能实现。如果某个服务发生故障或响应延迟,可能导致请求阻塞,线程无法释放,最终导致整个系统资源耗尽,这称为“服务雪崩”。 熔断器通过监控服务调用失败率,在达到阈值时自动切断请求,进入熔断状态(类似电路保险丝),从而防止故障蔓延,保护系统稳定性。 熔断器的工作原理可以分为以下三种状态: 1. **关闭状态**:熔断器关闭,所有请求正常通过。在此状态下,会统计请求失败率,当失败率超过阈值时,熔断器跳转到打开状态 。 2. **打开状态**:熔断器打开,所有请求被快速拒绝,直接触发降级逻辑。熔断器保持打开状态一段时间(如10秒)后,自动进入半开状态 。 3. **半开状态**:允许少量探测请求通过,若成功则恢复服务,否则重新进入打开状态 。 落地技术:Resilience4j , Sentinel**。** #### 6. 服务链路追踪 在微服务架构中,一次用户请求往往需要经过多个服务协同处理,服务间的调用关系变得非常复杂。如果没有链路追踪,当某个服务出现问题时,排查问题需要逐一检查各个服务的日志,费时费力,效率低下。 服务链路追踪可以帮助我们: - **可视化调用链**:清晰地展示请求经过的每一个服务节点,以及服务间的调用关系和耗时 。 - **快速定位问题**:通过分析调用链的耗时分布,快速找到性能瓶颈和服务异常点 。 - **监控系统性能**:实时监控各个服务的响应时间、错误率等指标,及时发现潜在问题。 链路追踪的实现原理: - 埋点:在代码中插入探针,用于收集追踪数据 - 数据传递:在服务间传递Span Context - 数据收集:将收集到的追踪数据发送到链路追踪系统 - 数据存储:将追踪数据存储起来 - 数据展示和分析:提供可视化界面,展示调用链、耗时分布、错误信息等 落地技术:Zipkin、Jaeger和SkyWalking #### 7. 分布式事务 在微服务架构中,不同的服务之间无法做到使用同一个事务,这就无法保证数据的一致性 。例如,在一个电商系统中,订单服务需要调用库存服务扣减库存,如果订单服务成功而库存服务失败,就会导致数据不一致。 分布式事务用于在分布式系统中保证不同节点之间的数据一致性 。实现分布式事务的方案有很多,包括强一致性方案(如2PC、3PC)和最终一致性方案(如TCC、Saga、本地消息表等) 常用分布式事务的方案: **1) TCC模式** TCC(Try-Confirm-Cancel)采用补偿机制,其核心思想是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作 - **Try阶段**:尝试执行业务,完成所有业务检查(一致性),预留必要的业务资源(准隔离性) 。 - **Confirm阶段**:确认执行业务,不再做业务检查。只使用Try阶段预留的业务资源,Confirm操作满足幂等性 。 - **Cancel阶段**:若业务执行失败,则取消执行业务并释放Try阶段预留的业务资源 。 **适用场景**:对一致性要求高、业务逻辑较简单的场景 。 **2)Saga模式** Saga模式是把一个分布式事务拆分为多个本地事务,每个本地事务都有相应的执行模块和补偿模块,当Saga事务中任意一个本地事务出错时,可以通过调用相关的补偿方法恢复之前的事务,达到事务最终一致性 **适用场景**:业务流程长、需要保证最终一致性的场景 #### 8. 身份认证与授权 在微服务架构中,身份认证与授权是一个复杂的问题,因为服务数量多,调用关系复杂,需要统一管理用户身份和访问权限,主要挑战包括: - **单点登录**:用户只需要登录一次,就可以访问所有相互信任的应用系统 。 - **权限控制**:需要控制不同用户对不同服务的访问权限。 - **令牌管理**:需要安全地生成、验证和管理访问令牌 。 **主流方案:OAuth2 + JWT** OAuth2是一个授权框架,允许第三方应用程序获得对用户账户的有限访问权限。JWT(JSON Web Token)是一种开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于在各方之间安全地传输信息作为JSON对象. OAuth2 + JWT的组合是微服务架构中常用的认证授权方案,其工作流程如下: 1. 用户通过客户端向授权服务器发起认证请求 。 2. 授权服务器验证用户身份,生成访问令牌(JWT) 。 3. 客户端使用访问令牌访问资源服务器 。 4. 资源服务器验证访问令牌,返回相应的资源 #### 9. 日志聚合 在微服务架构中,日志分散在不同的服务器上,每个服务实例都会产生大量的日志文件。如果没有集中的日志管理系统,排查问题需要登录到每台服务器查看日志,效率低下。日志聚合系统可以将所有服务的日志收集起来,集中存储和管理,提供统一的查询和分析界面。 主流方案: ELK/EFK Stack和Lok ## 微服务开发框架 微服务开发框架是构建微服务应用的基础,它提供了服务注册⁢发现、配置管理、负载均衡、熔断降级等 微服务治理能力的统一抽象。没有框架的‏话,开发者需要自己处理这些复杂的分布؜式问题,开发效率会大大降低。 目前主流的 Java 微服务开发框架包括: - Spring Cloud:基于 Spring Boot 的微服务框架,生态完善,社区活跃 - Spring Cloud Alibaba:阿里基于 Spring Cloud 的扩展,集成了阿里云的微服务组件 - Dubbo:阿里开源的高性能 RPC 框架,专注于服务调用 注意:Spring Cloud Alibaba 并不是一个 Stater , 它本身只是一个**依赖管理平台 ,** 在项目中可以引用BOM`spring-cloud-alibaba-dependencies`, BOM 只负责锁定各个组件版本,具体组件按需引入。 | **功能** | **Maven 依赖** | **说明** | | --------------------------- | ---------------------------------------------- | ------------------------------ | | **Nacos 注册中心** | `spring-cloud-starter-alibaba-nacos-discovery` | 服务注册与发现, 相当于 Eureka | | **Nacos 配置中心** | `spring-cloud-starter-alibaba-nacos-config` | 动态配置管理 | | **Sentinel** | `spring-cloud-starter-alibaba-sentinel` | 流量控制与熔断 | | **RocketMQ** | `spring-cloud-starter-alibaba-rocketmq` | 消息队列 | | **Seata** | `spring-cloud-starter-alibaba-seata` | 分布式事务 | | **Dubbo** | `spring-cloud-starter-dubbo` | 高性能 RPC 通信 | | **SchedulerX、OSS、SMS 等** | 对应的 `spring-cloud-starter-alibaba-*` | 云服务扩展 | ### Spring Cloud概述 Spring Cloud 是由 Pivotal 团队(现为 VMware 的一部分)在 2014 年发起的微服务框架项目。它并非一个全新的框架,而是**基于 Spring Boot 的编程模型**,通过整合一系列成熟的第三方组件来提供微服务开发所需的常见模式解决方案。 Spring Cloud 的设计理念是**利用 Spring Boot 的开发便利性**,巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以通过 Spring Boot 的开发风格做到一键启动和部署 主要组件: | **组件名称** | **功能描述** | **开源公司/组织** | | ---------------------- | ---------------------------------------------- | ----------------- | | Spring Cloud Config | 集中式配置管理工具,支持外部存储(如Git) | Netflix | | Spring Cloud Netflix | 集成Netflix OSS套件(Eureka, Hystrix, Zuul等) | Netflix | | Spring Cloud Gateway | 基于Spring 5+的反应式API网关 | Spring社区 | | Spring Cloud Sleuth | 分布式链路追踪,集成Zipkin、HTrace等 | Spring社区 | | Spring Cloud OpenFeign | 声明式REST客户端,整合了Ribbon负载均衡 | Netflix | | Spring Cloud Bus | 事件、消息总线,用于在集群中传播状态变化 | Spring社区 | 说明: **OpenFeign** 比较重要,它的定位是**简化微服务之间的调用**,让 HTTP 调用变得像调用本地方法一样简单的工具。 简单来说,你只需要创建一个 Java 接口,然后在上面添加一些注解,OpenFeign 就能帮你自动生成实现这个接口的代理类。当你调用接口方法时,它会自动帮你构建和发送 HTTP 请求,并将响应结果反序列化成 Java 对象。 ### Spring Cloud Alibaba概述 Spring Cloud Alibaba 是阿里巴巴基于 Spring Cloud 规范实现的微服务解决方案,它**结合了阿里巴巴自身的微服务实践和开源中间件产品**。该项目于 2018 年开源,并在 2019 年 7 月正式从 Spring Cloud Incubator 毕业成为 Spring Cloud 的官方子项目,它是 **Spring 社区第一个也是唯一一个国产开源项目**。Spring Cloud Alibaba 的诞生旨在为 Java 开发者提供一套**一站式微服务解决方案**,方便通过 Spring Cloud 编程模型轻松使用阿里巴巴的分布式应用解决方案。 ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/3vtD0FNMTwWVucyo.webp) | **组件名称** | **功能描述** | **对应阿里巴巴产品** | | ----------------- | -------------------------------------------- | -------------------- | | Nacos | 动态服务发现、配置管理和服务管理平台 | Nacos | | Sentinel | 流量控制、熔断降级、系统负载保护 | Sentinel | | RocketMQ | 开源分布式消息系统,提供低延时消息发布与订阅 | RocketMQ | | Dubbo | 高性能Java RPC框架(集成) | Apache Dubbo | | Seata | 高性能微服务分布式事务解决方案 | Seata | | Alibaba Cloud OSS | 阿里云对象存储服务 | 阿里云OSS | | Alibaba Cloud SMS | 覆盖全球的短信服务 | 阿里云短信服务 | Spring Cloud 和 Spring Cloud Alibaba 通信协议对比: | 协议类型 | Spring Cloud 支持 | Spring Cloud Alibaba 支持 | | -------------- | ----------------- | ------------------------- | | **HTTP/HTTPS** | ✅ (主要) | ✅ (主要) | | **Dubbo 协议** | ❌ | ✅ (核心) | | **gRPC** | ⚠️ (需自行集成) | ✅ (深度集成) | | **REST** | ✅ (基于HTTP) | ✅ (基于HTTP) | | **消息队列** | ✅ (通过 Stream) | ✅ (通过 Stream) | | **WebSocket** | ✅ (网关支持) | ✅ (网关支持) | ### Dubbo概述 Apache Dubbo(最初称为 Dubbo)是**阿里巴巴于2008年**开始研发并在2011年开源的一款高性能 Java RPC 框架,后来捐给了 Apache 基金会, 成为 Apache 顶级项目。 Dubbo 支持的通信协议:Dubbo协议、HTTP协议、gRPC协议、REST协议 # 附录1 : 云原生概念与 Higress 网关 **Higress**:阿里巴巴开源的一款**云原生 AI 网关 ,基于 envoy 构建,**旨在为云原生应用和 AI 场景提供高性能、高集成、易扩展的流量治理服务。 **envoy**:是CNCF(云原生计算基金会)的项目,云原生时代网络通信的基础设施。在微服务中,eveoy的设计理念是**网络应该是透明的。当网络和应用程序出现问题时,应该很容易确定问题的根源** ,比如在每个微服务旁边都部署一个 Envoy 代理(Sidecar),所有进出该服务的流量都被强制经过这个 Sidecar。 ![image-20251104234034889](D:\resource\typoraPictrue\image-20251104234034889.png) 作用是无缝为服务提供**流量管理、安全和可观测性**,业务代码无需任何改动。 下面是 Higress 与 ⁢Spring Cl oud Gatew‏ay 网关的详细对比: | **对比项** | **Spring Cloud Gateway** | **Higress** | | ------------------------ | -------------------------- | --------------------- | | 性能 | 中等 (基于 Spring WebFlux) | 高 (基于 Envoy C++) | | 内存占用 | 较高 (JVM) | 较低 (C++) | | 配置方式**(落地语法)** | **代码 + 配置文件** | **控制台 + 配置文件** | | 插件生⁢态 | Spring 生态 | Envoy + 自定义插件 | | 可观测性 | 依赖 Spri‏ng **Actuator** | 内置丰富的监控指؜标 | | 云原生 | 支持 | 原生云原生设计 | | 学习成本 | 低 (熟悉 Spring) | 中等 | | AI 支持 | 需要自定义开⁢发 | ⭐**原生 AI 功能支持** | 假如你需要在网关中写一些业务逻辑,Higr⁢ess 可能就不适合了,而 Spring Cloud Gat‏eway 是可以在代码中引入并؜且自定义 Java 业务逻辑的。**各有适用场景,在技术选型要考虑到这些点。** **AI 网关的概念**:参考[Higress官方](https://higress.cn/docs/latest/overview/what-is-higress/#什么是-ai-网关),可以得知我们的后端应用可以集成多个大模型服务(deepseek,glm,Qwen等),后端应用对任意一个集成进来的AI大模型发出/响应请求,AI 网关会对其进行拦截,对本次请求赋予通用能力,比如内容审核,Token计算,日志等。 AI 网关还有插件功能,赋予了更多通用能力,[参考 Higress 插件文档——AI提示词](https://higress.cn/docs/latest/plugins/ai/api-provider/ai-prompt-decorator/?spm=36971b57.35684624.0.0.43a1476765MjoY),可以得知,在大模型请求前后,我们还能插入一些通用的提示词,类似于系统提示词概念。 ![img](https://pic.code-nav.cn/post_picture/1625164612255182850/CxLbjS5yB1vyKCBm.webp) 云原生 AI 网关的**云原生**是什么呢? **云原生**:关键在于 **“Native”(原生)** 这个词,它意味着应用从设计之初就**为云环境而生**,充分考虑云的弹性、分布式、自动化等特性。 **云原生应用**: 本质上是更适合在云上部署的应用。应用从设计之初就**为云而生**,充分利用云平台的弹性伸缩、分布式部署和自动化运维能力,从而实现快速迭代、高可用性和资源高效利用。云原生应用的特点是启动快、性能高、内存占用少、能够弹性伸缩。 把一个传统应用改造成云原生应用,需要做微服务拆分,让其具备弹性伸缩能力、分布式部署能力,需要引用CICD、无服务器技术,让其实现自动化运维能力。 **云原生应用程序开发**: 云原生开发 ≠ 在云上写代码, 而是**为云而生的开发方式**, 利用**云计算环境的弹性、可扩展性和自动化**特性的**现代软件开发方法**, CNCF(云原生计算基金会)提出了四个关键特征,它们决定了“云原生”与传统开发的本质区别 。四个关键特征: - **容器化**: 每个服务独立打包运行 ,落地技术是 Docker 。 - **微服务化**: 系统拆分为小型可独立部署服务 ,落地技术是Spring Cloud ,Dubbo - **动态编排**: 自动调度、扩容、恢复服务 ,落地技术是 Kubernetes - **声明式管理:** 用配置描述“期望状态” ,落地技术是 YAML 配置, GitOps 。 云原生开发是一整套现代开发方式,具体落地实践是: - **持续集成(CI)**:简单说就是 代码一改,提交代码后,自动跑测试,快速发现 bug ,落地技术 GitHub Actions 或大厂自研 - **持续交付(CD)** : 测试通过后,自动部署到测试环境或生产环境 , 落地技术 Argo CD 或大厂自研 - **DevOps 文化** : 开发 + 运维不再分家, 自动构建、部署、监控、告警 , 落地技术 Docker、Kubernetes 、 Prometheus - **无服务器(Serverless**) : “Serverless” 并不是真的没有服务器 ,**服务器的管理被云平台完全隐藏**,开发者只需要写业务逻辑代码,开发者可以发布一个函数,公开被大家调用,区别于传统理解的一定要开发一个应用服务被调用。 以上就是原生应用程序开发的概念。 无服务器使用场景示例: 比如你写了一个 Node.js 函数: ```java exports.handler = async (event) => { const name = event.query.name || "World"; return { message: `Hello, ${name}!` }; }; ``` 上传到 AWS Lambda 或阿里云函数计算。 然后配置触发器: - HTTP 请求触发; - 或者文件上传触发。 完成!你不用建服务器,不用开 Nginx,不用部署。每次有人访问,平台自动运行你的函数,按调用量计费。 # 本文参考 鱼总 https://www.codefather.cn/course/1948291549923344386/section/1960544845213282305

nacos配置获取不到

### Bug 描述 nacos配置获取不到 ### 错误信息 ``` 2025-11-04 10:41:48.159 WARN 19028 --- [ restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[test] & group[DEFAULT_GROUP] 2025-11-04 10:41:48.162 WARN 19028 --- [ restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[test.yaml] & group[DEFAULT_GROUP] 2025-11-04 10:41:48.164 WARN 19028 --- [ restartedMain] c.a.c.n.c.NacosPropertySourceBuilder : Ignore the empty nacos configuration and get it based on dataId[test-dev.yaml] & group[DEFAULT_GROUP] 2025-11-04 10:41:48.165 INFO 19028 --- [ restartedMain] b.c.PropertySourceBootstrapConfiguration : Located property source: [BootstrapPropertySource {name='bootstrapProperties-test-dev.yaml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-test.yaml,DEFAULT_GROUP'}, BootstrapPropertySource {name='bootstrapProperties-test,DEFAULT_GROUP'}] 2025-11-04 10:41:48.168 INFO 19028 --- [ restartedMain] c.v.usercenter.UserCenterApplication : The following 1 profile is active: "dev" 2025-11-04 10:41:48.184 WARN 19028 --- [ restartedMain] c.a.c.n.c.NacosConfigDataLoader : [Nacos Config] config[dataId=test, group=DEFAULT_GROUP] is empty ``` pom配置如下: ``` <dependencies> <!-- Nacos 配置中心依赖 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bootstrap</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <!-- Spring Cloud 版本管理(关键新增) --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.4</version> <!-- 与 Spring Boot 2.6.x 兼容的版本 --> <type>pom</type> <scope>import</scope> </dependency> <!-- Spring Cloud Alibaba 版本管理 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.4.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> ``` bootstrap配置如下: ``` spring: application: name: usercenter # 服务名(对应 Nacos 配置的 Data ID 前缀) profiles: active: dev cloud: nacos: config: server-addr: 127.0.0.1:8848 # Nacos 服务器地址(多个用逗号分隔) file-extension: yaml # 配置文件格式(yaml 或 properties) # 可选配置 namespace: public # 命名空间(隔离环境,默认 public) group: DEFAULT_GROUP # 配置分组(默认 DEFAULT_GROUP) # 配置刷新策略(默认开启自动刷新) refresh-enabled: true username: nacos password: nacos config: import: - nacos:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}?group=${spring.cloud.nacos.config.group} ``` 自己在nacos上的public命名空间下创建了dataid为usercenter-dev.yaml的文件,配置如下 ``` spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/user_center?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai username: root password: xxxx ``` 当前环境为java8,springboot2.7,nacos2.2.0

Dubbo与HTTP端口混用导致转发异常,如何排查处理

我user中心暴露了dubbo端口和http端口,我网关转发的时候一次转发到了dubbo端口一次就到http端口,怎么解决这种问题。转发到dubbo端口的时候报错日志如下2025-10-24T10:28:53.970+08:00 DEBUG 23076 --- [api-gateway] [ioEventLoop-7-2] c.apimanage.gateway.filter.AuthFilter : [AuthFilter] Token validated for user: 'admin' 2025-10-24T10:28:53.970+08:00 INFO 23076 --- [api-gateway] [ioEventLoop-7-2] c.apimanage.gateway.filter.AuthFilter : [AuthFilter] 认证成功,转发请求到下游服务 2025-10-24T10:28:53.971+08:00 DEBUG 23076 --- [api-gateway] [ioEventLoop-7-2] c.a.gateway.config.RateLimiterConfig : Path based rate limit for: /user/list 2025-10-24T10:28:53.976+08:00 DEBUG 23076 --- [api-gateway] [ioEventLoop-7-2] o.s.c.g.f.ratelimit.RedisRateLimiter : response: Response{allowed=true, headers={X-RateLimit-Remaining=19, X-RateLimit-Requested-Tokens=1, X-RateLimit-Burst-Capacity=20, X-RateLimit-Replenish-Rate=10}, tokensRemaining=-1} 2025-10-24T10:28:53.993+08:00 WARN 23076 --- [api-gateway] [ctor-http-nio-9] r.netty.http.client.HttpClientConnect : [60891de0-1, L:/192.168.70.35:58972 - R:/192.168.70.35:20884] The connection observed an error java.lang.IllegalArgumentException: invalid version format: UNSUPPORTED at io.netty.handler.codec.http.HttpVersion.<init>(HttpVersion.java:123) ~[netty-codec-http-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.http.HttpVersion.valueOf(HttpVersion.java:85) ~[netty-codec-http-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.http.HttpResponseDecoder.createMessage(HttpResponseDecoder.java:155) ~[netty-codec-http-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.http.HttpObjectDecoder.decode(HttpObjectDecoder.java:277) ~[netty-codec-http-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.http.HttpClientCodec$Decoder.decode(HttpClientCodec.java:238) ~[netty-codec-http-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:529) ~[netty-codec-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:468) ~[netty-codec-4.1.101.Final.jar:4.1.101.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:290) ~[netty-codec-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.101.Final.jar:4.1.101.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.101.Final.jar:4.1.101.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.101.Final.jar:4.1.101.Final] at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.101.Final.jar:4.1.101.Final] at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na] 2025-10-24T10:28:54.000+08:00 WARN 23076 --- [api-gateway] [ task-2] c.a.g.controller.FallbackController : 服务降级处理 - 用户中心服务不可用 ![54e002bc-d206-4ce1-9f8a-a62bb0af296b.png](https://pic.code-nav.cn/post_picture/1958719057440403457/VXBr1sJqVaGX3npR.webp) ![4977f61b-8a45-4a14-b21f-aac2f2403a55.png](https://pic.code-nav.cn/post_picture/1958719057440403457/HUyooD1EnSJGvxsb.webp)

网关路由使用lb://无法调用微服务,改http正常

我有个网关路由相关的问题,路由配置使用 lb://auth-center 这种就调不过去,改为 http://localhost:8081就正常。其他微服务也是这种情况。使用的是gateway网关,路由配置如下: /** * 配置路由规则 * 集成限流配置到不同的API路由 */ @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { logger.info("Configuring custom route locator with rate limiting"); RouteLocator routeLocator = builder.routes() // 认证中心路由 - 使用严格限流 .route("auth-center", r -> r .path("/api/auth-center/**") .filters(f -> f .stripPrefix(2) .requestRateLimiter(c -> c .setRateLimiter(strictRateLimiter) .setKeyResolver(ipKeyResolver) .setDenyEmptyKey(false) ) .circuitBreaker(c -> c.setName("authCenterCircuitBreaker").setFallbackUri("forward:/auth-fallback")) ) // .uri("lb://auth-center") .uri("http://localhost:8081") ) // 用户服务路由 - 使用默认限流 .route("user-center", r -> r .path("/api/user-center/**") .filters(f -> f .stripPrefix(2) .requestRateLimiter(c -> c .setRateLimiter(defaultRateLimiter) .setKeyResolver(userKeyResolver) ) .circuitBreaker(c -> c.setName("userServiceCircuitBreaker").setFallbackUri("forward:/user-fallback")) ) .uri("lb://user-center") ) // API中心路由 - 使用宽松限流 .route("api-center", r -> r .path("/api/api-center/**") .filters(f -> f .stripPrefix(2) .requestRateLimiter(c -> c .setRateLimiter(lenientRateLimiter) .setKeyResolver(ipKeyResolver) ) .circuitBreaker(c -> c.setName("apiCenterCircuitBreaker").setFallbackUri("forward:/api-fallback")) ) .uri("lb://api-center") ) .build(); logger.info("Custom route locator configured successfully"); return routeLocator; }

网关如何正确转发Dubbo与HTTP协议服务?

老师你好,请教个架构设计方面的问题呗。一个微服务同时暴露dubbo端口和http端口这样的设计合理吗,那网关转发的时候怎么设计呢,我路由配置使用.uri("lb://user-center")这样写默认路由他是两类端口轮询调用的,这好像有问题,一次是正常,一次是报协议不对。实际企业中他们使用dubbo时网关一般是咋做呢,我是没设计过网关和认证中心没啥经验,麻烦老师给指点方向。我目前的架构是使用spring-boot3.2.0+Spring Cloud Alibaba+Dubbo3.3.0+gateway网关+Spring Security+nacos+knife4j

黑马面试专题-微服务

### 框架 ![image-20250722193603204.png](https://pic.code-nav.cn/post_picture/1912443888513626113/hwlF8f574m8TvmXQ.webp) #### SpringCloud 5大组件有哪些 通常情况下: - 注册中心 Nacos - 负载均衡 Ribbon - 服务调用 Feign - 服务保护/服务熔断 sentinel - 服务网关 GateWay #### 服务注册和发现是什么意思?SpringCloud 如何实现服务注册? Eureka的作用 ![image-20250722194728182.png](https://pic.code-nav.cn/post_picture/1912443888513626113/eytNEpcl889yY4Rz.webp) **回答:** 我们当时项目使用Eureka作为注册中心,这也是spring cloud体系中一个核心组件 **服务注册:**服务提供者需要把自己的信息注册到eureka,有eureka来保存信息,比如服务名称、ip、端口号 **服务发现:**服务的消费者向eureka拉去服务列表信息,如果服务提供者有集群,消费者会利用负载均衡的算法,选择一个发起调用 **服务监控:**服务提供者每隔30s向eureka发送心跳,报告健康状态,如果eureka服务90s没有接受心跳,从eureka服务中删除 #### 我看你之前也用过nacos,你能说一下nacos和eureka的区别吗 nacos ![image-20250722195654522.png](https://pic.code-nav.cn/post_picture/1912443888513626113/au9f0OkVEA5gYTs5.webp) **回答:** - Nacos和eureka共同点: - 都支持注册服务和服务拉去 - 都支持服务提供者发送心跳检测 - Nacos和eureka的区别 - Nacos支持服务端主动检测提供者状态:临时实例采用心跳检测,非临时实例采用主动检测模式 - 临时实例心跳不正常会被移除,非临时实例则不会移除 - Nacos支持的服务列表变更的消息推送模式,服务列表更新更及时 - Nacos集群默认采用的AP模式(高可用),当集群中存在非临时实例采用CP模式(强一致性);Eureka采用AP模式 - Nacos还支持配置中心,eureka只有注册中心 #### 你们项目中负载均衡如何实现? Ribbon负载均衡的流程 ![image-20250722201217189.png](https://pic.code-nav.cn/post_picture/1912443888513626113/vUFpvPe9dwYWaeM9.webp) #### **Ribbon负载均衡的策略?** - **RoundRobinRule:简单轮询服务列表来选择服务器** - **WeightedResponseTimeRule:按照权重来选择服务器,响应时间越长,权重越小** - **RandomRule:随机选择一个可用的服务器** - BestAvailableRule:忽略那些短路的服务器,并选择并发数较低的服务器 - RetryRule:重试机制的选择逻辑 - AvailabilityFiltering Rule:可用性敏感策略,先过滤非健康的,再选择连接数较小的实例 - **ZoneAvoidanceRule:以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这** **个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询**(默认) #### 如果想自定义负载均衡策略如何实现? 两种方式: 1. 创建类实现IRule接口,可以指定负载均衡策略(全局) 2. 在客户端的配置文件中,可以配置一个服务调用的负载均衡策略(局部) #### 什么是服务雪崩,这么解决这个问题? ![image-20250722203027039.png](https://pic.code-nav.cn/post_picture/1912443888513626113/S3tzixFg8hRQrizw.webp) **回答:** - 服务雪崩:一个服务失败,导致整条链路的服务都失败的情形 - 服务降级:服务自我保护的一种方式,或者保护下有服务的一种方式,用于确保服务不会受请求突增一ing想变得不可用,确保服务不会崩溃,一般在实际开发与feign接口整合,编写降级逻辑 - 服务熔断:默认关闭。需手动打开,如果监测到10s内请i去失败率炒超过50%,就出发熔断机制。之后没过5s,重新发送请求微服务,如果微服务不能响应,继续熔断。如果微服务有响应,则关闭熔断,恢复正常 #### 你们的微服务是怎么监控 ![image-20250723111007687.png](https://pic.code-nav.cn/post_picture/1912443888513626113/eVfqgnKu9nEQ33H1.webp) 我们项目中采用的skywalking进行监控的 1. **skywalking**主要可以监控接口、服务、物理实例的一些状态。特别是在压测的时候可以看到众多服务中哪些服 务和接口比较慢,我们可以针对性的分析和优化。 2. 我们还在**skywalking**设置了告警规侧,特别是在项目上线以后,如果报错,我们分别设置了可以给相关负责人 发短信和发邮件,第一时间知道项目的bug情况,第一时间修复 #### 你们项目中有没有做过限流?怎么做的? 为什么要限流? 1. 并发的确大(突发流量) 2. 防止用户恶意刷接口 限流的实现方式: - Tomcat:可以设置最大连接数 - Nginx:漏桶算法 - 网关:令牌桶算法 - 自定义拦截器 **Nginx:** 原理:就是想象有一个固定大小的桶,这个桶有一个小孔可以漏水。当数据(如网络请求或数据包)到达时,它们会被放入这个桶中。桶按照固定的速率漏水(即处理数据),而不管数据是以什么速率流入的。 ![image-20250723115005219.png](https://pic.code-nav.cn/post_picture/1912443888513626113/Oa2IvnUSyDMsByDN.webp) ![image-20250723114942261.png](https://pic.code-nav.cn/post_picture/1912443888513626113/ObdM4iVSC8hmgavQ.webp) **网关限流: ** **令牌桶算法:**固定生成令牌存入令牌桶,桶满后暂停生成,请求需要到令牌桶申请令牌,没有申请到令牌会被阻塞或者丢弃,申请到令牌的请求才会被服务处理 ![image-20250723120121228.png](https://pic.code-nav.cn/post_picture/1912443888513626113/sBOPVLe6twscAU87.webp) - key-resolver:定义限流对象(ip、路径、参数),需代码实现,使用spel表达式获取 - replenishRate:令牌桶每秒填充平均速率。 - urstCapacity:令牌桶总容量。 **回答:** - 先介绍业务,什么情况下去做限流,需要说明QSP具体多少 - 我们当时有一个活动,到了假期就会抢购优惠,QPS最高可以达到2000,平时10-50之间,为了应对突发流量,需要做限流 - 常规限流,为了恶意攻击,保护系统正常运行,我们当时系统能够承载最大的QPS是多少 - nginx限流 - 控制速率(突发流量),使用的漏桶算法来实现过滤,让请求以固定的速率处理请求,可以应对突发流量 - 控制并发数,限制单个ip的连接数和并发连接的总数 - 网管限流 - 在spring cloud gateway中支持局部过滤器RequestRateLimiter来做限流,使用令牌桶算法 - 可以根据id或者路径进行限流,可以设置之每秒填充平均速率,金额令牌总容量 #### 解释一下CAP和BASE **Consistency(一致性)** 用户访问分布式系统中的任意节点,得到的数据必须一致 ![image-20250723131415356.png](https://pic.code-nav.cn/post_picture/1912443888513626113/TMy6HJuPKUsHmdf2.webp) **Availability(可用性)** 用户访问集群中任意健康节点,必须得到响应,而不是超市或拒绝 ![image-20250723131525900](C:\Users\许颢达\AppData\Roaming\Typora\typora-user-images\image-20250723131525900.png) **Partition tolerance(分区容错)** Partition(分区):与因为网络故障或者其他故障导致分布式系统中的部分节点与其他节点断开连接,形成独立的分区 Tolerance(容错):在集群出现分区时候,整个系统也要持续对外提供服务 ![image-20250723132106160.png](https://pic.code-nav.cn/post_picture/1912443888513626113/i77KkhR0Fa8mZmAL.webp) 解决:如果需要数据的强一致性,等待网络连接成功,数据同步完成之后在访问 结论: - 分布式系统节点之间需要网络连接,分区(P)是必然存在的 - 如果要保证访问的高可用性(A),可以持续对外提供服务,但不能保证数据的强一致性-->AP - 如果要保证访问的数据强一致性(C),就要放弃高可用性-->CP **BASE理论** BASE理论是对CAP的一种解决思路,包含三个思想: - Basically Available(基本可用):分布式系统在出现故障时,允许损失部分可用性,即保证核心可用。 - Soft State(软状态):在一定时间内,允许出现中间状态,比如临时的不一致状态。 - Eventually Consistent(最终一致性):虽然无法保证强一致性,但是在软状态结束后,最终达到数据一致。 ![image-20250723131525900.png](https://pic.code-nav.cn/post_picture/1912443888513626113/kXlWctZwfDdnsIuF.webp) **回答:** - CAP定理(一致性、可用性、分区容错性) - 分布式系统节点通过网络连接,一定会出现分区问题(P) - 当分区出现时,系统的一致性(C)和可用性(A)就无法同时满足 - BASE理论 - 基本可用 - 软状态 - 最终一致 - 解决分布式事务的思想和模型: - 最终一致思想:各分支事务分别执行并提交,如果有不一致的情况,再想办法恢复数据(AP) - 强一致思想:各分支事务执行完业务不要提交,等待彼此结果。而后统一提交或回滚(CP) #### 你们项目采用哪种分布式事务解决方案? 简历上写的微服务,只要发生了多个服务之间的写数据,都需要进行分布式事务控制 描述项目中采用的哪种方式(seata|MQ) 1. seata的XA模式,CP,需要互相等待各个分之十五提交,可以保证强一致性,性能较差 **银行业务** 2. seata的AT模式。AP。底层使用undo log实现,性能好 **互联网业务** 3. seata的TCC模式,AP,性能较好,不过需要人工编码实现 **银行业务** 4. MQ模式实现分布式事务,在A服务写数据的时候,需要在同一个事务内发送消息到另一个事务,异步,性能最好 **互联网业务** #### 分布式服务的接口幂等性如何设计? 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复条用的结果和单词条用的结果一直 需要幂等场景 - 用户重复点击(网络波动) - MQ消息重复 - 应用使用失败或者超时重复机制 基于RESTful API的角度对部分常见类型请求的幂等性特点进行分析 ![image-20250723142637812.png](https://pic.code-nav.cn/post_picture/1912443888513626113/ciwnlW3uMMsXMl5M.webp) 解决: - 加唯一索引 - token+redis ![image-20250723143142117.png](https://pic.code-nav.cn/post_picture/1912443888513626113/BVcKgMa3z1z4ZZKR.webp) **第一次请求(获取token)** 1. **客户端发起第一次请求**:用户在客户端(如手机APP或网页)进行创建商品、提交订单、转账、支付等操作时,首先向服务端发送一个请求。 2. **服务端生成唯一token**:服务端接收到请求后,生成一个唯一的token,并将这个token存储到Redis中。这个token的作用是作为后续请求的凭证,用于验证请求的合法性。 3. **返回token给客户端**:服务端将生成的token返回给客户端,客户端需要保存这个token以便在后续的操作中使用。 **第二次请求(带token请求业务接口)** 1. **客户端带token请求业务接口**:当用户再次进行相关操作(如提交订单)时,客户端会带上之前获取的token一起发送请求到服务端。 2. **服务端验证token是否存在**:服务端接收到带有token的请求后,会先检查Redis中是否存在这个token。如果存在,则表示这是一个合法的请求;如果不存在,则认为这是一个非法或重复的请求。 3. **处理业务并删除token**:如果token存在,服务端会继续处理用户的业务请求(如创建订单),并在处理完成后从Redis中删除这个token,以防止同一个token被多次使用。如果token不存在,服务端则直接返回错误信息,拒绝处理该请求。 4. **返回请求结果**:无论请求是否成功,服务端都会将处理结果返回给客户端,客户端根据返回的结果进行相应的展示或提示。 通过这种方式,可以有效地防止用户因网络延迟、误操作等原因导致的重复提交问题,保证了业务操作的准确性和系统的稳定性。 - 分布式锁 ![image-20250723143455048.png](https://pic.code-nav.cn/post_picture/1912443888513626113/I1MHWinnxIYxUhgU.webp) **回答:** - 幂等:多次调用方法或者接口不会改变业务状态,可以保证重复调用的结果和单次调用的结果一致 - 如果是新增数据,可以使用数据库的唯一索引 - 如果是新增或修改数据 - 分布式锁,性能较低 - 使用token+redis:来实现,性能较好 - 第一次请求,生成一个唯一token:存入redis,返回给前端 - 第二次请求,业务处理,携带之前的token,到redis进行验证,如果存在,可以执行业务,删除token;如果不存在,则直接返回,不处理业务 #### 你们项目中使用了什么分布式任务调度 **xxl-job解决问题** - 解决集群任务的重复执行问题 - cron表达式定义灵活 - 定时任务失败了,充实和统计 - 任务量大,分片执行 **路由策略有哪些** xjob提供了很多的路由策略,我们平时用的较多就是:轮询、故障转移、分片广播… **xxl-job任务执行失败怎么解决?** - 路由策略选择敌障转移,使用健康的实例来执行任务 - 设置重试次数 - 查看日志+邮件告警来通知相关负责人解决 **如果有大数据量的任务同事都需要执行,这么解决?** - 让多个实例一块去执行(部署集群),路由策略分片广播 - 在任务执行的代码中可以获取分片总数和当前分片,按照取模的方式分摊到各个实例执行

下载 APP