公司动态
创业团队技术选型7月复盘:我们做的5个正确与3个错误决策
创业团队技术选型7月复盘我们做的5个正确与3个错误决策一、选型的起点生存优先技术选型在创业团队中有一个核心约束资源极度有限。我们没有大厂的试试看预算。每一个技术决策都意味着未来6-12个月的沉没成本。7月是团队成立的第14个月。我们经历了技术栈的两次重大调整和无数小修复。回头看有些决策救了命有些决策埋了雷。本文整理5个正确决策和3个错误决策。每个决策都附上了当时的情境、选择的逻辑和后来的验证。二、五个正确决策正确决策一起步用Monolith而非微服务初期只有3个后端和一个前端。有人建议直接上微服务便于后续扩展。我们坚持选择了Monolith。18个月后的验证Monolith开发效率是微服务的2-3倍在10人以下团队。用户增长到8万DAU时才开始拆分第一个服务。拆分时数据模型清晰边界明确远比先拆分再调整容易。核心逻辑微服务的价格 运维复杂度 网络延迟 数据一致性 在验证PMF之前不要为还没到来的规模支付这个价格。正确决策二选择生态成熟的技术栈Go作为后端主语言不是因为Go是最好的语言。而是因为标准库丰富net/http、context、testing都在标准库里。部署简单单二进制文件无需运行时。招聘相对容易Go开发者在创业圈供给充足。PostgreSQL作为唯一数据库没有引入MySQL/Redis分片。理由是一个PostgreSQL能搞定的事情不要引入新组件。// 我们坚持的单数据库架构核心 type Repository struct { db *sql.DB } // 利用PostgreSQL的特性而非引入新组件 func (r *Repository) CreateTaskQueue(name string) error { // 用PostgreSQL的LISTEN/NOTIFY替代Redis pub/sub _, err : r.db.Exec( CREATE OR REPLACE FUNCTION notify_task() RETURNS trigger AS $$ BEGIN PERFORM pg_notify(task_channel, json_build_object( id, NEW.id, type, NEW.type, status, NEW.status )::text); RETURN NEW; END; $$ LANGUAGE plpgsql; ) return err }正确决策三不做性能优化做性能基准初期不优化但建立了完整的性能基准每个API的P50/P95/P99延迟。数据库慢查询的周度基线。内存和CPU的7日趋势。当性能真的出问题时有数据支撑、有方向可循。而不是感觉慢了就瞎优化。# 性能基准采集脚本简化 import psycopg2 import time from statistics import median def benchmark_endpoint(url: str, samples: int 1000): 采集API延迟分布 latencies [] for _ in range(samples): start time.perf_counter() response requests.get(url) latencies.append(time.perf_counter() - start) latencies.sort() return { p50: latencies[int(samples * 0.5)], p95: latencies[int(samples * 0.95)], p99: latencies[int(samples * 0.99)], max: latencies[-1], avg: sum(latencies) / samples, }正确决策四基础设施即代码IaC早于功能开发在MVP完成后就做了完整的TerraformAnsible自动化。这个决策当时看起来浪费了宝贵的开发时间。但后来证明是回报最高的技术投资环境搭建从半天→15分钟。故障恢复从手动→自动。新人入职第二天就能部署完整环境。正确决策五日志先行监控后补我们反常识地先做了结构化日志然后才做Metrics和Tracing。原因是对于创业团队95%的问题通过日志能定位。Metrics告诉你有问题日志告诉你问题在哪。// 结构化日志规范 type LogEntry struct { Timestamp time.Time json:ts Level string json:level Message string json:msg TraceID string json:trace_id,omitempty UserID string json:uid,omitempty Duration time.Duration json:dur,omitempty Error string json:error,omitempty Extra map[string]any json:extra,omitempty } func (l *Logger) InfoWithContext(ctx context.Context, msg string, fields map[string]any) { entry : LogEntry{ Timestamp: time.Now(), Level: INFO, Message: msg, TraceID: traceIDFromContext(ctx), Extra: fields, } l.write(entry) }三、三个错误决策错误决策一过早引入GraphQL团队在第8个月引入了GraphQL初衷是让前端更灵活地获取数据。但带来的问题远多于解决的问题N1查询问题从偶发变为常态。缓存策略从简单RESTCDN变为复杂需要分析query字符串。认证鉴权从中间件层面降级到resolver层面。3个月后回退到RESTful API损失了约120个开发人日。教训API复杂度的提升应该由用户需求驱动而非技术兴趣驱动。在DAU10万的阶段RESTful是最优解。错误决策二技术栈的求新心理在框架选择上多次犯了因为新所以好的错误。典型案例在第10个月升级到Go 1.23的一个实验性特性结果在生产环境暴露了一个编译器bug回滚了一夜。反思后的选型三个原则选最稳定的版本不选最新的版本。选团队最熟悉的不选社区最热的。选已验证的方案不选论文中的方案。错误决策三基础设施过度设计第一版K8s集群为了高可用配置了3个master5个worker。月成本8000元。但实际负载最多占用30%的资源。而我们当时的月收入才不到3万。更务实的方案应该是阶段一验证期单机Docker Compose成本:500元/月 阶段二成长期托管K8s最小化成本:2000元/月 阶段三规模期自建K8s集群成本:视规模而定我们在阶段一就上了阶段三的架构。四、技术债务的7月清理7月我们做了一次集中的技术债务清理数据库清理了23个历史遗留的无用索引写入性能提升12%。代码重构了3个最复杂的服务模块圈复杂度从平均35降到18。监控补齐了之前计划中但没做的10个核心告警规则。文档编写了架构决策记录ADR记录了8个关键决策的背景和理由。这次清理投入了2个工程师3周的时间。ROI验证后续两个迭代的开发效率提升了约20%。五、总结核心技术提炼五正确决策Monolith起步PMF前不做微服务、选成熟技术栈GoPostgreSQL、做性能基准不做优化、IaC早于功能、日志先于监控。三错误决策过早引入GraphQL复杂度过早引入、追新心理选稳定、不选最新、基础设施过度设计匹配增长阶段做架构。选型三筛法必要性解决当前问题→ 替代性有更简单方案→ 可逆性可逆且低成本。技术债清理ROI公示无用索引清理→写入12%、代码圈复杂度减半→开发效率20%。技术债是利息定期偿还比破产重组便宜。架构的黄金法则架构复杂度应与业务规模成正比。规模未到时的复杂性 纯负债。