HelloFresh 的规模每一天都在不断增长,产品在持续改进,新的想法不断涌现,供应链也已经完全实现自动化,所有这一切都让我们惊讶。另外一方面业务的持续增长也给我们带来了许多技术挑战。
今天给大家介绍基础架构中的一次 API Gateway 升级过程,这次改造的目的是给微服务铺路,使得我们将来可以更快、更灵活和更安全的方式快速迭代。
我们最近完成开发了一个新的 API Gateway(网关) [1],因此面临着将老的主 API 单体应用迁移到其下层的复杂挑战,理想情况下当然是升级过程中没有停机,迁移后可以使我们能够开发更多的微服务,并容易地将它们连接到我们的基础设施中,而无需额外的代价。
我们的 API 网关位于基础设施的上层,它每天接收大量的请求,我们在开发它时选择 Go 语言,因为它的性能、简单性和优雅的高并发解决方案。借助我们其他已有的系统或组件,使得这种改造变得简单:
我们使用 Consul 作为我们的服务注册发现工具。连同 HAProxy 一起,使我们能够解决进微服务架构的两个主要问题:服务注册发现和客户端负载均衡。
对于我们的基础设施,最有用的工具是我们的自动化工具。 在云环境中我们使用 Ansible 进行配置服务,从单个机器到处理网络、DNS、CI 服务等。 重要的是,我们团队达成了一个约定:当开发一个新的服务,工程师的第一件事是为这个服务创建 Ansible 脚本。
在我们的基础设施中的任何系统、组件、数据都应该被监控。我们有一些关于如何正确记录日志和监控应用程序的最佳实践:
对于任何给定时间点,仪表板(dashboard)都能够显示系统的状态;
对于记录日志,我们使用 ELK,借助它我们可以快速分析服务的详细行为;
对于监控,我们喜欢 Statsd + Grafana 的组合。 它非常简单易用并且足够强大;
即使借助这些工具,我们依然面临一个难题:了解老的架构,并且尽可能平滑的升级它。在这个阶段,我们花了一些时间和精力来重构我们的老系统,以支持我们的新 API 网关和身份验证服务,这也是本文将要介绍的(后续内容请继续关注此系列)。
我们遇到的一些问题:
虽然我们可以更改我们的移动客户端,但没法保证用户会很快更新。因此我们不得不保持向后兼容性,比如通过 DNS 来确保旧版本依然可以正常使用;
我们必须分析公开和私有 API 中的所有可访问地址,并自动在网关中注册它们;
我们必须禁用原有 API 中的身份验证,并将此职责交给新的身份验证服务;
我们必须确保 API 网关和微服务之间的通信安全、可靠;
为了解决导入问题,我们使用 Go 语言写了一个脚本先来读取我们的 OpenAPI 规范(Swagger 生成的 API DOC),再为我们 原有 API 的每个资源(Restful 中的 resource)创建一个代理,同时需要包含正确的规则(如限速,配额,CORS等)。为了测试服务之间的通信,我们在一个 staging 环境中搭建了一整套基础设施,并开始执行我们的自动化测试集。我们维护了一套大型自动化功能测试集,帮助我们保障原 API 到移动客户端和 Web 客户端的服务质量。在我们确信上述事情在 staging 环境中正确工作后,我们开始考虑如何将其应用到生产环境。
必须承认第一次尝试(生产环境)完全是个灾难,即使我们有一个相当不错的计划:
支持识别各类商场、超市及药店的购物小票,包括店名、单号、总金额、消费时间、明细商品名称、单价、数量、金额等信息,可用于商品售卖信息统计、购物中心用户积分兑换及企业内部报销等场景
涉农贷款地址识别,支持对私和对公两种方式。输入地址的行政区划越完整,识别准确度越高。
根据给定的手机号、姓名、身份证、人像图片核验是否一致
通过企业关键词查询企业涉讼详情,如裁判文书、开庭公告、执行公告、失信公告、案件流程等等。
IP反查域名是通过IP查询相关联的域名信息的功能,它提供IP地址历史上绑定过的域名信息。