ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从业务需求出发,谈谈后端技术栈的搭配逻辑

从业务需求出发,谈谈后端技术栈的搭配逻辑 一个最简单的道理你的后端技术栈是由业务需求定义的而不是由招聘市场的热度或技术领袖的演讲定义的。但我见过太多团队拿着最流行的语言和框架做着最普通的业务最后却陷入性能调优和复杂度管理的泥潭。他们不是不懂技术而是忘了问自己这个业务到底需要什么技术选型不是选择题而是推导题。你推导的起点错了后面所有答案都只是精致的错误。先给业务“画像”再谈技术选型很多技术栈讨论一开始就错了因为它们从“某个框架好不好”开始而不是从“我的业务本质是什么”开始。业务才是技术栈的唯一输入源。你需要回答几个粗暴的问题你的业务是面向用户的互联网应用还是面向内部管理的系统是强一致性的金融交易还是允许最终一致的社交feed是日均请求几百次还是每秒几万次这些问题的答案直接划定了技术栈的可行域。我习惯把业务分成几个粗糙的类型CRUD型业务核心是管理数据的增删改查技术栈越简单越好一个Web框架加一个数据库就够复杂领域业务比如物流、电商订单、财务结算核心是领域逻辑和状态流转需要强大的类型系统和领域建模能力高并发读业务核心是缓存、异步、CDN和读写分离数据密集型业务比如推荐、搜索、报表核心是计算引擎和数据管道。如果你的业务是混合型那么你需要的是分层组合而不是强迫一个框架去满足所有需求。这里有个残酷的教训当你的业务只是一个简单的进销存系统时选择微服务架构就是给自己挖坟。微服务解决的是组织复杂性和需要独立扩展的问题而不是业务复杂度的问题。很多团队用微服务仅仅因为简历上写着“分布式经验”。结果呢每个服务都需要部署、监控、日志、链路追踪运维成本呈指数级上升。业务没有到那个量级单体应用读写分离比什么微服务都靠谱。业务量级决定架构的复杂度阈值技术栈的复杂度必须严格匹配业务的发展阶段。早期业务的第一原则是“快”快速验证商业模式快速上线快速迭代。这时候你需要的是一门你团队最熟悉的后端语言一个全功能的Web框架一个关系型数据库PostgreSQL或MySQL一个对象存储完了。什么消息队列、Redis缓存、Elasticsearch、Kubernetes都等有真实需求再说。我见过最荒谬的场景一个刚上线的小公司用户量不超过一千却已经上了Kafka、Flink、Spark还搞了K8s集群理由是“为了未来发展”。这种未雨绸缪本质上是技术恐惧而不是技术规划。未来的业务形态是不可预测的你现在搭建的所谓“高可用架构”很可能在业务转型后变成一堆废铁。而且早期引入高复杂度技术栈会拖慢迭代速度错过战场上的窗口期。当业务量真的大起来你会遇到具体的瓶颈。第一个瓶颈通常是数据库连接数解决方式是增加连接池、做读写分离、加Redis缓存。第二个瓶颈是单表数据量过大解决方式是分库分表或引入分布式数据库。第三个瓶颈是核心业务链路延迟过高解决方式是拆分服务把非核心逻辑异步化。你的每一步架构演进都应该是被真实业务指标逼出来的而不是被技术焦虑推着走的。同时你要明白一个道理业务量级不是线性的。从1000并发到10000并发不只是加几台机器的事情可能需要换掉整个中间件栈。但从100万用户到200万用户可能只是加机器的过程。搞清楚你的业务到底处在哪条增长曲线上决定了你要提前多少步做准备。数据一致性是硬约束不是口味问题后端技术栈最关键的分水岭不是编程语言而是数据一致性的要求。如果你连自己的数据都搞不定再花哨的技术栈都是空中楼阁。很多业务根本不需要分布式事务因为一个简单请求可能只更新一行数据用关系型事务就足够了。但有些业务比如订单与库存、转账与日志、报名与名额扣减它们天然需要跨表、跨服务的一致性。这时候你面临两种选择要么用强一致性的技术方案比如关系型数据库的分布式事务、或者PostgreSQL的SSI隔离级别要么用最终一致性的方案比如消息队列加本地消息表、Saga模式。选择的关键在于你的业务能不能接受短暂的中间状态支付业务不能但订单超时关闭可以社交好友关系通常可以但库存扣减大概率不可以。我特别看不惯一种风气凡是遇到数据一致性问题就下意识地引入分布式事务框架。分布式事务是最后的手段不是第一选择。绝大多数业务场景只要你能把数据操作收敛在同一个数据库内用普通事务就能解决。而分布式事务框架比如Seata、TCC它带来的性能损耗、接入复杂度、调优难度会把你拖入一个深不见底的坑。好的后端架构是在业务逻辑设计阶段就把数据尽量内聚而不是在技术栈上强行支撑分散的事务。你看那些优秀的系统往往在业务流程上做了巧妙地算计把需要强一致的操作放进一个本地事务把可以异步的操作放进消息队列从而让整个系统的技术栈保持简单。团队能力是技术栈的天花板这一点传统技术选型讨论经常忽略但它往往决定成败。再先进的技术栈如果团队没有人真正掌握那就是挂在墙上的装饰品。一个由五年Java工程师组成的团队你让他们去写Rust即便Rust更酷、更安全首月的交付速度也会慢得吓人。而一个由Node.js高手组成的团队你让他们去用Go他们大概率会写出像Java一样繁琐的Go代码。说句不好听的技术选型其实就是选“团队能驾驭的最大公约数”。这里的“驾驭”不是指“会写hello world”而是指能熟练应对生产环境下的各种问题——CPU飙高、内存泄漏、连接池耗尽、GC停顿、网络抖动。你选一门冷门语言出了问题连Stack Overflow上都没有答案只能自己硬啃源码。你选一个没人用的框架想招人都招不到团队里走一个核心成员整个项目就瘫痪了。当然这不意味着团队永远只能用自己会的东西。团队需要“学习成本”的预算但是要控制在合理范围内。如果你要解决一个业务难题比如实时数据聚合而团队没有合适的现成技术那么引入一个新的流处理框架就是合理的。但要遵守一个原则一次只引入一个新技术让团队有足够的时间消化。不要同时上微服务容器编排消息队列新的数据库这样团队会彻底迷失在技术切换的混乱中业务交付遥遥无期。另外你还要评估团队的技术偏好很多人低估了这一点——让一群热爱Python的人去写Java即使性能更好但士气低落带来的生产力损失往往比性能收益更大。生态与运维成本比框架炫技更重要很多人在选技术栈时只盯着语言本身的特性比如“Go的goroutine比Java线程好”“Node.js的事件循环异步性能高”。但他们忘了后端系统是一个完整的生态而生态的力量远超某个语言特性。你要选的不是一个语言而是一个能支撑你业务整个生命周期的全家桶。拿Java生态说它可能不够优雅但Spring Boot、Spring Cloud、MyBatis、Netty、很多中间件都是社区久经考验的。你遇到的大多数问题都能找到解决方案。Go生态虽然没有那么庞大的框架体系但它好在部署简单、并发模型清晰非常适合网络服务和网关层。PHP虽然被很多人瞧不起但它做Web CRUD业务的速度至今没有几个语言能比。技术选型的正确姿势是看这个“生态矩阵”对你的业务场景覆盖度如何而不是看某个语言的跑分高低。运维成本是另一个容易被低估的维度。你需要的不是“能跑”而是“好维护、好监控、好部署、好扩容”。一套复杂的分布式系统如果每星期都需要一个资深后端工程师手动处理问题那它本身就是业务增长的瓶颈。选择技术栈时你必须考虑这个技术有没有成熟的监控告警方案有没有方便的可观测性SDK有没有自动化部署工具链比如在Kubernetes上Java应用的内存配置、启动时间、OOM行为就比Go要麻烦得多。如果你的团队没有专职运维那么尽量选择“云托管式”的数据库和中间件比如用云数据库替代自建MySQL用云Redis替代自建Redis。运维的复杂度应该转移给云厂商或专业的中间件服务而不是压在自己团队的背上。技术栈是动态演进的不是一锤定音我必须提醒你今天的选择不是永远的选择。业务在变技术在变团队也在变。技术栈是一个活体它需要随着业务的演进不断重塑自己。早期你用一个Node.js MongoDB做原型速度快但当你发现事务需求越来越多、数据关系越来越复杂时你就要考虑迁移到PostgreSQL或者增加一个关系型数据库作为辅助。这不是打脸而是业务驱动的自然结果。一个健康的后端技术栈应该具有“可替换性”。核心业务逻辑要尽量与技术栈解耦比如你用了某个框架的ORM那不要让ORM的模型直接渗透到业务层你用了某个消息队列那不要在你的代码里直接依赖那个消息队列的API。哪怕做不到完全解耦也要在架构层面划分出清晰的边界。这样当你需要替换组件时可以做到局部调整而不是推倒重来。另外一个动态演进的原则是不要引入超出当前问题域一个级别以上的复杂度。比如你的服务还不存在性能问题就不要引入多级缓存和异步削峰你的数据量还不到一千万行就不要讨论分库分表你的团队还不到十个人就不要想着拆分中台。复杂度不是越多越好而是越少越好——因为每一份复杂度都是未来修改时的成本。还有一点很重要业务需求本身是会变化的技术选型应该保留对变化方向的开放性。比如如果你的业务大概率会走向高并发、高扩展性那么早期选择Go或Java比选择Python或Ruby更有优势如果你大概率会走向数据密集型业务那么选择带有丰富数据流处理生态的比如JavaFlink、Kafka Streams比选择Node.js更有前景。你虽然不能预知未来但你可以避免走在一条很难转向的路上。回到业务本质的那张白纸如果你现在正面临技术栈选择的纠结不如把自己放空回到底层逻辑你的业务最核心的诉求是“快速验证”还是“高可靠性”是“低成本”还是“极致性能”是“团队易上手”还是“长期演进”这些问题没有标准答案但一旦你诚实地回答了它们技术选型就不会再迷茫。举几个典型的搭配逻辑。比如一个内容社区类业务核心是用户生成内容、feed流、搜索。那么后端技术栈可以围绕Node.js或Go起步搭配PostgreSQL用户和帖子数据 Redis热点缓存 Elasticsearch搜索 云对象存储。这套组合开发快、运维简单足以支撑百万级用户。当用户量和互动量上来后再引入消息队列做异步通知引入画像系统做个性化推荐。而一个企业级ERP业务核心是复杂业务规则、流程审批、数据报表。这类业务最好选择Java Spring Boot MySQL或PostgreSQL理由是你需要强大的事务管理、成熟的权限框架、稳定的报表库。你会需要工作流引擎而不需要太多高并发组件。相反如果是一个物联网设备接入平台海量轻量级设备连接、数据上报、指令下发那么Go就比Java更合适因为并发连接数极高且单连接逻辑简单Go的goroutine模型能够轻松应对配合MongoDB或者InfluxDB存储时序数据再加上Kafka做数据缓冲这就是与技术场景匹配的搭配。永远不要为了技术而技术也不要用“技术前沿”来掩饰业务洞察的肤浅。那些真正的架构师不会上来就讨论微服务、K8s、Service Mesh他们会先问你的业务增长曲线什么样你的团队能驾驭什么你的数据一致性要求是什么你的运维资源有多少你的业务是否有季节性洪峰你的时间预算是三个月还是三年这些问题弄清楚之后技术栈自然会水落石出。技术栈的搭配逻辑表面上是各种语言和框架的组合本质上是一种“业务设计”。你在选语言的同时也在选择团队的工作方式、系统的演进路径、甚至公司的商业命运。所以下一次当你又想去追逐某个新技术时请记住这句话后端技术栈最好的样子不是让业务去迁就技术而是让技术默默支撑业务像空气一样自然。当没有人再讨论“为什么选这个技术”的时候说明它已经对了。技术最大的成功是成为业务背后的无名英雄而不是站在台前闪闪发光。你最终的目标是让技术栈变得无聊且稳定——稳定到没有人每天都想重构它无聊到它已经融入到业务的日常呼吸里。那种状态才是后端技术架构的终极境界。
返回列表