Skip to content

常见技术栈

打开任何一个稍微复杂的 Web 系统的技术架构图,你会看到一堆名字:Vue、React、FastAPI、Spring Boot、MySQL、Redis、Kafka、Nginx、Prometheus、Grafana……第一次看很容易懵——这么多东西都是干嘛的?其实它们不是平铺在一起的工具清单,而是各自占着系统的某一层:页面、接口、数据、入口、发布、观测。

理解技术栈的关键是先看每个组件在系统里站哪一层——页面谁来渲染、接口谁来提供、数据放在哪里、异步任务怎么跑、外部请求从哪里进来、出问题去哪里看。把这些位置关系理清楚,再看到陌生技术栈就不会晕。

一、页面层(前端)

前端负责页面结构、样式、交互和接口调用。浏览器最终加载的东西就是 HTML、CSS、JavaScript、图片、字体这些。

类型主流选择在什么位置
基础能力HTML、CSS、JavaScript浏览器原生支持,所有前端最终都跑这三样
框架Vue、React、Angular复杂交互、组件化开发,简化 DOM 操作
构建工具Vite、Webpack把源码(Vue/JSX)编译成浏览器能跑的纯 JS
UI 组件库Element Plus、Ant Design、Naive UI表单、表格、弹窗、导航这些现成组件

国内内部平台 Vue 用得多一些(上手快、生态完善),React 在大厂和海外项目里更主流。页面特别简单的时候,原生 HTML/CSS/JS 也够用,不一定非要上框架。前端构建之后产出的静态文件,可以放在 Nginx、对象存储(OSS/S3)或者 CDN 上。

前端和后端的连接点是 HTTP API。前端代码通过 fetchaxios 这种工具请求 /api/users/me/api/tasks 这类接口,后端返回 JSON,前端拿到 JSON 渲染页面。这就是前后端分离的核心交互模式。

二、接口层(后端)

后端负责 HTTP 接口、业务逻辑、认证权限、数据库读写、调用外部系统。用什么语言写都行,常见的几种组合:

语言主流框架适合什么场景
JavaSpring Boot、Spring Cloud企业业务系统、大型微服务体系(国内最主流)
PythonFastAPI、Django、Flask运维平台、内部工具、数据处理、AI 应用
Go标准库 net/http、Gin、Fiber云原生组件、API 网关、运维工具(性能好)
Node.jsExpress、NestJSBFF(服务于前端的后端)、轻量 API

语言选择往往跟团队背景关系最大,而不是技术本身好坏。Java 生态最完整、招人也容易,所以大公司核心业务基本都用 Java;Python 写内部工具和数据处理特别快,运维平台和 AI 应用多用 Python;Go 编译出来是单个二进制文件,部署简单、性能好,云原生组件(K8s、Docker、Prometheus 全家桶)几乎都是 Go 写的;Node.js 跟前端 JavaScript 同语言,前端团队能顺手写后端。

注意一个事:一个后端服务可不只是几个路由函数。真正生产级的后端还要处理配置管理、数据库连接池、HTTP 客户端超时、统一错误返回、权限拦截、日志中间件、优雅关闭、健康检查、metrics 暴露……这些"非业务"代码往往比业务代码还多。

三、数据层

数据库保存系统的所有状态——用户、订单、权限、审计、配置、任务记录,都要落到某种存储里。根据数据特性选不同的存储:

类型主流选择适合存什么
关系型数据库MySQL、PostgreSQL用户、订单、权限、审计、配置这种结构化数据
文档数据库MongoDB字段变化多、结构不固定的文档型数据
缓存/键值Redis热点数据、会话、计数器、分布式锁
搜索引擎Elasticsearch、OpenSearch日志检索、全文搜索、海量数据分析

国内传统 Web 和大部分业务系统 MySQL 用得最多——稳定、生态成熟、运维资料多。PostgreSQL 在复杂 SQL、JSON 字段、GIS 地理数据、扩展能力上比 MySQL 强,最近几年用得越来越多。MongoDB 适合"文档型"数据——比如一篇文章有标题、正文、标签、评论这些,字段可能动态变化,用关系型数据库建表很麻烦,用 MongoDB 直接存 JSON 文档就特别顺手。Redis 几乎是缓存的标准选择,也经常顺手用来做会话存储、限流计数、分布式锁。

数据库选型不只看"能不能存",还要看备份恢复方案、迁移工具、索引能力、权限模型、监控生态、团队熟悉程度。一个团队没人会运维的数据库,再先进也不能上生产。

四、缓存和消息队列

缓存放在数据库前面,挡住重复查询。Redis 是最主流的缓存组件,除了缓存也经常顺手做会话存储、计数器、限流、分布式锁——一个 Redis 能解决一堆小问题,所以在技术栈里几乎必出现。

消息队列放在服务之间,主要解决两个问题:让耗时任务异步执行(用户不用等)、把突发流量缓冲下来(削峰填谷)。

消息系统适合什么场景
RabbitMQ任务分发、可靠投递、传统业务队列(AMQP 协议)
Kafka日志流、事件流、大吞吐数据管道
Redis Stream/List内部小任务、轻量队列(不想到处装新组件)

一个典型场景:用户点击"导出报表",如果同步等接口生成,可能要等几十秒到几分钟,用户体验极差。改成异步——接口立刻返回任务 ID,实际生成工作扔到消息队列里后台慢慢跑,生成完了再通知用户。这种模式下要区分两个状态:"请求已接收"(接口返回成功)不等于"任务已完成"(报表真生成出来了)。排查这类问题时,要看任务状态机、队列有没有积压、消费失败和重试记录。

五、文件存储

上传的文件(头像、附件、图片)、备份包、日志归档、构建产物——这些都不适合长期绑在某台应用服务器的本地目录上。

对象存储是主流方案,按 bucket(桶)和 object key(对象键)组织文件,通过 HTTP API 访问。云厂商的对象存储(阿里云 OSS、腾讯云 COS、AWS S3)、自建的 MinIO 都属于这一类。

后端数据库里一般只保存文件元数据,不直接存文件本身:

字段干什么
文件名展示给用户的原始名字
大小、类型用于下载、预览、校验
归属对象这个文件属于哪个用户、任务、业务单据
object key对象存储里的真实路径(数据库存这个,不存文件本身)

为什么不能放本地目录?应用一旦扩成多实例就出问题——用户上传头像时请求落到 app-01,文件保存到 app-01:/data/uploads/;下次访问头像时请求被分到 app-02,app-02 本地没这个文件,直接 404。对象存储让多个实例访问同一份文件,从根上解决这个问题。

六、入口层

入口层负责接收外部请求,再送到正确的内部服务。这一层组件不少:

组件主要职责
Nginx静态资源服务、反向代理、TLS 卸载、限流
HAProxy高性能代理和负载均衡(四层/七层都行)
云负载均衡(SLB/ALB)公网入口、四层/七层转发
Ingress / GatewayKubernetes HTTP/HTTPS 入口
API 网关(Kong/APISIX)认证、路由、限流、审计、协议转换

用户报 502、504、404、证书错误、跨域错误这些事,入口层是第一处检查点。入口日志能看到请求有没有进来、转发到了哪个后端、后端返回了什么状态、耗时花在哪里。基本上 80% 的"用户访问异常"问题,从入口日志开始查最快。

七、观测和发布

可观测组件负责"看见"系统状态,出了问题能定位:

能力主流选择
指标采集和存储Prometheus、VictoriaMetrics
指标看板Grafana(几乎是标准)
告警Alertmanager、Nightingale(夜莺)
日志收集和查询Loki、ELK、OpenSearch
链路追踪OpenTelemetry、Jaeger、Tempo

发布组件负责把代码变成线上版本,管的是构建、测试、镜像、部署:

能力主流选择
代码仓库GitLab、GitHub、Gitea
CI(持续集成)GitLab CI、Jenkins、GitHub Actions
镜像仓库Harbor、云厂商镜像仓库
CD/GitOps(持续部署)Argo CD、Flux

把前面所有层串起来,一套典型的内部技术栈大概长这样:前端用 Vue 或 React → 后端用 FastAPI/Spring Boot/Go → 数据库用 MySQL 或 PostgreSQL → 缓存用 Redis → 文件放对象存储 → 入口用 Nginx 或 Ingress → 指标进 Prometheus → 日志进 Loki 或 OpenSearch → CI 用 GitLab CI 或 GitHub Actions → 镜像放 Harbor → 部署到 Kubernetes

这不是固定答案,只是一种容易理解的位置关系。换技术栈时(比如把 Vue 换 Svelte、把 MySQL 换 TiDB),先确认每一层都有对应的组件和排查入口——能跑起来是一回事,出问题能排查才是更重要的另一回事。