🤖Spring AI MCP Server 开发指南
“如果说 MCP 是 AI 世界的 USB 接口,那 Spring AI 就是帮你焊好接口、包好外壳、还贴心地附赠了说明书的那个工具人。” 目录 写在前面:MCP 是个啥? Spring AI 版本演进史 从零搭建一个 MCP Server 核心注解详解 配置参数大全 传输协议的前世今生 进阶玩法 常见踩坑实录 写在前面:MCP 是个啥?MCP (Model Context Protocol) 是 Anthropic 提出的一套开放协议,让 AI 模型能够像调用 API 一样调用外部工具。你可以把它理解为: 12传统 Web 开发:浏览器 <--HTTP--> 服务器MCP 世界: AI 模型 <--MCP--> 你的工具服务 以前你想让 AI 查个天气、算个数,得靠 prompt 里硬塞一堆上下文。现在有了 MCP,AI 可以主动说:”嘿,我需要查一下北京的天气”,然后你的 MCP Server 就屁颠屁颠地把结果递过去了。 一句话总结:MCP 让 AI 从”只会动嘴”进化成了”能动手”。 Spring AI 版本演进史Spring...
🚀 Java 启动神咒:如何让程序“永生”且“听话”
🚀 Java 启动神咒:如何让程序“永生”且“听话”在 Linux 运维界,如果你只会写 java -jar,那你只是个“临时工”。真正的“高级特工”都用下面这串咒语: nohup java -jar mybatis-plus.jar > all.log 2>&1 & 1. nohup:长生不老药 💊 大白话:“别管我,我不下班!” 内幕:默认情况下,你关掉 SSH 窗口,系统会给程序发个“下班信号”把它掐死。加了 nohup(No Hang Up),程序就练成了金钟罩,你就算把电脑砸了,它在服务器里也照样跑。 2. > all.log:正能量账本 📝 大白话:“好听的话记这里。” 内幕:把程序跑出来的 INFO、DEBUG 等正常日志全塞进 all.log 桶里,别在大黑屏幕上乱喷。 3. 2>&1:坏消息合并器 🖇️ 大白话:“脏水也往同一个桶里倒。” 内幕: 1 是正常日志,2 是报错信息(比如数据库连不上)。 2>&1 意思是:把报错(2)强行插进正常日志(1)的队伍里。 一针见血:如果不写这个,一...
📘 Java 核心门槛题册(15题)
📘 Java 核心门槛题册(15题) 🧠 第一部分:Java 值传递专项(10题) 1️⃣ 基本类型传递123456789public static void main(String[] args) { int a = 10; change(a); System.out.println(a);}static void change(int a) { a = 20;} 输出? A. 10B. 20C. 编译错误D. 运行异常 2️⃣ 包装类型传递123456789public static void main(String[] args) { Integer a = 10; change(a); System.out.println(a);}static void change(Integer a) { a = 20;} 输出? A. 10B. 20C. nullD. 编译错误 3️⃣ 修改对象属性12345678910111213class...
🐰 RabbitMQ 逃生指南:如何让消息“死心塌地”?
🐰 RabbitMQ 逃生指南:如何让消息“死心塌地”?各位被“消息丢失”虐过的码农同胞们,大家好!👋 在分布式系统的江湖里,丢消息就像丢外卖一样让人崩溃。今天我们就用最不正经的方式,聊聊最正经的 RabbitMQ 消息可靠性。 1. 生产者:老板,你收到了吗? (Publisher Confirm) 📣你辛辛苦苦写了一封“情书”(消息),直接扔进邮筒就跑?万一邮筒是假的呢?万一邮递员半路去吃火锅了呢? 常规操作:发完就当没事发生。❌ (渣男行为) 可靠操作:开启 Confirm 模式。✅ 消息发出去后,RabbitMQ 会给你回个信儿(ACK)。 如果它没收到,会给你发个“拒收信”(NACK)。 金句:一定要听到 RabbitMQ 的回响,才算你发得响亮!👂 2. 交换机:没地方放请告诉我! (Return Mechanism) 🚩有时候你的情书写得太潦草(路由键写错),RabbitMQ 拿着信转了一圈,发现根本没有对应的垃圾桶(队列)可以投递。 常规操作:RabbitMQ 悄悄把信撕掉,装作无事发生。🤫 可靠操作:设置 Man...
😎 Kafka 消息不丢失:一次把话说清楚
一句话结论先给你:Kafka 想做到“消息不丢”,不是靠玄学,而是靠 生产者、Broker、消费者三方配合。 一、Kafka 为啥会丢消息?先泼一盆冷水:Kafka 本身不保证消息 100% 不丢。 丢不丢,取决于你怎么用它 👇 你要是 acks=0,那就是“发出去就当成功”,消息随缘 你要是自动提交 Offset,那就是“吃没吃不重要,先结账” 你要是 ISR 副本只剩 Leader,那就是单点写入,翻车只差一次宕机 Kafka 给你的是工具箱,不是保险箱。 二、Kafka 的可靠性三板斧 🪓1️⃣ 生产者:别太心急(acks=all)1acks = all 含义很朴素: Leader 不点头不算数,ISR 里的人没签完字不返回成功。 acks=0:发完就跑 🚀(最快,也最容易后悔) acks=1:Leader 说行就行 ⚠️(Leader 一挂就凉) acks=all:ISR 集体通过 ✅(最稳) 👉 结论:要可靠,别犹豫,直接 acks=all。 2️⃣ Broker:设一道“安全底线”(min.insync.replicas ≥ 2)1mi...
🌏Referer 与 Origin 是什么?(接口防盗链速查版)
在做接口防盗链或来源校验时,最常用的两个请求头就是 Referer 和 Origin。它们都用来告诉服务器: 👉 这个请求,是从哪来的 但两者作用相似、语义不同、可靠性也不同。 一、Referer 是什么?Referer 表示: 当前请求是从哪个页面跳转/发起的 它通常是一个 完整 URL。 示例1Referer: https://www.example.com/page/detail?id=123 特点 包含:协议 + 域名 + 路径(甚至参数) 主要由 浏览器自动添加 历史最悠久,兼容性最好 常见使用场景 图片 / 视频 / 静态资源防盗链 简单页面级来源校验 局限性 ❌ 可能被浏览器/插件裁剪或直接不发送 ❌ HTTPS → HTTP 时可能丢失 ❌ 很容易被脚本伪造 二、Origin 是什么?Origin 表示: 发起当前请求的“站点源” 它只包含 协议 + 域名 + 端口,不包含路径。 示例1Origin: https://www.example.com 特点 不包含路径,更“干净” 主要用于 AJAX...
🍃Spring Boot 多模块项目中 Parent / BOM / Starter 的正确分工
🎯 结论先行(只记这三条)✅ Parent:继承规则(构建规范、插件、依赖管理)✅ BOM(dependencyManagement):只管版本,不引包✅ Starter(dependency):真正引入功能 🧱 1️⃣ Parent 是干什么的?📌 Parent ≠ 引入依赖 Parent 的职责只有这些: 🧩 统一依赖版本策略(通过 dependencyManagement) 🔧 统一插件配置(compiler / surefire / boot plugin) 📐 统一构建规范(Java 版本、编码、profile) 👉 Parent 是“规则继承”,不是“功能引入”。 📘 2️⃣ dependencyManagement 是不是“引入依赖”?❌ 不是 123456789<dependencyManagement> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp...
🤯 ThreadLocal 的 Entry 为何要继承 WeakReference?
一段看着别扭、却极其正确的 JDK 设计 一个所有人都会停顿的瞬间第一次读到 ThreadLocal 的源码,很多人都会在这里愣住几秒钟: 12345678static class Entry extends WeakReference<ThreadLocal<?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; }} 心里会不自觉冒出一句: “为啥不老老实实包一层?非要继承?” 🤨 代码不丑,但不顺眼。 于是问题来了: 👉 这是历史包袱?👉 这是早期 Java 的怪癖?👉 还是一次“反直觉但极其理性”的设计选择? 先把「另一种写法」摆上桌面假设我们不用继承,而是用组合: 123456789static class Entry { final WeakReference<ThreadLocal<?>&g...
一条河流过系统:从 CPU 到 Java 的并发叙事图 🌊🧠
一条河流过系统:从 CPU 到 Java 的并发叙事图 🌊🧠这不是分章节的说明书。 这是一条河。 从 CPU 发源,流经 操作系统,穿过 线程与锁,最后抵达你敲下的那一行 Java 代码。 中途不停,也不回头。 CPU 上电的那一刻,就写好了宪法 ⚖️ 有些指令,只有皇帝能用。 于是世界被分成了几层: Ring 0 👑:内核态 能碰硬件 能关中断 能调度众生 Ring 3 🧑💻:用户态 写代码 算业务 做梦想 这不是制度选择,这是硅片上的物理规则。 程序不服气:“我也想读磁盘。” 💾 CPU 冷冷一句: 你没资格。 操作系统站出来,像个公证人: “写个系统调用吧,我替你跑这一趟。” 于是: 用户线程 ✍️ 系统调用 🚪 CPU 切 Ring 0 🔁 内核执行 🧠 结果原路奉还 🎁 这条路径,是 Ring 切换的正门。 接着,真正跑在 CPU 上的生命体登场了 🧬 CPU 不认识进程,只调度线程。 用户线程: 写在 Java / C / Go 里 平时待在 Ring 3 内核线程: 属于...
🐷DDNS告别“丑陋端口号”:Cloudflare、腾讯云、阿里云ESA大比拼
核心痛点:丑陋的“猪尾巴” 😖家里宽带虽好,配置了 DDNS 也能随时访问,但众所周知,运营商封了 80/443 端口。 想从外网回家?只能忍受 http://yiqiquhuxi.cn:88 这种带着端口号的丑陋网址。不仅难记,看起来还特别 Low,毫无“优雅”可言。 🐷💻 我的目标很简单:不管是家里 NAS 还是小主机,我要通过 https://yiqiquhuxi.cn 直接访问,把背后真实的 88 端口藏得干干净净! 为了实现这个“端口隐身术”,我折腾了三种方案,给大家排排雷。👇 方案一:Cloudflare (赛博菩萨) 😇关键词:免费、Origin Rules、国际大厂 这是我最开始发现的方案。CF 不愧是赛博菩萨,直接利用它的 Origin Rules 功能就能实现端口非标转标准。 操作步骤: DDNS:让域名随时找到家里的公网 IP。 开启小黄云:Cloudflare 开启代理模式。 配置 Origin Rules:告诉 CF,“收到 yiqiquhuxi.cn 的访问请求,请帮我悄悄改写成 88 端口 再发回我家”。 优点:完全免费,...









