news 2026/9/24 21:43:04

前后端分离架构详解:从接口设计到部署落地的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前后端分离架构详解:从接口设计到部署落地的完整实践

前后端分离这个词,这几年几乎成了Web开发的默认姿势。打开招聘网站,十个后端岗位有八个写着“熟悉Spring Boot + Vue前后端分离开发”;GitHub上热门的前端项目也几乎都长一个样,dist目录打包静态资源,后端只负责出接口。但“分离”到底分离了什么?很多人其实没完全想清楚。有人觉得分离就是把HTML从后端模板里挪到前端工程里,有人觉得分离就是前端用Vue、后端用Spring Boot,还有人把前后端分离和跨域问题绑定在一起,一提分离就想到CORS。

我早年做项目是从JSP时代过来的,那时候一个页面里HTML、Java代码、SQL语句混在一起,改一个按钮颜色要重启整个服务,数据库加一列字段前后端都要跟着动,线上出问题还得把前后端代码一起回滚。后来切到前后端分离架构后,整个节奏完全变了——前端调接口、后端改数据,两条线并行推进,互不扯皮。但这套模式真落地的时候,又会踩到接口设计、鉴权、跨域、部署、联调协作一大堆坑。

这篇文章我不打算只讲概念,而是把这套前后端分离模式从设计思路、核心细节、项目实操到常见问题排查完整拆一遍。不管你是刚转行的新人,还是想把现有项目拆成前后端分离的老手,都能在这里找到一个可以照着做的完整方案。

1. 前后端分离拆开的不只是代码,更是协作方式

1.1 从模板渲染到前后端分离:为什么要拆

先聊聊这套模式为什么会出现。在早期的Java Web开发里,JSP是绝对的主流。一个.jsp文件里既能写HTML标签,又能嵌入<% %>脚本块,还能直接引用后端的JavaBean。这种写法的好处是“方便”,前端页面想要数据,直接在服务端取出来塞进页面就行。但坏处随着项目变大越来越明显:

第一,耦合严重。一个页面的展示逻辑和业务逻辑搅在一起,前端工程师要懂Java才能改页面,后端工程师改个字段还要担心页面渲染崩掉。

第二,联调效率低。前端页面和后端代码打包在同一个Web应用里,每次改动都要整个应用重新编译、重启。哪怕只是改个按钮颜色,也得走一遍完整的构建部署流程。

第三,分工困难。前端和后端的技能栈完全不同,硬塞在同一个工程里,两边都没法独立开发、独立测试。前端想用一个更好的构建工具,后端说不行,会影响我的工程结构。

前后端分离的本质,就是把“数据”和“展示”这两件事彻底拆开。后端专注提供数据接口,前端专注消费数据并渲染页面。双方通过一份约定好的接口契约交互,谁都不需要关心对方内部是怎么实现的。这其实和“设计模式”里的“开闭原则”是一个思路——对扩展开放,对修改关闭。接口稳定了,前后端各自内部怎么改都不会影响对方。

1.2 分离的真正边界:工程、接口、部署

很多人以为分离就是把代码文件分两个仓库,前端一个、后端一个。这只是最表面的工程边界。真正的前后端分离要拆三层:

第一层是工程边界。前端工程用Vite、Webpack这类构建工具管理,产出纯静态资源;后端工程是独立的API服务,不渲染任何页面。前后端各自有独立的代码仓库、独立的依赖管理、独立的测试流程。

第二层是接口边界。这是前后端分离里最重要也最容易忽略的一层。后端暴露的每个API,必须有明确的路径、方法、入参、出参定义。前端只依赖这两份东西,不依赖后端的具体实现语言、框架、部署地址。接口就是双方签的合同,合同摆好了,各自开发才不互相等。

第三层是部署边界。前端构建出的静态文件部署到Nginx这类Web服务器上,后端服务独立部署在应用服务器或容器里。两者可以分别水平扩展——前端静态资源流量大了,就多配几台Nginx;后端接口压力大了,就多扩几个实例。甚至可以把前端静态资源放到CDN上,这是传统模板渲染模式根本做不到的。

1.3 什么样的项目不适合做前后端分离

写到这里我得泼一盆冷水。前后端分离不是银弹,不是所有项目都适合无脑上。用这套模式是有成本的——接口设计要花时间、联调要花时间、跨域要处理、权限要重新梳理。如果项目很小,比如一个公司内部不到十个页面、没有独立前端团队的报表系统,用传统的服务端模板渲染反而更快,一个人就能搞定。

另外,对SEO要求极高的内容型网站,如果不上服务端渲染(SSR)或静态站点生成(SSG),纯前端渲染会带来很大劣势。搜索引擎爬虫抓到的可能是一个空的HTML骨架,或者执行完JS跑出来的结果,既要额外做预渲染又要解决直出问题,成本很高。

所以判断一个项目适不适合前后端分离,核心看三个条件:团队有没有明确的前端后端分工、项目规模大到值得维护一套接口契约、页面渲染和数据获取是否真的需要解耦。这三个条件都满足,再谈分离才有意义。

2. 分而不散:接口、鉴权与跨域是三大核心细节

2.1 接口契约先定好:统一返回体与全局异常

前后端分离项目最先要定,也最容易被忽略的,就是接口返回格式。很多项目前期没人管这件事,张三写的接口返回一个JSON对象,李四写的接口返回一个字符串,王五心情好又套了一层data。前端接这种接口简直是灾难,每个接口都要单独写解析逻辑,报错还报不明白。

我在项目里用的方案是统一返回体。无论成功失败,所有接口都返回同一个结构:

public class Result<T> { private Integer code; private String message; private T data; public static <T> Result<T> success(T data) { Result<T> result = new Result<>(); result.setCode(200); result.setMessage("success"); result.setData(data); return result; } public static <T> Result<T> error(Integer code, String message) { Result<T> result = new Result<>(); result.setCode(code); result.setMessage(message); return result; } }

同时配合全局异常处理器,让后端代码里不用到处写try-catch。业务异常统一抛出,最终都会转成上面这个结构返回给前端。这样一来,前端在axios拦截器里只要判断一次code,等于200就取data,不等于200就提示message,所有接口的交互逻辑完全一致。

分页接口也要单独定一个通用结构。我常用的分页返回体包含totallistpageNumpageSize四个字段,前端拿到这个结构就能直接渲染所有带分页的表格,不用每个接口单独适配。

2.2 JWT鉴权:登录态如何跨端保持

HttpSession那套方案,依赖服务端保存会话状态,天生就不适合前后端分离。因为前端可能是Web、可能是App、可能是小程序,后端可能是单体、可能是微服务集群。保持登录态最主流的方案是JWT(JSON Web Token)。

JWT的核心思路是:用户登录成功后,后端生成一个包含用户信息的签名Token返回给前端,前端每次请求都在Header里带上这个Token,后端验证签名即可。这个方案的好处是天然无状态,后端不需要存Session,集群环境下不需要做会话同步,验收也方便。

完整落地过程我一般分四步:

第一步,登录接口发放Token。用户提交用户名密码,校验通过后用HMAC或RSA算法签发Token,有效时长一般设两小时到一天。

第二步,前端存储Token并在请求头携带。Token存localStorage还是cookie是有讲究的。存localStorage更简单但容易被XSS攻击读取,存cookie要设置HttpOnly但会面临CSRF风险。项目里我常规做法是存localStorage,然后在axios请求拦截器里给每个请求加Authorization头。这样后端能直接读Header,不依赖cookie机制。

// axios 请求拦截器 service.interceptors.request.use(config => { const token = localStorage.getItem('token'); if (token) { config.headers['Authorization'] = `Bearer ${token}`; } return config; }, error => Promise.reject(error));

第三步,后端配置拦截器统一校验。写一个JwtInterceptor,排除登录、注册等白名单接口,其余所有请求都先校验Token。校验失败直接返回401,前端响应拦截器收到401就跳转登录页。

第四步,登录过期处理。Token是有时效的,过期后前端所有请求都会401。我的做法是在响应拦截器里判断401后,清除本地Token,跳转到登录页并提示“登录已过期,请重新登录”。更流畅的方案是搞一个刷新Token的机制——一个短期Access Token配一个长期Refresh Token,Access Token失效时用Refresh Token重新换一个。这个机制在移动端很有用,Web端如果嫌麻烦,直接过期重新登录也完全能接受。

2.3 跨域问题:开发环境与生产环境要分开处理

前后端分离项目必然面临跨域。前端页面跑在localhost:5173,后端接口跑在localhost:8080,端口不同,浏览器的同源策略就会拦截请求。很多新人在这里被折磨到怀疑人生,配置半天CORS还不生效。其实跨域这个问题的解法在开发和生产环境是完全不同的两套思路。

开发环境的正解是前端代理。以Vite为例,配置server.proxy/api开头的请求转发到后端地址:

// vite.config.js export default defineConfig({ server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } } });

这样前端请求/api/user/list,Vite开发服务器会转发到http://localhost:8080/user/list,浏览器里看到的请求始终是同源的,完全不会触发跨域。这套机制的原理类似反向代理,Vite开发服务器充当了中转站。

生产环境的正解是Nginx统一入口。前端静态资源和后端接口都挂在同一个域名下,通过路径前缀区分。/api开头的请求走反向代理到后端服务,其余请求直接命中前端静态文件:

server { listen 80; server_name yourdomain.com; root /usr/share/nginx/html; index index.html; location /api/ { proxy_pass http://backend-server:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location / { try_files $uri $uri/ /index.html; } }

这套配置下来,前后端天然同源,不需要后端额外开CORS。只有一种情况必须处理后端CORS——前后端域名分离部署,比如前端挂在CDN、后端是独立API服务。这时候才用@CrossOrigin注解或者CORS配置类,而且要注意配置allowedOrigins时必须写完整的前端域名,不能写*否则配了withCredentials也没用。

3. 从零到一落地:Spring Boot 3 + Vue 3 前后端分离实操

3.1 工程初始化与目录结构设计

拿一个典型的Spring Boot 3 + Vue 3项目举例,我会把工程分成两个独立仓库,前端用Vite构建,后端用Maven管理。

前端目录结构长这样:

frontend/ ├── public/ ├── src/ │ ├── api/ # 接口请求定义,按模块拆分 │ ├── assets/ # 静态资源 │ ├── components/ # 公共组件 │ ├── router/ # 路由配置 │ ├── store/ # Pinia 状态管理 │ ├── views/ # 页面组件 │ ├── utils/ # 工具函数,axios实例一般放这里 │ ├── App.vue │ └── main.ts ├── package.json └── vite.config.ts

后端目录结构长这样:

backend/ ├── src/main/java/com/example/ │ ├── controller/ # 接口层 │ ├── service/ # 业务逻辑层 │ ├── mapper/ # 数据访问层 │ ├── entity/ # 实体类 │ ├── dto/ # 数据传输对象 │ ├── config/ # 配置类,包含CORS、拦截器注册 │ ├── common/ # 统一返回体、异常处理、工具类 │ └── security/ # 认证授权相关 ├── src/main/resources/ │ ├── application.yml │ └── mapper/ # MyBatis XML文件 └── pom.xml

这个结构不复杂,但有几个关键的模块必须从第一天就放好:common里的统一返回体、config里的拦截器注册、api目录下的接口请求封装。这几个模块是前后端协作的地基,后面所有业务代码都建立在它们之上。

3.2 开发联调:后端接口文档与前端Mock双管齐下

前后端分离之后,最怕的是“后端还没写完,前端没法开工”。解决这个问题的标准做法是:后端用Swagger或Knife4j生成接口文档,前端基于文档先做Mock数据。

Spring Boot 3集成Knife4j的配置很简单,引入依赖后在配置类里加上文档扫描注解,启动项目后访问/doc.html就能看到接口文档页面。每个接口的路径、入参、出参模板一目了然,前端照着文档就能写接口调用代码。

前端自己再准备一套Mock也不是不行,但既然后端文档已经定义了接口结构,更高效的做法是前端在api目录下先把所有请求函数写好返回Promise,在Mock阶段直接返回假数据。等后端接口跑通了,只需要改一个baseURL切换开关。这里最忌讳的是前端自己造一套和后端结构不相符的假数据,等联调时全都要返工。

接口联调阶段我想强调一个工具,不是聊技术,是聊协作方式。前后端是同一团队的,建议直接拉一个接口联调群或者用一个在线协作表格,专门记录接口状态:是“文档已出”“后端已实现”“前端已联调通过”,还是“接口有变更”。很多项目的坑不是技术问题,是“接口改了但前端不知道”、“前端改了但后端还在按旧参数排查”。一份实时更新的接口清单比什么工具都好用。

3.3 后端接口数据交互的几个高频细节处理

联调阶段有几个细节是新手必踩的,我单独拎出来讲。

第一个是Long类型精度丢失。数据库自增主键和雪花ID都是Long类型,后端直接往前端返回JSON时,超过JavaScript安全整数的数值会被截断。比如主键ID是1853413796856741888,前端拿到手可能变成1853413796856741900,再把这个ID传回后端查询,直接查不到数据。解决办法有两种,一是在实体类的ID字段上加@JsonSerialize(using = ToStringSerializer.class)直接序列化成字符串,二是用Jackson Config全局处理。强烈建议全项目统一用第一种或者全局配置,不要一个接口一个接口地处理,容易漏。

第二个是日期格式统一。后端返回日期默认是2025-06-11T10:30:00.000+08:00这种格式,前端展示起来很痛苦。我通常在application.yml里配置全局日期格式化:

spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8

这样后端所有日期接口都返回2025-06-11 10:30:00这种格式,前端不用重复做格式化处理。

第三个是下划线与驼峰映射。数据库字段习惯用user_name,Java实体类习惯用userName,前端拿到JSON希望是userName。MyBatis-Plus默认开启驼峰映射,如果用的原生MyBatis,记得在配置里加上mapUnderscoreToCamelCase=true,否则字段映射不上,查出来全是null,前端就会一脸懵。

3.4 遇到成熟脚手架项目时,怎么合理地“抄作业”

聊到实操,不能不提那些前后端分离的开源脚手架。比如你可能会在网上看到大量基于Spring Boot + Vue的快速开发平台,像若依框架这类项目就是典型代表。它们已经把用户管理、权限控制、代码生成、系统监控这些通用功能都实现好了,开发一个企业后台管理系统,基于它二次开发效率极高。

遇到这类脚手架我的建议是:一定要借鉴,但别无脑照搬。借鉴的是它的工程结构和通用模块设计——统一返回体怎么写的、权限拦截器怎么配的、菜单路由怎么动态生成的、代码生成器怎么用的。但要注意,开源框架为了覆盖大量场景,往往带了很多你用不到的功能模块,如果直接拿来做生产项目,一定要把用不到的功能删掉,否则项目体积臃肿不说,还要花额外精力维护。另外,这类框架用的依赖版本一般比较保守,整合进新项目前要先确认包版本有没有兼容性问题。

4. 不止于编码:部署、自动化与团队协作实践

4.1 用Jenkins搭建前后端分离项目的自动化部署流水线

项目开发完总要部署上线。前后端分离项目最大的优势就是在部署这一步体现得淋漓尽致——前后端可以独立构建、独立发布、独立回滚。

我在生产环境最常用的部署方式是:Jenkins从Git拉取代码并完成前端构建,再将dist目录同步到Nginx服务器,同时也拉取后端代码用Maven打包并重启后端服务。整套自动化流程我写成Jenkins Pipeline文件,长这样:

pipeline { agent any stages { stage('拉取前端代码') { steps { git url: 'git@github.com:yourname/frontend.git', branch: 'main' } } stage('构建前端') { steps { sh 'npm install --registry=https://registry.npmjs.org' sh 'npm run build' } } stage('部署前端') { steps { sh 'scp -r dist/* root@your-server:/usr/share/nginx/html/' } } stage('拉取后端代码') { steps { git url: 'git@github.com:yourname/backend.git', branch: 'main' } } stage('打包后端') { steps { sh 'mvn clean package -DskipTests' } } stage('重启后端服务') { steps { sh 'ssh root@your-server "systemctl restart backend.service"' } } } }

这套流水线跑起来后,开发只需要把代码推到主干分支,剩下的构建、部署、重启全部自动完成。要注意前端的scp同步最好配合rsync做增量同步,首次全量没问题,后面每次构建只传变更文件,部署速度会快很多。

4.2 多人协作中最容易被忽视的接口变更管理

前后端分离后,团队内部的技术依赖变成了“接口依赖”。我最想给团队强调的一句话是:接口不是写出来的,是讨论出来的。后端的接口设计要秉承“面向前端需求”的原则,不能我数据库有什么字段就返回什么字段,而是前端页面要什么数据就返回什么数据,减少一次请求携带无用字段。

多人协作时接口变更管理是个大学问。代码层面要解决的是:后端接口签名改了,前端怎么及时感知;前端换了接口,后端怎么知道。解决思路是从流程上约束:

第一,接口变更必须走文档更新流程。先改接口文档,再改代码,最后通知前端同事。顺序反了,文档和代码就会出现不一致。

第二,接口版本管理要明确。如果是一次破坏性的重构——路径改了、参数改了、返回结构改了,建议不要直接覆盖原接口,而是新增一个V2版本,让前端有时间平滑迁移。

第三,定期做接口联调评审。我一般建议在每次迭代结束前,前后端坐在一起过一遍改动过的接口,用真实数据跑一遍流程,能提前发现一大批字段缺失、类型不匹配、状态码语义不统一的问题。

5. 常见问题排查与避坑实录

5.1 前后端分离项目高频问题速查表

我把这几年实操中遇到的高频问题,按“现象 — 原因 — 解决方案”整理成一个速查表,方便你遇到问题直接对照:

现象原因解决方案
前端接口请求404代理没配全,或者Nginx的location匹配没生效检查Vite proxy配置;Nginx配置里location顺序是否合理
前端能登录,但登录后接口401Token没带,或者拦截器没放行该路径检查axios拦截器加Token的逻辑;后端JwtInterceptor白名单是否遗漏
刷新页面后404,白屏前端用的是history路由,Nginx没配try_files在Nginx静态资源location里加try_files $uri $uri/ /index.html
接口返回了数据,但页面显示不出来字段名对不上,或者Long类型精度丢失检查后端是否启用驼峰映射;Long类型ID按字符串序列化
开发环境接口能通,部署后跨域报错生产环境没走Nginx代理,直接直连后端接口用Nginx统一反向代理,保持同源
页面中文乱码后端返回头没指定UTF-8,或者前端页面编码不对检查后端server.servlet.encoding配置;确保HTML文件是UTF-8保存
上传大文件一直失败Nginx默认client_max_body_size太小在Nginx增加client_max_body_size 50m

5.2 跨域配置不生效的排查思路

跨域是最容易让人头大的问题。你配置了@CrossOrigin,但还是报CORS错误,我每次排查都会按下面这个顺序走一遍:

第一,确认请求是“简单请求”还是“预检请求”。如果前端请求带着自定义Header(比如Authorization),浏览器会先发一个OPTIONS请求探路。很多后端框架的拦截器直接把OPTIONS请求拦截掉了,导致预检请求都到不了Controller层,更谈不上返回CORS头。解决办法是在WebMvc配置类里,让CORS配置和拦截器都放行OPTIONS请求。

第二,确认CORS配置没有和Spring Security冲突。如果你用了Spring Security,CORS过滤器一定要配置在Security过滤器链之前,否则Security先返回了403,CORS头根本没机会写入响应。

第三,确认allowedOrigins没有写*。当你需要携带Cookie时,Access-Control-Allow-Origin不能是星号,必须是指定的完全匹配的域名,而且要配合allowCredentials(true)使用。

5.3 前端history路由刷新404的经典处理

这个问题我见过不下十次。前端用Vue Router的history模式,本地开发一切正常,打包部署到Nginx后,点击页面里跳转没问题,但一旦按F5刷新,直接就404。

原因是history模式的路由路径是浏览器地址栏的真实路径,比如/user/list。刷新时浏览器向服务器请求这个路径,但服务器上根本没有这个路径对应的静态文件,于是返回404。

解决办法就是Nginx的try_files配置。它会在静态文件确实不存在时,把请求重写到/index.html,让前端路由自己去匹配。注意上面那个配置里,location /块里必须写上try_files $uri $uri/ /index.html;,缺一不可。

还有一种变体,如果前端部署在子路径下,比如/admin,那么Nginx配置和前端路由的base参数都要同步设置,否则资源路径全乱。

5.4 联调阶段最大的隐藏坑:环境差异

最后一个坑我必须强调。有时候开发和测试环境都好好的,一上预发布环境就出一堆问题。多数情况不是代码问题,是环境差异:

后端接口的IP或域名配置,在前端是写死的还是走环境变量?很多前端工程里把baseURL写死在src/config.js里,换环境就要改代码重新构建。正确做法是区分构建环境,用Vite的import.meta.env按环境加载配置,或者更简单地,把API地址放在Nginx的代理配置里,前端始终请求相对路径/api,这样换环境完全不用重发前端。

数据库数据和开发环境不一致,比如开发环境有100条数据,测试环境只有3条,就会出现分页组件的边界问题。这个要靠测试环境的数据尽量仿真解决。

还有时间同步。后端服务器和用户本地时区差异会导致接口返回的时间相差8小时,记住后端统一用GMT+8,前端展示时也要关注本地时区。


前后端分离这套模式,说到底不是技术有多高深,而是它逼着你把“数据”和“展示”的边界想清楚。我见过太多项目,名义上说了前后端分离,实际上前端页面里到处硬编码接口地址、后端Controller里返回乱七八糟的结构,最后联调一个月才上得了线。这些坑,基本都在上面这些细节里。

如果你正准备把一个老项目改造成前后端分离,我的建议是从小处入手,先把某个模块的接口切出来,跑通开发联调部署全流程,再逐步推广。这个过程里,接口契约和自动化部署越早建立越好,它们会反过来逼着团队规范起来。我自己踩了这么久的坑,最深的体会是:前后端分离的难点从来不在“分”,而在“分完之后怎么还能高效地合在一起”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 21:42:52

PaddleOCR 3.0工程化落地:精度、速度与稳定性的三位一体升级

1. 项目概述&#xff1a;PaddleOCR 3.0不是一次简单升级&#xff0c;而是OCR工程落地逻辑的重构你最近刷到“百度飞桨PaddleOCR 3.0开源发布 OCR精度跃升13%”这个标题&#xff0c;第一反应可能是——又一个版本号更新&#xff1f;但作为连续三年在金融票据、政务文档、工业质检…

作者头像 李华
网站建设 2026/9/24 21:42:51

Agent Skills:智能体落地中可插拔技能的设计哲学与实战

1. 为什么说 Agent Skills 是智能体落地的关键拼图做过 AI 应用的人应该都有这种感觉&#xff1a;大模型本身能力再强&#xff0c;也只是个“大脑”&#xff0c;没有手脚。你要让它真正干活儿&#xff0c;就得给它配工具、配流程、配执行策略&#xff0c;而这一整套可复用的能力…

作者头像 李华
网站建设 2026/9/24 21:42:48

从零构建cua:用Go打造本地开发环境配置管理命令行工具

说实话&#xff0c;第一次看到手里的项目需求只有“cua”三个字母时&#xff0c;我愣了好几秒。这既不像什么现有开源项目的缩写&#xff0c;也不太像正经产品名&#xff0c;倒像个语气词或者音效词。但做工具这事儿&#xff0c;名字从来不是最重要的&#xff0c;重要的是它背后…

作者头像 李华
网站建设 2026/9/24 21:41:28

辽源信誉好的本地装修专业公司推荐 城市人家装饰省心之选

装修对大多数家庭来说都是一件大事&#xff0c;更是容易让人头疼的烦心事。不少辽源业主第一次接触装修&#xff0c;光是前期做功课就花了不少时间&#xff0c;但真到选装修公司的时候&#xff0c;还是容易踩坑。今天就来聊聊大家在选本地装修公司时&#xff0c;最容易遇到的4个…

作者头像 李华
网站建设 2026/9/24 21:41:02

LLM模型意外删除怎么办?Pirate Face抢救工作流全解析

做模型工程最怕听到的一句话是什么&#xff1f;不是训练崩了&#xff0c;也不是显存不够&#xff0c;而是“那个模型被删了”。本地磁盘误清空、云盘配额到期、模型仓库下架、许可证变更撤回权重……我这两年见过太多次“模型消失”的现场&#xff0c;每一次都有人拍桌子后悔当…

作者头像 李华
网站建设 2026/9/24 21:40:39

开源本地AI平台:架构设计、部署实践与踩坑全记录

最近我把一直在维护的本地AI平台整理成了一个开源项目&#xff0c;最初是以 Show HN 的形式发布出去的&#xff0c;没想到反响比预期热烈。正好借这篇博客&#xff0c;把整个项目的来龙去脉、架构设计、部署流程和踩坑记录都摊开聊聊。这个项目简单来说就是一个开源、本地可用、…

作者头像 李华