作者简介:陈辉,曾任职 Google、阿里巴巴、Facebook,现任杭州映兔科技 CTO,创业中。
从公司成立第一天起,我们就以 Google 的技术标准要求团队,鼓励使用新技术、鼓励重新造轮子、鼓励全栈,同时因为业务涉及视频、电商、社交多个领域,我们在创业环境下对微服务、DevOps、自动化测试和部署、搜索、交易、数据监控、直播技术方面的技术选型积累了一定经验。非常高兴能把这些经验分享给各位同在创业的小伙伴。
我们的技术选型原则
技术选型对创业公司至关重要,好的选型会让你少走弯路,产品更快推向市场,比竞争对手更快赢得客户,获得更多融资,有更多资源投入产品研发和市场扩展 … 如此往复形成良性循环。相反,每一个错误选型都会带来巨大的技术债务,我知道一些创业公司把 demo 时的选型一直用到 A 轮甚至 B 轮,然后不得不停下业务花几个月时间去重构整个系统。
可以说,对初创团队的技术 leader,最重要的事情就是选择正确的技术体系。
下面是我们技术选型的三个原则:
一、利用好创业公司技术选型的后发优势
大公司的基础设施往往超过 N 年没有更新,在建立之初可能是前沿的,但很多已经远落后社区,而且因为所谓的稳定性和技术栈的统一,不允许团队使用最新的技术。创业了,就打开了所有的禁忌,do what the fuck you want,只要你精挑细选,总有一款工具是最适合你的。工具不仅能提高工程师的生产力,工具更定义了你的工作模式,选择你的工具,而不是被工具选择。
这对从大公司出来的技术 leader 尤为重要,把之前 BAT 的那套放在脑后,重新出发,你的面前就会打开一扇宝库大门。
二、第三方付费服务很多不靠谱,小心绕开雷区
花钱买的未必就好,有时候花钱买来的是坑,还得自己填。第三方服务,小的不稳定,大的没法订制,提个需求都可以排到两个月后了。这里的名单很长,特别留心那些给无线开发者提供的服务,很多不靠谱。
解决方案:让第三方服务成为可动态配置的组件,多个服务方互备,配置而不集成。比如我们的 SMS 推送服务就使用了多个服务互备,极大降低了短信丢失率,另外可以通过配置随时替换服务方,降低了对单一服务方的依赖。
三、自力更生、重造轮子
因为轮子是你的车最重要的组件,同时没有哪个轮子合适装在你的车上,你的车是独一无二的喷气火箭战车。我不是说你需要重写 MySQL 或者 CDN,而是把你的业务系统中除了网络和存储的组件自己开发,从交易到账号到搜索到推送系统,网络和存储交给公有云并克制在这块造轮子的冲动。
你应该重写 leancloud,重写 fir.im,重写 elasticsearch,而且要在两周内完成。如果你对此嗤之以鼻,说明你没找到最优秀的工程师,或者是他们的野心还没有被发动。相信我,这不难,我们已经这样做了而且比使用外部服务更好。
创业,要有“无论什么技术我们都可以实现而且比其他人做的更好”的信念,这是创业赋予你最大的自由,抓住这个自由。
我们选择的技术
下图是我们后台系统选择的一部分技术栈:
一、Go 语言
我经历过的两家公司, Google 主要用 C++,阿里用 Java。前者是一种存在天生设计缺陷的语言,而且 C++ 的开发效率真不算高,即使是对 Google 这样的工程团队,也做了 Style Guild 来规避 C++ 存在的雷区。 而 Java 过于臃肿,缺乏原生的多线程支持,运行环境庞大不适合容器化微服务,如果你给 Java 程序打过 docker 包就知道了,动辄上百兆的运行时。
从创业的第一天,我们选择 Go 作为后台系统开发语言,现在看来是我们做过的最好的决定之一。Go 的优点包括:原生支持多线程编程,可编译为 standalone binary 无需运行时环境(docker 镜像一般 10 几兆就搞定了),自带格式化工具能够统一团队的编程风格,极适合写微服务,而且学习上手快,Java 或者 C++ 程序员只要一个星期就可以达到熟练运用的水平。
创业以来我们用 Go 从头实现了整套后台系统,包括 RTMP 直播服务器、用户体系、交易、IM、搜索、监控、小二后台,我们甚至用 Go 写机器学习代码和机械臂控制程序(我们在用的 Google 的tensorflow 最近也加入了 Go 语言支持) … 实践证明 Go 完全可以胜任所有的后台开发工作,而且有极高的效率和工程实现质量。
二、Kubernetes
我们是微服务的坚定践行者,微服务技术的核心是容器编排系统,现在最流行的三个容器编排系统是 Kubernetes,Mesos,Swarm。
通过比较我们选择了 Kubernetes(简称 k8s),因为 Kubernetes 的设计最吸引我们,有 Google 支持,社区活跃度和发展前景俱佳。我们整个后台系统基于 Kubernetes,并且已经完全微服务化,有 80 多个微服务数百个容器在运行。
我们在实战中使用 Kubernetes 的几点经验如下。
1、二进制版本和配置版本要做分离,且代码化
微服务的配置 yaml 文件 checkin 到 git 代码库,而且做 binary/config 分离,分别控制二进制和配置环境的版本,所有的线上部署的改动都在代码中反映出来。举个 k8s 中微服务配置的例子,如下图。
这是我们一个微服务的 deployment 文件,我们用 git 的版本号做 docker 镜像的 tag(jenkins 自动打包后加上去的),docker 镜像里只包含 binary 文件,配置文件通过 configmap 的 volume mount 为容器内的一个目录,而且配置文件也做了版本号控制,数据库密码等不走代码,而是由集群管理员手工输入为 kubernetes 的 secret,不留任何记录,从而避免了敏感信息的泄露。
2、集群管理
考虑混合云上多 k8s 集群的管理需求,我们用 zone 来标识不同数据中心的 kubernetes 集群,zone 由三个字母标识,如下图
通过三字母标识法,我们将混合云部署统一化,极大方便了代码和文档中的服务标识。
3、使用 Namespace
Kubernetes 的 namespace 极有用,我们用 production namespace 指代生产环境,staging 指代预发,kube-system 指代集群系统级别的服务比如 DNS、prometheus 监控和报警等。
另外 k8s 也支持通过 namespace 的 node selector 来指定某个服务需要运行在哪类机器节点上,这样就可以将预发和生产环境运行在不同的机器上,做到不同环境的资源隔离。
4、基于 DNS 的自动化服务注册、发现和负载均衡
通过 skyDNS 就可以将一个服务的分布在不同服务器上的 instance 命名归一化,比如通过调用 ama-server.production.svc.k8s:20001 就可以将调用请求自动路由到某个服务节点上,调用端不需要关心服务是怎么部署的,服务注册和服务发现自动完成。
关于 Kubernetes 和微服务化还有很多细节,如果有机会再分享给大家。
三、Prometheus 和 Grafana 监控系统
如果你知道 ELK,那 Prometheus+Grafana 实现了一套更为优秀的数据监控系统。比如我们在 gRPC 服务的 /metrics 下添加了类似下面的指标来监控 RPC 性能:
然后 prometheus 会根据 kubernetes 的配置自动找到这些 metrics,我们设置这样的语句进行计算
最后在 Grafana 里通过这样的界面展示出来:
如果你在 Google 工作过会心中窃喜,这不就是 Google 的 Borgmon 嘛!对的,Prometheus 就是由一位 xoogler 工程师写的,参考了 Google 内部数据监控系统的设计。
这套体系和 ELK 相比较轻,且非常容易扩展,我们写了几个模块把服务日志和前端访问记录融合在一起做分析,同时 Prometheus 指标描述能力非常强大几乎可以做任何运算(事实上这种语言是图灵完备的)。
四、gRPC
集群内部服务间通讯我们用 Google 开源的 gRPC,最近出了 1.0 稳定版。你可能听说过无数个基于 protobuf 的 RPC 实现,请放弃它们转用 Google 自己的 gRPC 吧。
五、Github
我们用 Github 做代码仓库,她的用户分组和权限管理很有用,而且支持通过 webhook 提醒 Jenkins 完成后续的持续集成工作。
使用 Github 的另一个好处是,当你想把一个内部项目开源时,只要点几个按钮就可以了,后续开发流程不变,无缝衔接。
六、Phabricator
Facebook 的一款项目管理工具,我们用它做文档中心和代码审查工具。
七、Bearychat
非常好用的团队沟通工具,好到让你想放弃邮件沟通,因为这比写邮件快多了。我们建了几十个频道,大家分组针对特定话题做深入讨论。而且 bearychat 支持机器人,可以把各种系统通知平滑衔接进来,ChatOps 的利器。
八、Jenkins
我们在 Jenkins 上做微服务和 iOS/Android app 的测试和打包,可以说 Jenkins 是整个持续集成的枢纽,任何的代码改动都可以从这里触发后续行为,从 docker 自动打包,到推送 bearychat 消息提醒,到服务或 app 发布等。
九、Bugtags
付费服务,帮助我们组织测试环节的部分工作流程,避免上线前遗漏 bug fix。
十、Whiteboard
就是白板啦!我们将任务分解为原子 task,子团队纵切(产品、UED、前端、后端),任务状态横切(待开始、进行中、blocked、完成),不同迭代版本使用不同颜色,每日晨会更新,进度一目了然,“石器时代”的技术选型还是那么有效 :)
最后的话
因篇幅原因一些更细的内容比如微服务的搭建和配置无法在这里展开,如果有机会继续分享一些好玩的“黑科技”给大家,也欢迎关注我们的公众号“映兔技术团队”。谢谢!
----- The End -----
大家可能还感兴趣:
谢谢。