软件公司买服务器,和普通企业买服务器不太一样。普通企业买一台,跑一套系统;软件公司手里同时有好几个项目,每个项目至少有开发、测试、正式运行几套环境,服务器的数量会在不知不觉中翻上几倍。下面这张表是个示意,假设一家规模不大的开发公司,同时在做五个项目。
项目(示意) | 开发 | 测试 | 预发布 | 生产 |
A 企业官网外包 | — | 1 | — | 1 |
B 自研SaaS产品 | 1 | 1 | 1 | 2 |
C 客户的APP后端 | 1 | 1 | — | 1 |
D 客户的内部管理系统 | — | 1 | — | 1 |
E 数据中台项目 | 1 | 1 | 1 | 3 |
合计(台) | 3 | 5 | 2 | 8 |
五个项目,各自配了几台机器,加起来已经十八台。这只是假设的例子,实际中不少环境可以共用,但它说明了一件事:软件公司采购服务器,难点不在单台怎么选,而在这么多环境怎样划分、怎样管理,以及项目交付之后怎样妥善处理。
我们是做云主机和服务器租用的,这篇文章想站在采购方的角度,聊聊软件公司在研发基础设施上需要考虑的事情。文中会提到恒讯的产品,但放在了后面单独一节,前面的内容对任何服务商都适用。
项目的排期总是交叉的。任何一个时间点,团队里都有项目在开发,有项目在测试,有项目在等客户验收,还有已经上线的在运行,几类需求叠加在一起,对服务器的压力就不是单个项目能比的。
不同客户的项目,通常要求独立部署:代码和数据涉及保密,合同里也常有条款要求环境隔离,不能和别的客户混放。开发、测试和生产三类环境的用途不同,对稳定性的要求也不同,开发环境可以随时重来,生产环境一出问题,影响的是客户的业务。
项目交付并不意味着服务器可以关掉。外包项目验收之后常常还有维保期,SaaS产品则是持续运行。团队如果分散在不同城市,还需要统一的代码仓库、测试环境和构建服务器,否则很容易出现“在我这里是好的”这类扯皮。随着项目数量、数据量和构建次数增加,计算和存储需求会一路上升,构建任务多了,还会出现排队。
以一次普通的代码改动为例,看看它会途经哪些环境。
开发人员先在开发环境里写代码、调试功能、联调接口,这里可以随意折腾,出了问题影响的只是自己。代码提交到Git仓库之后,CI/CD环境接手:拉取代码、构建、跑自动化测试,构建失败就打回去。通过之后,部署到测试环境,由测试人员做功能测试、集成测试,必要时做性能验证。
预发布环境的意义不一样,它要尽可能模拟正式运行的环境,包括系统版本、配置、数据量级和网络结构,用来发现“测试环境没问题,一上线就出事”这类问题。最后才轮到生产环境,承载客户真实的访问和业务数据。
贯穿这条链路的,还有数据库环境。不同项目、不同环境各有自己的数据库:测试库用模拟或脱敏的数据,生产库要有备份和严格的权限。数据库是最容易出事故的一环,值得单独规划。
不是每个项目都要走满这几步,小项目可能只有测试和生产,大项目则可能再加灰度环境。重要的是,每个环境的用途和边界都是清楚的。
能省则省的想法人人都有,把测试和生产放在同一台机器上,看起来能省下一台的钱。这种省法,往往要在出事之后加倍还回去。
测试时运行的脚本、打开的调试开关、占用的端口和资源,都可能直接影响同机的生产服务,一次误操作重启,就是一次线上事故。测试数据和生产数据混在一起,也容易误删误改真实数据,或者反过来,测试产生的脏数据流进了生产报表。
不同项目依赖的运行时和库版本常常不一样,比如不同版本的JDK、Node或Python,同机部署容易互相冲突,升级一个,另一个就坏了。权限也是个问题:开发人员为了调试,需要较大的权限,生产环境则应当严格收紧,混用就意味着没法分别设置。
最后是回滚和排查。生产环境需要单独的稳定性保障,一旦环境边界不清楚,出问题时很难判断是哪次改动造成的,版本回滚也无从下手。
环境的边界,要靠主机、网络和账号层面的隔离来保证,不能靠团队成员的自觉。
两者没有绝对的优劣,要看场景。下表按常见的几种情形作了归纳,仅供参考。
场景 | 倾向的选择 | 说明 |
临时的开发、测试环境 | 云主机 | 开通快,随用随开,项目结束后可按产品规则调整或回收,避免长期占用成本 |
小规模项目的生产环境 | 云主机 | 资源需求不大,规格可以升级,运维门槛较低 |
对硬件独享和性能一致性要求高的数据库、构建集群 | 可评估物理服务器 | 整机资源由自己独享,不受同一宿主机上其他实例的影响;采购周期和扩容方式与云主机不同 |
长期稳定、负载较高的核心业务 | 两者都可评估 | 需要按长期使用来核算成本,同时考虑扩容的灵活程度 |
代码仓库、制品库、构建服务等公共基础服务 | 视规模而定 | 小团队用云主机即可,构建任务繁重的团队可以考虑更高规格,甚至物理服务器 |
云主机的长处在于部署快,可以按项目开通;物理服务器的特点是硬件资源由自己独享,适合对性能一致性要求高的场景。两者在交付周期、升级方式和计费方式上也有差别,采购前要向服务商问清楚。
也可以混合使用,比如开发和测试环境用云主机,生产环境中最核心的数据库用物理服务器。混合使用时,要评估两类服务器之间的网络访问延迟,同一区域内通常更有利,具体以实际测试为准。总的来说,选择不应只看价格,要看项目对稳定性、性能一致性和灵活性的要求。
CPU。开发和测试机以日常调试和运行为主,要求不高;构建服务器是例外,编译、打包、跑测试可以并行利用多个核心,核数多,构建就快。生产环境则按并发请求来定。
内存。要同时容纳开发工具、应用服务和数据库。Java一类的技术栈,构建阶段占用的内存常常比运行阶段更高;同一台机器上跑多个容器时,占用要累加计算。
磁盘。源代码和依赖本身不大,但构建产物、缓存、Docker镜像和日志会不断累积,没人清理的话,最先被写满的往往是磁盘。生产数据的容量另外规划。
磁盘I/O。持续集成任务会大量读写小文件,数据库对读写延迟又很敏感,两者放在同一块盘上会互相拖累。带宽。拉取依赖和镜像、上传部署包、客户访问测试和生产环境,都要占用带宽,跨境项目还要特别关注网络质量。
IP。测试环境要不要公网访问?给客户做验收时通常需要,这时可以设置来源IP白名单,而不是对所有人开放。生产环境按服务需要配置,并提前了解后续新增或更换IP的方式。
首先是按项目划分资源和访问权限:每个项目一组服务器,项目成员只能访问自己项目的机器。其次是统一命名和资产管理,让服务器的名字一眼就能看出用途。
命名可以采用“项目简称-环境-角色-序号”的格式,比如 crm-test-app-01、crm-prod-db-01,一看就知道属于哪个项目、哪个环境、承担什么角色。资产台账里还应记录负责人、到期时间、客户归属和备份情况。
不同客户的项目使用独立环境,保密要求、费用核算和日后的移交都会更清楚。每月或每季度统计一次CPU、内存、磁盘的使用率,长期偏低的缩小规格,长期偏高的提前扩容。
闲置的测试环境,是最常见的浪费来源:项目验收后留下的测试机,临时拉起的演示环境,没人记得关。可以设置到期提醒,谁申请,谁负责续期或释放。对长期运行的项目,则要建立独立的运维计划,有自己的监控、备份、补丁和值班安排,不能挂在研发团队名下“顺便照看”。
代码托管在Git仓库里,无论是自建的还是第三方的,提交或合并代码都可以触发流水线。构建任务建议放在单独的构建机上,可以是一台独立的云主机,避免它抢占测试或生产环境的资源。一条典型的流水线大致如下。
提交代码 → 自动构建 → 自动化测试 → 部署测试环境 → 集成测试 → 部署预发布 → 人工确认 → 部署生产
构建环境要干净、可复现,依赖的版本要固定;测试环境可以用脚本或容器按需拉起、用完销毁。每次发布都应该对应明确的版本号,比如Git标签,部署脚本也要纳入版本管理,并且尽量做到重复执行结果一致。手工登录服务器去改配置,是最常见的隐患之一。
容器化适合项目多、运行环境差异大的情形,它能统一环境,减少依赖冲突。同时也带来镜像管理、编排、网络和存储方面的新问题,规模小、结构简单的项目,未必需要。是否采用,要看团队的技术储备和项目实际需要。
回滚要提前准备:保留上一个版本的构建产物,出问题时能迅速切回。数据库结构变更的回滚比代码回滚难得多,需要事先设计好兼容方案,比如先新增字段,等稳定之后再删除旧字段。
部署账号遵循最小权限原则,密钥和令牌不要写进代码仓库,放在环境变量或专门的密钥管理里,人员离职、项目移交时及时更换。项目上线之前,在预发布环境做一轮冒烟测试,检查配置、连接和关键流程,通不过就不上生产。
监控要覆盖CPU、内存、磁盘和网络,也要覆盖服务进程、端口和接口响应,并且告警要有人接收,否则告警等于没有。日志要集中收集,设置保留周期,避免写满磁盘,错误率、5xx之类的异常要触发告警。
数据库备份要明确频率和存放位置,并验证过恢复;平台侧提供的存储保护,不能代替企业自己的独立备份。系统补丁和依赖库的安全更新,先在测试或预发布环境验证,再选窗口期更新生产环境。网络访问控制方面,只开放必要的端口,管理端口限制来源地址,数据库不对公网开放。
出了故障,要有固定的排查顺序,比如网络、系统、应用、数据库,逐层缩小范围,同时保留好日志和监控数据,故障之后做复盘。
恒讯科技业务涵盖云主机、全球服务器、CDN和网络专线,服务行业中包括软件开发。和研发基础设施关系最紧的,是云主机和物理服务器这两类产品。
云主机适合开发、测试和中小规模的正式环境:官网上提供多种实例规格,可以选择CPU、内存、云盘和带宽,配有Web控制台和API管理,团队可以统一开通和管理多台机器。物理服务器则面向对独享硬件资源和性能一致性要求更高的场景。具体有哪些规格和节点,请以产品页和顾问的确认为准。
不同项目、不同环境对资源的要求不同,我们建议先把环境清单理出来,就像文章开头那张表,再分别规划:测试环境可以用较小的规格,预发布环境尽量接近生产,生产环境根据项目的并发和数据量单独配置。这样不会为了所有环境一律配高而浪费,也避免生产环境被测试环境拖累。
云主机有北京、辽宁、江苏、香港、广东等位置,另有全球服务器资源。做跨境项目的团队,可以结合客户所在的市场,与我们讨论香港及其他海外节点的部署,具体可提供的地区、规格和线路,以产品页和顾问确认为准。团队分布在不同城市的话,也可以告诉我们开发人员的所在地,一起评估访问各节点的网络连接情况。
项目交付、业务增长之后,资源需要调整,购买前请向顾问确认升级的方式、是否需要重启,以及费用如何计算。我们不建议把价格低当作选择开发服务器的唯一依据,规格是否匹配项目,升级是否方便,出了问题有没有人响应,往往比单价更影响交付。咨询时,把环境清单、各项目的技术栈、预计并发量和数据量、团队所在地和客户所在地发给我们,会比较容易给出有针对性的建议。
问 开发环境和生产环境需要分开购买云主机吗?
答 建议分开,至少使用不同的主机,并在网络和账号上隔离。预算有限的时候,测试机可以先从较小的规格起步,用到不够再升级。
问 多个软件项目可以共用一台云服务器吗?
答 开发和测试阶段,可以通过容器、不同的端口或虚拟主机让多个项目共用一台,只要注意资源争抢。生产环境,尤其是不同客户的项目,建议各自独立,原因是资源隔离、权限和数据隔离,以及合同中可能存在的保密要求。
问 软件开发服务器需要多大内存?
答 没有统一的数字,取决于技术栈、是否与数据库同机以及并发情况。要留意构建任务的内存占用往往比运行时更高。我们的建议是先按所用技术栈的推荐配置起步,再观察峰值占用,逐步调整。
问 云主机可以安装Docker吗?
答 一般的Linux云主机可以安装Docker,但能否使用还和系统版本、虚拟化方式以及内核支持有关。采购前向顾问确认一下运行环境的要求,会比较稳妥。部署容器之后,内存和磁盘的规划也要相应留出余量。
问 软件项目交付后服务器如何移交?
答 最省事的方式,是一开始就以客户的名义购买,账号归客户所有,开发公司只获得必要的权限。如果由开发公司购买,则需要事先确认账号或资源能否转移,转移规则以服务商的政策为准。移交时建议附上一份清单:服务器账号和密钥、部署文档、域名与证书、备份情况、监控配置、第三方服务的密钥,以及到期时间。
问 测试服务器和正式服务器配置必须相同吗?
答 不必完全相同,但系统版本、数据库版本和依赖环境要保持一致。如果要做性能测试,则需要接近生产的配置,否则测出来的结果没有参考意义。预发布环境最好尽量贴近生产。
如果你的团队正在评估服务器方案,不妨先像文章开头那样,列一张项目与环境的对照表,再来和我们聊配置。我们可以据此一起梳理,哪些环境适合云主机,哪些需要进一步评估物理服务器,具体方案以实际产品和咨询确认为准。
Copyright © 2013-2020. All Rights Reserved. 恒讯科技 深圳市恒讯科技有限公司 粤ICP备20052954号 IDC证:B1-20230800.移动站


