SpringCloud微服务实战:美食分享平台从架构到部署全流程复盘

发布时间:2026/10/18 4:56:31
SpringCloud微服务实战:美食分享平台从架构到部署全流程复盘
最近在整理一套完整的SpringCloud微服务实战项目——一个以美食分享为业务场景的交流平台。源码、设计文档、部署说明和讲解视频都是齐的拿来可以直接跑通完整的微服务调用链路也可以作为课程设计或毕业设计的底子快速改造。前后我断断续续折腾了差不多一个多月中间踩了不少坑正好趁这个周末把它们全部整理出来。如果你正在准备一个微服务方向的实践项目或者打算用这套平台做毕业设计这篇记录应该能帮你省掉不少弯路。先说结论这个项目不是那种只放几个接口应付检查的Demo而是一个能真正跑起来的分布式系统。它包含网关、认证、用户、内容、互动、推荐等独立服务配合Nacos注册中心、Sentinel熔断限流、Redis缓存、RabbitMQ异步通知、MinIO对象存储完整模拟了一个真实社区产品的后端形态。业务上覆盖了注册登录、发帖探店、图文上传、点赞评论、关注Feed流、个性化推荐这些常见的社区功能既有架构深度又有业务完整度。下面是整个项目的完整复盘从架构设计到模块拆解从本地启动到部署上线再到常见坑的解决方案一路讲清楚。1. 项目整体脉络为什么是SpringCloud还有别的选择吗1.1 微服务拆分不是越多越好刚接触微服务的时候很容易有一种冲动功能拆得越细越好用户一个服务、帖子一个服务、点赞一个服务、收藏一个服务……结果就是把简单问题复杂化服务数量爆炸联调成本高还要处理一堆分布式事务。这个项目在拆分服务时第一原则是“按业务域拆不按动作拆”。美食分享平台的业务可以归纳为五条主线身份认证、用户关系、内容发布、互动行为、个性化推荐。于是最终的服务划分非常清晰服务名职责范围关键依赖gateway统一入口、路由转发、跨域处理、JWT校验Nacos、Redisauth登录注册、令牌签发与刷新MySQL、Redisuser用户资料、关注/粉丝关系MySQLcontent美食帖发布、图文上传、帖子详情MySQL、MinIOinteraction点赞、评论、收藏MySQL、Redis、RabbitMQrecommend浏览记录、内容召回与排序MySQL、Redis每个服务都独立进程、独立数据库逻辑上分库、独立扩容。这样的划分逻辑很清楚某一块流量大了单独把这个服务多拉两个实例就行其他服务完全不受影响。实际开发中这种按业务域拆分的方式也比按页面拆分、按接口拆分要稳定得多。我见过很多项目把登录逻辑放进用户服务里结果网关想做统一鉴权就很尴尬。这个项目把auth单独拎出来用户服务只做用户数据和关系职责边界非常干净。后续不管是要接入微信扫码登录还是做手机验证码登录都只改auth和网关不会动到用户主链路。1.2 SpringCloud全家桶选型之旅既然决定了微服务技术栈选型就成了重头戏。SpringCloud的生态组件非常多但是老牌的Eureka已经进入维护模式Consul在国内用的团队相对少最终选择了Spring Cloud Alibaba这套组合核心组件如下Nacos注册中心 配置中心二合一Spring Cloud Gateway网关基于WebFlux响应式模型性能比Zuul好很多OpenFeign服务间声明式HTTP调用Sentinel限流、熔断、降级RabbitMQ异步消息解耦MinIO自建对象存储存放帖子图片为什么选Nacos而不是Eureka最直观的原因有三个。第一Nacos控制台比Eureka精致太多服务列表、健康检查、配置管理都在一个界面上完成第二Nacos同时充当注册中心和配置中心省掉了一整套Config组件的部署和接入第三国内公司用Spring Cloud Alibaba的非常多做完这个项目面试聊微服务实践完全不虚。关于Sentinel很多人觉得项目里没有高并发用不上限流熔断其实不然。Sentinel在项目里可以对热点接口做限流比如帖子详情接口、首页Feed流接口万一有刷接口的情况直接返回降级提示而不是把服务拖垮。这个在答辩时非常加分能体现出你对生产环境的思考而不是只会写CRUD。有同学问过为什么不直接上Dubbo。Dubbo是RPC框架性能确实好但和SpringCloud生态结合需要额外适配OpenFeign的体验。既然项目定位是“微服务架构的完整实践”SpringCloud全家桶整套下来更贴近当前企业的主流技术栈学习性价比也更高。1.3 这套架构解决的核心痛点单体应用最大的痛是什么是改一处、动全身。美食分享平台如果做成单体帖子模块的一次小改动都得把整个应用重新打包上线一旦用户量和数据量上来数据库连接、内存、CPU全部挤在一起任何一个小功能出问题都可能导致全站不可用。微服务化之后几个最直观的改变独立部署content服务发布新版本user服务完全不需要重启独立扩容大促或者活动期间互动量暴增只把interaction服务扩到3个实例就好故障隔离某个服务内存溢出其他服务的请求依然正常处理技术异构不同服务可以按需选型比如推荐服务后续想上Python的算法模型完全可行但这里必须泼一盆冷水微服务的确带来了灵活性也引入了分布式系统的复杂度。服务间调用变成网络调用延迟增加了数据不再在一个库一致性变难了链路一长排查问题就得靠日志追踪。这个项目的处理方式是“尽量不做跨服务强一致写操作”比如发布美食帖只写content库点赞这种高频操作先用Redis缓存再通过RabbitMQ异步落库用最终一致性取代强一致性——这是目前互联网产品最务实的做法。2. 核心功能模块拆解从用户到推荐的完整链路2.1 用户中心与登录鉴权用户模块属于基建型服务所有业务都离不开它。user表设计得很常规但有关键点id自增主键username唯一昵称passwordBCrypt加密存储avatar头像URLbio个性签名status账号状态正常/禁言/封禁密码为什么必须用BCryptMD5和SHA这类摘要算法虽然快但是彩虹表攻击一打就穿。BCrypt内置随机盐每次加密结果都不同即使数据库泄露攻击者也很难还原原始密码。这是安全底线不是可选项。登录流程是这样的前端把用户名密码提交给auth服务auth服务校验通过后签发JWT令牌令牌里只放userId、用户名、角色这三样轻量信息然后返回给前端。之后前端每次请求都在Header里带上令牌网关层统一做JWT校验再把userId放到请求头里传递给下游业务服务。这里最大的设计亮点是鉴权收敛到网关。业务服务完全不用关心“当前用户是谁”网关已经帮你解析好放到请求头里了拿request.getHeader(userId)直接用就行。这样每个服务都不用写重复的鉴权过滤器代码量大幅减少。JWT还有一个细节我设置access_token有效期2小时refresh_token有效期7天。前端拦截到token过期就静默用refresh_token换新的用户全程无感。如果不做刷新机制用户用着用着突然掉线体验非常糟糕这在真实的社区产品里是不可接受的。2.2 美食分享内容发布与内容流美食分享平台的核心内容形态是“图文探店帖”。content服务的post表设计成这样的核心字段title标题content正文支持Markdown语法cover封面图URLimages多图URL用分隔符拼接或JSON数组存储tag_ids关联的标签location探店地点经纬度 地点名称status草稿/已发布/已下架view_count、like_count、comment_count统计计数发布流程是典型的“先传文件再提交内容”。前端先把图片上传到MinIO拿到URL后和其他字段一起提交给content服务。为什么要分两步因为HTTP请求体大小有限制图片二进制直接塞进表单里会非常笨重而且无法做进度条断点续传也麻烦。拆开之后文件走对象存储业务数据走接口各司其职。MinIO的使用在这个项目里是个亮点。它可以本地部署、API兼容S3规范和云厂商的对象存储用法几乎一样但不花钱。部署方式也很简单一个Docker命令起个容器控制台里就能管理桶和文件。内容流是社区产品的核心。Feeds流这块我没有选择用复杂的推拉结合方案而是做了非常实用的混合模式用户发帖后把帖子ID推送到所有粉丝的Redis收件箱ZSET按时间排序用户刷首页时先拉收件箱里的帖子ID列表再批量回查post表详情。如果用户关注的人太多或者是大V粉丝量巨大再考虑拉模式兜底。这个设计对课设/毕设来说已经足够有深度了面试官问起来也能讲清楚每种模式的优缺点。2.3 评论、点赞与互动通知interaction服务承担了社区里最活跃的两类操作点赞和评论。点赞这种操作有极度明显的读写不均特征读多写少且要求响应快。如果每次点赞都直接操作MySQL高峰时数据库连接很容易被打满。这里的方案是Redis使用Hash结构like:post:{postId}存储点赞用户集合点赞/取消点赞直接操作RedisO(1)复杂度毫秒级响应通过RabbitMQ异步把点赞记录同步到MySQL评论类似评论本身写入MySQL但热门评论会预热到Redis帖子详情页只查缓存有效降低数据库压力。这里用Redis做缓存后要注意缓存穿透和击穿问题帖子详情接口在代码里做了空值缓存和互斥重建这两个细节是很多项目会忽略的。互动通知走RabbitMQ是这套系统的另一个亮点。比如A点赞了B的帖子interaction服务发送一条MQ消息通知服务订阅消息后写入站内信。这样点赞接口不需要等待通知落库用户体验上就是“秒赞”。而且MQ天然实现了削峰填谷即使瞬间有大量点赞MySQL也能按自己的节奏慢慢消费不会被打爆。2.4 个性化推荐逻辑推荐服务是整个项目里最能体现“思考深度”的部分。我没有直接套一个复杂的机器学习模型而是用了一套“标签召回 规则排序”的方式用户在注册时选择口味偏好标签比如川菜、粤菜、甜品、火锅。用户浏览帖子时的行为点赞、评论、收藏会不断强化用户与某个标签的关联度。推荐时先从用户在近7天互动最多的标签里选出Top3标签再按这些标签召回近期高热度帖子最后根据分数排序输出。分数计算是精华所在score 0.4 * 热度分 0.3 * 标签匹配分 0.2 * 关注关系分 0.1 * 时效分热度分参考浏览量、点赞量、评论量做对数归一化标签匹配分来自用户标签与帖子标签的重合度关注关系分表示“我关注的人发的帖子优先展示”时效分让新帖有一定的流量机会。这套推荐逻辑讲白了就是“基于内容的召回 启发式排序”但背后涵盖了召回、排序、冷启动这些推荐系统的基本概念。在数据量到百万级别之前这种方案和上模型的效果差距不大但实现成本和可解释性都好得多。答辩时如果老师追问为什么不用协同过滤你可以说“协同过滤需要用户行为矩阵数据稀疏时效果很差规则方案更适合创业期产品快速验证。”这句话一出来层次感立马就有了。3. 从源码到落地的全流程实操3.1 拿到源码后的第一步先把工程跑起来很多同学一拿到源码就急着看代码噼里啪啦打开IDEA就开始启动然后报一屏错误心态直接崩了。正确顺序是先搭环境再看代码。这个项目需要的基础环境如下JDK 1.8或17推荐JDK8兼容性最稳Maven 3.6MySQL 5.7或8.0Redis 6RabbitMQ 3.8MinIONacos 2.x本地开发我建议直接Docker起中间件一条命令搞定所有依赖docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORDroot -d mysql:8.0 docker run -p 6379:6379 -d redis:6 docker run -p 5672:5672 -p 15672:15672 -d rabbitmq:3-management docker run -p 9000:9000 -p 9001:9001 -d minio/minio server /data --console-address :9001Nacos作为注册中心和配置中心我本地是用单机模式启动的startup.cmd -m standalone中间件全部起来之后下一步是初始化数据库。项目doc目录下会有sql文件夹里面有每个服务的建库脚本。注意顺序不能乱先建库再导数据并且检查一下数据库账号密码和项目配置里的spring.datasource.password是否一致。最后就能启动服务了。启动顺序有讲究我总结为“先中心、后网关、再业务”。先启动Nacos然后启动gateway之后启动auth、user、content、interaction、recommend最后启动后台管理端的前端工程。如果启动过程中某个服务报“找不到Nacos”多半是Nacos地址没配对或者Nacos本身没起来。注意启动命令里如果没有指定--spring.profiles.activedev服务默认加载的是application.yml大概率连的数据库和Nacos都是错的。这个项目我建议明确指定dev环境配置文件里的命名空间、分组也要和Nacos控制台上保持一致。3.2 注册中心、配置中心与网关接入细节Nacos在项目里承担了两个角色。作为注册中心每个服务启动后会自动把自己的IP和端口注册上去服务间通过服务名就能互相发现不用硬编码IP地址。作为配置中心我们把数据库连接、Redis地址、MQ连接这些配置统一放到Nacos上服务启动时从Nacos拉取配置真正做到了“配置和代码分离”。每个服务里都有一个bootstrap.yml它是启动时最先加载的配置文件负责连接Nacos获取真正的配置spring: application: name: content-service cloud: nacos: server-addr: 127.0.0.1:8848 config: file-extension: yaml namespace: dev group: FOOD_SHARE discovery: namespace: dev group: FOOD_SHARE这里的namespace和group是一个很容易踩坑的点。如果Nacos配置中心的命名空间ID和你bootstrap.yml里写的不一致服务启动时会报“config data not found”之类的错误但往往不是直接报错而是用本地默认配置启动等你排查半天才发现Nacos上的配置根本没生效。我先把这个坑写在这后面第4章还会详细讲。网关的配置是一个重点。网关是所有请求的入口路由配置决定了请求转发到哪个服务spring: cloud: gateway: routes: - id: user-route uri: lb://user-service predicates: - Path/api/user/** filters: - StripPrefix1 - id: content-route uri: lb://content-service predicates: - Path/api/content/** filters: - StripPrefix1lb://表示通过负载均衡从注册中心找到目标服务实例StripPrefix1表示转发时去掉第一个路径前缀。比如浏览器请求/api/content/post/1网关转发到content-service的路径是/post/1也就是content服务里的Controller只写/post/1而不写/api/content/post/1。这个前缀剥离机制理解不透的话很容易出现404。网关还有一个很关键的配置跨域。前端在localhost:8080后端网关在localhost:8088不做跨域处理浏览器一定报CORS错误。我在网关层统一加了CorsFilter全局允许跨域请求之后所有业务服务就再也不用单独处理跨域了。这一点如果漏掉前端所有请求都会挂在预检请求上而且错误信息容易误导人看起来像是接口写错了。3.3 服务间调用与前端联调服务间调用用的是OpenFeign。比如content服务需要查询用户的基本信息直接调用user服务提供的接口不需要自己写HTTP客户端代码FeignClient(name user-service, path /user) public interface UserFeignClient { GetMapping(/{id}) UserVO getUserById(PathVariable(id) Long id); }Feign的底层是HTTP调用所以会引入网络延迟。为了不让接口变慢我的做法是能一次查询就别多次调用比如帖子列表需要展示作者头像和昵称不要循环一条帖子调一次接口而是把帖子里的userId全部收齐一次批量查回来在内存里做聚合。前端联调阶段最大的体验问题是接口地址不统一。前端项目里的axios请求地址统一写成了/api开头由Vite的代理转发到网关或者直接在nginx里配置反向代理。这样前端代码里没有任何硬编码的后端地址换环境部署只需要改一处代理配置。这个习惯看起来小但在真实项目里能节省大量沟通成本。联调时最经典的问题就是前端请求到的数据和后端调试接口的数据不一致。本质原因是前端请求打到了测试环境的网关而后端本地调试的端口是8080起的直连服务两边数据库不同。我建议联调阶段把前端的代理地址指向你自己的网关地址所有人都用同一套环境数据一致性才有保障。3.4 生产环境落地部署建议本地跑通只是第一步部署到服务器才是完整闭环。项目提供了的部署文档里最省心的一种方式是Docker Compose一键编排。Docker Compose的编排思路很清晰把MySQL、Redis、RabbitMQ、MinIO、Nacos这些基础设施编排在一起每个微服务单独打一个镜像也编排进来。服务器上一句docker compose up -d整个平台就起来了。每个微服务的Dockerfile很简单基于Java基础镜像把打好的jar包塞进去FROM openjdk:8-jre-alpine COPY target/content-service.jar app.jar ENTRYPOINT [java, -jar, /app.jar, --spring.profiles.activeprod]打包的时候要注意Maven打包前先执行mvn clean package -DskipTests然后通过流水线把产物复制到服务器。如果只用一台2核4G的服务器我建议关掉非核心服务或者把推荐服务合并进content服务里跑不然内存很容易不够用。服务器上Nacos的部署本地用单机模式可以生产环境一定要用集群模式至少三个节点做集群否则Nacos挂掉全站瘫痪。这个在部署文档里写得很明确我没有偷懒省略因为生产环境的可用性是底线。关于域名和HTTPS我建议有条件就配一个。网关前面加一层NginxNginx负责HTTPS终结然后把请求转发到网关。这样网关只关心路由逻辑SSL证书这类事交给Nginx处理职责更清晰。4. 常见问题与排坑实录4.1 服务间调用失败明明注册了为什么找不到这个绝对是微服务项目上线第一天最容易翻车的点。现象是Nacos控制台上服务列表全部在线但是A服务调用B服务时一直报connection refused或者no instances available。排查思路按顺序来第一步先看Nacos服务列表确认服务提供方的实例数和健康状态是不是都正常。第二步看调用方FeignClient里的name值是否和服务提供方的spring.application.name完全一致。这个坑隐蔽在于Feign的name写错一个字母控制台不报错只会在运行时找不到实例。第三步检查服务提供方实际监听的端口。很多场景下服务启动时IDE或者命令行里手动指定了--server.port8082但配置中心里的端口还是8080而Nacos注册的又是配置中心里的端口。两边不一致调用方拿到的端口就是错的自然连接失败。我调试得最久的一次就是Feign接口调不通最后发现是服务提供方把Nacos集群配置里的IP写成内网IP而调用方在另一台机器上访问不到这个内网地址。注意服务部署到云服务器时Nacos注册IP不要配置成127.0.0.1或者内网地址要配置成公网IP或可被其他服务路由到的地址。项目部署文档里专门强调了这个配置项很多线上故障都是这个引起的。4.2 配置刷新不生效与缓存一致性问题Nacos配置中心有个非常方便的能力配置修改后服务不需要重启就能生效。实现这个效果只需要在配置类上加上RefreshScope注解。但很多同学加了注解后发现修改配置后第一次刷新有效第二次就不变了。原因是RefreshScope对普通的Value字段有效但对ConfigurationProperties绑定的对象刷新行为有时不可控。更隐蔽的是如果某个Bean在初始化时把配置值缓存到局部变量里那么即使RefreshScope帮你重新创建了Bean旧Bean销毁前已经缓存的旧值依然会被用到。解决办法其实很简单核心配置比如数据库连接、Redis地址不要频繁热更新更新这类配置就直接重启服务反而更安全RefreshScope只用来刷新那些可以容忍短暂失效的业务开关比如推荐算法里某个权重系数。这个思路虽然保守但能避免很多线上数据错乱的问题。另一个和配置相关的经典问题是缓存一致性。帖子的点赞数在Redis里有缓存MySQL里也有数据如果MySQL里被后台改掉了Redis里的旧值还会继续被读出来。我处理的办法是“先更新数据库再删除缓存”让下次查询重新回源。这个顺序如果反了比如先删缓存但数据库更新失败缓存里没有数据数据库又是旧数据就会导致数据错乱。虽然项目规模不大但把这些细节做对了在面试中绝对能成为亮点。4.3 数据库连接池耗尽的排查微服务架构下数据库连接池耗尽算是常见的疑难杂症。表现是服务正常但个别接口响应极慢过一会日志里开始刷HikariPool-1 - Connection is not available, request timed out after 30000ms。当时我第一时间查了数据库的max_connections发现没有到上限问题就锁定了是Hikari连接池里连接被占满。接着查Druid或Hikari的监控面板发现卡住的SQL里有一批针对帖子热度表的查询执行计划走了全表扫描单次查询虽然只要几百毫秒但并发一多就把连接池打满了。处理思路是先止血再根治。止血是重启服务让连接池释放根治是给慢SQL加复合索引同时给Feign调用增加超时时间避免因为下游服务慢而把数据库连接池里的连接长时间占住。这个坑给我的核心教训是微服务里一个接口出问题如果超时时间设置不合理链路会层层积压最后把所有服务的线程池和连接池全部拖死。所以在网关和Feign两个层面都要配置好超时时间这是必修课。4.4 文件上传后前端无法访问的排查美食分享平台离不开图片上传。我遇到过的典型情况是帖子发布成功图片URL也正确存到了数据库但前端打开帖子详情图片区域一片空白打开URL直接404。排查步骤第一步先手动在MinIO控制台里查看这个文件是否存在发现文件确实上传成功了。第二步直接访问MinIO的地址如果MinIO部署在服务器上访问地址是http://服务器IP:端口/桶名/文件名这里需要检查MinIO的访问端口是否在防火墙和安全组里放开了。MinIO API端口是9000控制台端口是9001。需要注意的坑是很多同学只放开了9001控制台端口没放开9000 API端口控制台能看到文件但API无法访问。第三步如果还是404检查桶的访问权限策略。MinIO默认桶是私有的需要设置成public-read或者通过预签名URL访问。我建议把桶策略设置为readonly因为美食分享平台的图片就是公共资源不需要鉴权。在控制台里给桶添加如下策略{ Version: 2012-10-17, Statement: [ { Effect: Allow, Principal: { AWS: [*] }, Action: [s3:GetObject], Resource: [arn:aws:s3:::food-share/*] } ] }设置完之后图片就能正常访问了。这个配置在部署文档里有写但确实很容易被遗漏。5. 源码、文档与讲解怎么配合使用5.1 交付物目录里每一块是干嘛的很多同学拿到一个完整项目交付包第一反应是无从下手不知道先看哪个。这里我把交付物里的几大块作用和阅读顺序梳理一下源码核心产物。包含后端微服务代码、前端页面、数据库脚本。建议先看后端的工程结构和核心模块的代码其次是前端页面和接口的对应关系。设计文档常说的lw也就是课程设计或毕业设计的设计说明这是你写论文、做答辩PPT的素材库。里面通常包含需求分析、可行性分析、系统设计、数据库设计、功能展示截图、测试报告等章节。你要做的不是整篇照抄而是把里面的内容组织成自己的语言补充自己实际开发的细节。部署文档手把手教你从零搭建环境、启动服务、部署上线的操作手册。我第一次跑通整个项目就是按部署文档一步步来的它解决了“从哪里开始”的问题。讲解视频讲解视频的重点通常包括系统演示、项目架构介绍、核心代码走读。它的价值是让你直观看到整个项目应该怎么演示、怎么讲重点。正确的学习路径应该是先照着部署文档把项目跑起来感受系统全貌再对照设计文档理解业务需求接着挑自己最感兴趣或者最复杂的模块精读源码最后跟着讲解视频学习整个项目的表述方式。顺序对了效率能高一倍。5.2 如何把交付项目改造成自己的作品既然这个项目最终可能用于课程设计或毕业设计我非常不建议“只改个名字和Logo就交上去”老师一眼就能看出来。真正有含金量的做法是做一个“功能增量”或“技术增量”。功能增量很好理解。比如原始项目是普通的美食帖你可以增加一个“探店合辑”功能让用户把多个帖子打包成一个合集支持合集的点赞和分享。这个功能涉及新表设计、新接口、新的前端页面工作量不大但整个业务故事就完整了而且是你自己的原创功能。技术增量更有含金量。原始项目的推荐服务用的是规则召回你可以把它升级成一个简单的协同过滤算法算出用户对帖子的预测评分或者引入ElasticSearch做全文搜索把帖子标题和内容的搜索从SQL的LIKE查询升级为搜索引擎的倒排索引。这些改动一旦完成并写入设计文档你的项目就完全不是“借鉴”而是真正属于自己的作品了。改项目一定要遵循一个原则小步快跑。先跑通原版再做增量每做一部分就提交一次代码确保随时能回滚到稳定状态。我有一个很惨痛的经历接手某一套项目后想一次性改三四个功能结果改到一半项目跑不起来了最后只能推倒重来浪费了整整两天时间。5.3 答辩/汇报的讲解思路无论是毕设答辩还是课程项目汇报有条主线非常重要。我建议按这个顺序来展示第一步讲选题背景和系统价值。为什么选美食分享平台因为美食内容天然有互动属性有用户生成内容UGC有社交关系有推荐场景是一个非常适合展示微服务能力的业务。第二步画架构图。不用画太复杂画清楚“浏览器→网关→注册中心→各微服务→数据库/缓存/消息队列/对象存储”这条主线就行。讲清楚每个中间件的作用比如Redis用来扛高并发读RabbitMQ用来做异步解耦MinIO用来存图片。第三步做功能演示。先演示注册登录再演示发布美食帖、图片上传、点赞评论、关注Feed流、个性化推荐。演示过程中不要光点按钮要点开网络请求向老师展示请求经过网关的转发过程这个细节很加分。第四步讲核心代码。不要从头讲到尾挑三处最核心的技术点讲深讲透。我推荐三个候选JWT在网关的鉴权流程、点赞用Redis结合MQ异步落库的方案、推荐服务的召回排序策略。把这三块讲清楚整个项目的技术含量就体现出来了。最后一步诚恳地讲一讲项目不足和后续改进方向。比如可以说“目前推荐服务采用的是规则方案后续可以引入协同过滤提高推荐效果评论体系目前是异步通知后续可以接入实时推送。”这样讲比吹得天花乱坠更能获得认可。最后再分享一个我个人的切身体会。整套项目我自己跑通第一遍的时候大概花了四个小时中间无数次踩坑但第二遍只需要一小时。之后每改一个功能、每踩一个新坑都会加深一次对微服务架构的理解。这个项目真正的价值不是那几千行代码而是它让我完整地走了一遍从架构设计到部署上线的链路这套经验是看多少教程都换不来的。如果你手上已经有这套源码包建议耐住性子按顺序把每个服务启动的顺序、每个配置项的含义、每个接口的调用链路都亲手过一遍走完这一遍之后你对SpringCloud的掌握程度会比啃一个月理论书籍深刻得多。