技术雷达:经过Lamoda手中的语言,工具和平台的列表

上一篇文章的评论中,关于我们使用的技术存在很多问题。 在本文中,我-Lamoda的研发人员Igor Mosyagin-我将介绍它们。 在切面下,您会找到详尽的语言,工具,平台和技术清单。 前端,后端,数据库,消息代理,高速缓存以及监视,开发和平衡是有关我们今天使用的东西和我们已经放弃的东西的详细故事。



我和我的同事随时准备在评论中或在HighLoad ++ 2018的公司展台上进行讨论。

在此处查看雷达的详细信息。

正如我们已经说过的,Lamoda涉及大量不同的技术和工具。 这不是巧合。 否则,我们无法应付负荷! 我们有一个大型的自动化仓库。 我们的呼叫中心有500名员工服务,并且我们建立的流程使我们能够在下订单后5分钟内给客户回电。 我们的送货服务每15分钟运行一次。 但是,除了我们自己的系统外,我们还与其他在线商店进行了B2B集成。 面对各种各样的任务以及诸如电子商务这样的动态业务的需求,技术堆栈的增长是不可避免的,因为我们想用最合适的技术解决每个问题。 多样性是不可避免的。 我们将在下面讨论堆栈的主要代表。 但是,让我们从允许我们不要迷失在这种多样性中的机制开始。

架构要点


我们正在积极向微服务架构迈进。 大多数系统已经按照这种意识形态进行了构建-两年前,我们经历了一个过渡阶段,研究了我们的问题及其解决方案。 但是,我们不会详细介绍此过程-Andrey Evsyukov的报告“ 以e-Com平台为例的微服务的功能 ”将提供更多有关此方面的信息。

为了不加剧技术多样性,我们引入了“成熟实践的专政”,根据该建议,建议新芯片的创建者使用公司某些地方已经使用的技术和工具。 大多数服务通过API相互通信(我们使用对JSONRPC标准第二版的修改),但是在业务逻辑允许的地方,我们也使用数据总线进行交互。

禁止使用其他技术。 但是,任何新想法都应在专门创建的建筑委员会中进行测试,该委员会应包括主要领域的领导人。

考虑下一个建议,委员会要么为实验开绿灯,要么从现有协议栈中提供某种替代方案。 顺便说一句,这个决定很大程度上取决于企业的当前情况。 例如,如果一个团队在黑色星期五销售的前夕宣布其将技术引入委员会从未听说过的生产中,则很可能会被拒绝。 另一方面,如果在不太关键的业务环境中引入新技术或工具,则可以使同一实验获得开绿灯,并且实施将从生产外的测试开始。

建筑委员会还负责维护技术雷达,每2-3个月进行必要的更改。 该资源的目的之一是使团队了解公司已经具备的专业知识。

但是,让我们继续最有趣的部分-分析雷达的各个部分。

值得注意的是,我们对技术采用的类别使用了稍微非标准的解释:

  • ADOPT-已实施和积极使用的技术和工具;
  • 试用-已经通过测试阶段并准备与生产一起使用(甚至已经在那里使用)的技术和工具;
  • 评估-目前正在评估并且尚未影响生产的试用工具。 在他们的参与下,只有测试项目得以实施;
  • 持有-在这一类别中我们拥有专业知识,但是上述工具仅在现有系统的支持下使用-不会在其上启动新项目。

发展历程




PHP-Python-执行


我们要使用的第一种语言是PHP。 如今,它仅解决了商店后端任务的一部分,并且最初整个后端都在PHP上运行。 随着业务在前端扩大,缺乏速度和生产力变得明显-那时我们使用PHP 5,因此Python取代了它(首先是2.x,然后是3.x)。 但是,PHP允许您编写丰富的业务模型,因此该语言一直留在后台用于自动执行各种操作流程,尤其是与第三方在线商店或交付服务的集成以及用于绘制产品卡的内容工作室的自动化。 现在我们已经在使用PHP7。在PHP中,我们编写了许多供内部使用的库:基础架构上的集成和包装,服务之间的集成层,各种重用的帮助程序。 第一批库已经在我们的github.com开源 ,其余的(最成熟的)库很快就会到来。 首先是状态机,几乎在所有应用程序中都使用状态机,以确保在发送所有必要动作之前按顺序进行操作。

随着时间的流逝,Python对于存储后端也变得不足。 现在,我们更喜欢生产效率更高,重量更轻的Go。

过渡到Go也许是一个重要的变化,因为它节省了大量的硬件和人力资源-效率已大大提高。 在Go上进行第一个项目的第一个人是RnD,他们不想处理Python的技术限制。 然后,在移动开发团队中,有些人熟悉他并将其提升为生产人员。 从他们的提交中,我们进行了测试,并对结果感到非常满意。 在单独的情况下,将项目的一部分从Python重写为Go后,群集节点的负载显着下降。 例如,将购物篮的折扣计算引擎从Python重写为Go,使我们可以在相同的硬件容量下处理8倍以上的请求,并且平均API响应时间减少了25倍。 即 即使对开发人员而言,Go的效率要比Python(如果正确编写)要高得多(如果您没有正确编写的话)。

由于移动开发必须与许多内部API交互,因此创建了一个代码生成器,根据API服务的描述(根据Swagger规范),客户端可以在Go上生成。 因此,在Go上,逐渐开始与现有的服务和工具相对应,尤其是那些造成负载“瓶颈”的服务和工具。 除了使移动后端开发人员的工作变得更轻松之外,我们还简化了以下内部约定,涉及如何开发API,如何命名方法,如何传递参数等。 这种标准化使所有团队更容易开发和实施新服务。

如今,Go已几乎在所有地方(与用户进行的所有实时交互)在网站和移动应用程序的后端以及与之关联的服务中广泛使用。 而且在不需要快速处理和响应的地方,例如,在与数据仓库交互的任务中,Python仍然存在,因为它与数据处理任务没有等同关系(尽管这里有Go渗透)。

如您所见,资产中包含Java。 它在仓库管理系统(WMS)中使用,有助于快速收集订单。 到目前为止,我们那里有一个相当旧的堆栈和一个旧的体系结构模型-在Wildfly 10和8 Java Hotspot上旋转的整体,在Netbeans应用程序平台上也有远程处理和Rich Client(现在此功能已转移到Web上)。 在这里,在我们的军械库中,我们为公司配备了标准存储,甚至还有我们自己的监控器。 不幸的是,我们找不到能够很好地可视化仓库及其重要流程的工具(例如,当某个部分超载时),而是我们自己制作的。

我们将Python用作机器学习的主要语言:我们建立推荐系统并对目录进行排名,纠正搜索查询中的拼写错误,并与Hadoop集群(PySpark)上的Spark结合解决其他问题。 Python帮助我们自动计算内部指标和AB测试。

前端和移动开发


桌面在线商店以及移动网站的前端都是用JavaScript编写的。 现在,前端正在逐渐转向ES6规范,并根据它创建新项目。 我们使用vue.js作为主要框架,但我们将在“工具”部分中对其进行详细介绍。

移动平台的应用程序开发是公司的一个独立部门,其中包括后端组以及具有自己的技术堆栈和工具的Android和iOS应用程序,由于平台的差异,很难始终将其跨整个部门统一。

两年来,Kotlin一直在进行所有新的Android开发,这使我们能够编写更加简洁和易懂的代码。 在最常用的功能中,我们的开发人员称之为:智能广播,密封类,扩展功能,类型安全的构建器(DSL),stdlib功能。

iOS开发正在Swift上进行,它取代了Objective-C。

特殊语言


Lamoda的任务范围不仅限于分别针对不同平台开发“展示柜”,我们有多种语言,仅在其系统内使用,可以在其中正常工作,但不会在基础架构的其他部分中实现:

  • R-用于商业智能(BI)框架中的数据处理和报告脚本。 它不在生产中,不再用于新任务,但是我们仍然有许多这样的脚本。 解决R的问题后,我们意识到该语言不适用于高负载的应用程序。 在新任务中,我们使用Python和其他与R不兼容的技术。
  • Scala-维尔纽斯的开发办公室使用它来开发呼叫中心自动化系统。 最初,该系统是用PHP编写的,但是在向微服务体系结构过渡的过程中,许多组件都是用Scala重写的。 此外,数据工程团队还编写Spark作业。
  • 我们正在研究的TypeScript。 交付已经在其帮助下得以实现,将来我们将在前端使用TypeScript +vue.js。
  • Lua用于配置nginx(通过nginx API),在其他项目中则不是,也永远不会。
  • 我们是一家时装公司,遵循时尚进行功能编程。 例如,我们的一个仓库中的分类设备模拟器是用Haskell编写的。

资料管理




DBMS,数据搜索和分析


与许多其他数据库一样,我们已经在PostgreSQL上实现了-在需要关系数据库的任何地方都可以使用它,例如,存储目录。 寻找这项技术的专家很容易,此外,还有许多不同的服务可用。

当然,PostgreSQL不是我们的IT基础架构中唯一的DBMS。 例如,在某些较旧的系统上,使用的是MySQL,而WMS则使用了一些MongoDB。 但是,对于高负载和规模化(考虑到我们技术堆栈的其余部分),我们不将其用于新项目。 总的来说,PostgreSQL是我们的一切。

雷达上也可以看到Aerospike。 我们非常积极地使用了它,但是后来产品的许可协议发生了变化,因此“我们的”版本被削减了一些。 但是,现在我们再次看着他。 也许我们会重新考虑我们对乐器的态度,并会更积极地使用它。 现在,Aerospike用于页面浏览事件的聚合服务以及用户使用购物篮的服务,以及社交证明服务(“本周有5个人将此产品添加到收藏夹”)。 现在,我们对此提出了更严格的建议。

Apache Solr用于搜索生产数据。 同时,我们还使用ElasticSearch。 两种解决方案都是开源的,但是如果更早的时候,当我们刚刚实现搜索时,Apache Solr已经拥有第三或第四版并正在积极开发中,而ElasticSearch甚至没有第一个稳定版本-在生产中使用它还为时过早。 现在角色已经改变-为ElasticSearch找到解决方案要容易得多,并且新来的人都准备好了。 但是,在产品中有Solr,至少在2018年黑色星期五之前我们不会转向其他解决方案。


根据Google趋势比较搜索查询动态的Apache Solr(蓝色)和ElasticSearch(红色)

数据分析发生在多个系统中,特别是我们积极使用Apache Hadoop。 同时,Vertica列DBMS用于存储数据集市(总容量约为4 TB)。 在这些展示柜中,构建了财务,运营和商业报告。 对于我们的许多ETL任务,我们以前使用Luigi,但现在我们转向Apache Airflow。 我们还使用Pentaho进行关系存储,其中有大约一千个常规ETL任务。

其他系统的部分分析和数据准备在Spark中进行。 在某些地方,这不仅是分析工具,还是我们lambda架构的一部分。

ERP系统在IT基础架构中扮演着重要角色:Microsoft Dynamics AX和1C。 作为DBMS,使用Microsoft SQL Server。 对于报表,它的组件,例如分析服务和报表服务。

快取


对于缓存,我们使用Redis。 以前,此任务是由MemCached执行的,不能用作具有定期转储到磁盘的键值存储,因此我们放弃了它。

消息队列


作为事件代理,我们同时使用两个工具-Apache Kafka和RabbitMQ。
Apache Kafka是一种工具,使我们可以在需要消息传递的各种系统中处理成千上万条消息。 单独的Kafka群集已部署到系统的某些高负载部分-例如,用于用户事件或日志记录(我们在Highload ++ 2017上有很好的日志记录报告 )。 Kafka允许您在不使用铁的情况下每秒处理60万条批量消息。

在内部系统中,我们使用RabbitMQ进行延迟的操作。

平台和基础设施




持续交付


为了进行部署,使用了Kubernetes,它取代了Hashicorp的Nomad + Consul捆绑包。 先前的堆栈在硬件升级中的效果很差。 当我们的Ops团队更改节点正在旋转并存储容器的物理服务器时,它会定期崩溃并崩溃,而不希望增加。 当时没有稳定的版本。 此外,我们当时没有使用最新版本-0.5.6,该版本仍需要更新。 升级到最后一个测试版需要一些工作。 因此,决定放弃它,转而使用更流行的Kubernetes。

现在Nomad和Consul仍在质量检查中使用,但将来他也应该转到Kubernetes。

为了实现持续交付,使用了两年前我们迁移到的Docker容器。 对于我们的高负载服务(购物篮,目录,网站,订单管理系统),快速获取服务的其他几个容器的能力很重要,因此我们到处都有容器。 Docker是最流行的容器化方法之一,因此它在雷达上的存在是很合逻辑的。

作为构建服务器和持续集成,Bamboo已部署,并与Jira和Bitbucket(标准堆栈)结合使用。

雷达还提到了詹金斯(Jenkins)。 我们对他进行了实验,但我们不会将他拖入新的项目。 这是一个很棒的工具,但是因为我们已经有了Bamboo,所以它不适合我们的堆栈。

使用Bamboo docker容器收集的数据在Artifactory的控制下存储在存储库中。

流程管理与平衡


我们使用NGINX Plus,但不使用平衡,因为它的指标不足以完成我们的任务。 例如,他不能说哪个请求最经常被路由或冻结。 因此,使用HAProxy来平衡负载。 它可以与nginx一起快速有效地工作,而无需加载处理器和内存。 此外,我们需要的度量标准是现成的-HAproxy可以按节点,按当前连接数,带宽的繁忙程度显示统计信息。

UWSGI用于运行同步Python应用程序。 Php-fpm被用作所有PHP服务上的流程管理器。

监控方式


我们使用Prometheus从应用程序和主机(虚拟机)以及应用程序时间序列数据库中收集指标。 我们收集日志,为此,我们使用ELK堆栈,作为警报系统,我们使用Icinga,它同时为ELK和Prometheus配置。 她向邮件和SMS发送警报。 6911支持服务会收到相同的警报,并决定吸引值班工程师。

Prometheus几乎涉及到所有地方,为此,我们拥有适用于所有语言的库,该库允许仅使用几行代码将其指标连接到项目。 例如, 可以在Open Source中获得PHP库。

为了以美观的仪表板形式直观地显示监视结果,使用了Grafana。 基本上,我们收集了Prometheus的所有仪表板,尽管有时其他系统也可以用作源。

对于捕获和自动错误汇总,我们使用Sentry,它与Jira集成在一起,可以轻松地为每个生产问题启动任务跟踪器。 他知道如何通过一些回溯和其他信息来捕获错误,因此登场很方便。

使用SonarQube收集有关创建的拉取请求的代码的统计信息。

框架和工具




在Lamoda IT基础架构的开发过程中,我们尝试了将近三打不同的工具,因此这一类别是我们雷达上最“大规模”的。 迄今为止,正在积极使用:

  • Symfony 3.x,以及最近的Symfony 4.x-用于PHP开发;
  • Django和用于Python开发的Jinja模板引擎。 顺便说一下,Jinja用于(包括)Ansible中的配置;
  • Flask-用于内部服务(与Django一起使用),但是在生产中我们不拖动它;
  • 春季-Java开发;
  • Bootstrap-用于Web开发中的各种内部工具(管理面板,自制仪表板等);
  • jQuery-用于js开发;
  • OpenAPI(Swagger)-用于所有API服务的文档,包括 用于在Go上生成上述代码;
  • Webpack-用于打包JS和最小化CSS;
  • 硒-用于测试前端;
  • 测试中还使用了WireMock,JMeter,Allure等。
  • Ansible-用于配置管理;
  • Kibana-用于在ElasticSearch中可视化搜索结果。

我想单独谈谈JavaScript开发。 与许多人一样,我们拥有整个实验领域。JavaScript网站使用一个自写框架。在前端,在对业务不重要的任务框架中,使用不同的框架进行了实验-Angular,ReactJS,vue.js。在这场“军备竞赛”中,似乎最初在内容工作室的自动化系统中使用的vue.js似乎处于领先地位,现在逐渐无处不在。

在干渣中


如果简而言之描述所有这些多样性,那么我们将使用GO,PHP,Java,JavaScript编写代码,将数据库保存在PostgreSQL上,并部署在Docker和Kubernetes上。

当然,所描述的技术堆栈状态不能称为最终状态。我们正在不断发展,并且随着负载的增加,必须更改合适解决方案的类别,这本身就是一项有趣的任务。同时,业务逻辑变得越来越复杂,因此我们必须不断寻找新工具。如果您想就为何选择此工具而不是其他原因进行辩论,欢迎发表评论。

Source: https://habr.com/ru/post/zh-CN428411/


All Articles