我们为什么选Rust重写核心服务?

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"两年多来,Kraken的Core Backend 团队一直在用Rust来对原本使用PHP编写的服务进行现代化改造,同时还在用Rust开发新产品、扩展功能集合并支持不断增长的加密货币交易活动。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"重写核心服务"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"针对一个问题从头开始构建一个解决方案往往会给我们带来另一个问题。当原来的开发人员没有参与新解决方案的设计和实现时,这种情况尤其常见。还有一些情况下,新的方案理论上更好用,但是做起来费的时间太久,拖慢了系统响应需求的进程。虽然我们可以设法避免这些常见的陷阱,但不管怎样我们在重写之前都要三思而后行。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2011年Kraken成立时,PHP提供了一个兼顾执行安全性、速度和生产力的选项。彼时我们用PHP构建了那么多功能,实在令人印象深刻。但多年以来,Kraken取得了长足发展,而PHP代码库开始变得难以扩展,很难共享知识并安全地做出较大的更改。这些核心服务处理的是分布式数据存储、加密和信息安全方面的事宜,这类技能组合在PHP开发人员中并不常见,他们通常更专注于在现有的Web和电商框架上构建内容。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总体而言,Kraken已进入了爆发式增长阶段,代码库和工具都需要跟上脚步。考虑到这一点,动态类型的编程语言非常适合早期的构建阶段,但随着代码库的扩张和工程师人数的增加,代码维护起来愈加困难。强类型提供了保证(和格式化的文档),从而加快了开发速度,让单个代码库可以支持更多开发人员。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们重写核心服务的主要目标是:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"尽可能保持系统安全性"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":2,"align":null,"origin":null},"content":[{"type":"text","text":"即使系统变得越来越大,也让系统更易维护、更加健壮"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":3,"align":null,"origin":null},"content":[{"type":"text","text":"获得更好的性能"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"早在2018年初,我们就已经意识到,继续使用PHP并不是实现这些目标的最佳长期解决方案。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"为什么选择Rust?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2018年初,Kraken已经有了用Go和C++编写的生产服务。尽管Rust提供了出色的性能、安全性和现代语言结构,但将其作为重写核心服务的语言选项还是一种赌注。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kraken非常注重安全性。因此,我们不想让C++代码参与用户输入。即使是世界上最好的C++团队(如构建Windows™或Chrome™的团队),做出来的代码中也有约70%的CVE来自于内存安全性问题——诸如释放后使用、缓冲区溢出、两次释放等,这可能会导致内存访问控制和特权升级攻击。可是在Java、Go或Rust等语言中,这些漏洞是被彻底堵死的。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"尽管Go可以抵御这类漏洞,但它不提供诸如泛型或求和类型之类的现代编程特性,结果会导致数据建模或重复问题。Kotlin提供了一个更复杂的类型系统,并且像Go一样,它简化了异步编程,但是带有一个承载诸多遗产的Java生态系统。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"再来看Rust。它的可靠性和性能让它在加密货币和区块链项目中取得了成功。一些Kraken工程师开始拿它做实验,并视其为构建可以长期满足Kraken后端需求的系统的一种选项:性能匹敌C++、现代语言构造有助于准确地建模业务逻辑和错误用例、对异步编程有着一流支持、编译时线程安全,还有充满活力的生态系统。Rust的价值主张和社区取得的成功促使Kraken在2018年中开始用Rust来重写核心服务。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"两年后"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Core Backend团队成绩斐然,如今同时负责现代化的Rust核心服务和仍在重写中的旧版PHP服务。同时,其他一些团队已经成功应用了Rust:Kraken的期货团队加入了我们的行列,他们独立地将所有后端堆栈迁移到了Rust上;Cryptowatch选择了Rust用于桌面应用程序;Kraken将冷存储系统迁移到Rust;Kraken Digital Asset Bank也在用Rust构建。这种语言本身也有了显著改进,让异步网络服务编写起来更容易了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总的来说,我们一直很忙:Core Backend团队的Rust git存储库保存了约500000行代码,比PHP更多,尽管许多特性仍是在PHP中实现的。部分原因是我们用Rust编写了更多的基础代码、测试和全新的特性,另一个因素是PHP与其他动态类型化的编程语言一样,不需要类型化结构定义(包括错误),而Rust代码中这种定义占据了很大一部分。在PHP中没有那些显式结构,这让重写过程几乎成了一次逆向工程的演练。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"从策略上讲,我们决定在Rust中重写完全相同的功能:由于所有PHP服务都是无状态的,因此可以轻松地将逻辑(逐个端点地)移植到Rust。这样一来,新招募的团队就可以获取更多有关底层系统的知识,并可以进行增量部署或轻松回滚。我们已经构建了一个全面的集成测试套件,PHP和Rust服务都需要通过它的测试以确保行为是相似的。将功能移植到Rust后,可以更轻松、更安全地扩展。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"尽管性能提升不是重写的主要目标,但我们很高兴看到Rust提供了开箱即用的惊人速度。我们Tokio驱动的RPC服务器并未做过特别优化(尽管我们通常对内存使用模式非常谨慎),结果每个实例可以支持150k请求\/秒的吞吐量,同时将p99.9延迟保持在3ms以下。系统的运行速度取决于最慢的部分,虽然我们的PHP核心服务不是Kraken的唯一瓶颈,但它们的IO性能要比Rust的低一些,并且对负载更敏感。在将整个端到端路径迁移到Rust并消除瓶颈之后,我们的客户应该能看到巨大的性能提升。同时,我们会将端点迁移至Rust、重新设计数据库和扩展服务,尽一切努力来提高性能和可靠性。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/46\/46bb477ace4794877f5bab5c12f1ff6b.webp","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":"center","origin":null},"content":[{"type":"text","text":"这是将一个端点移植到Rust时响应时间的变化"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"用于应用程序服务的Rust"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust通常被宣传为一种出色的系统编程语言,非常适合底层任务、命令行实用程序和网络服务(例如负载均衡器)。许多人认为Rust的复杂性对于一般的业务逻辑来说是很大的劣势,Rust的就业市场也太小了,以至于公司很难使用这种语言来完成诸如构建用户管理系统或REST API之类的常见任务。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust 非常适合系统编程,但我们也一直用它来做一些通常用更高级别语言(例如Java、Ruby或TypeScript)实现的应用程序服务。正确性在Kraken中绝对至关重要,而Rust的现代语言结构让我们更容易编写正确而健壮的代码。Rust缺少垃圾收集的特性在编写不需要“关心”内存管理的通用逻辑时往往被认为是一种劣势,但在实践中这并不是问题,因为我们正在构建的是无状态服务,而存储循环数据从来都不是问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但Rust需要精确度,我想说的是这是这种语言最大的好处:它的显式性(受其强大的类型系统支持)带来了容易审查且运行时可靠的表达性代码。在这方面,我认为Rust与Java和其他同类语言比起来既有更低级别的优势,也有更高级别的好处。Core Backend团队还开发了其他一些技术服务,例如负载均衡器或服务监视流,它们需要良好的性能,而且使用Rust让我们不必在系统和应用程序逻辑语言之间来回切换,还可以重用库和模式,实践中这非常方便。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"随着团队和代码库的成长,有效审查代码的能力变得至关重要。Rust可以让行为清晰且隔离地表现出来,这意味着我们无需过多考虑系统的其他部分——只研究当前函数往往就足够了。在审查代码时,我们会看到一个diff(更改的行和周围的上下文),虽然可能需要更多时间来深入研究更改,但更快的审核可以让开发人员迅速获得反馈,这是很好的驱动力。在Rust中可以肯定的是,编译后的更改不会出现数据争用(并发错误的主要来源之一)和内存安全问题(我们的大多数代码都用的是safe Rust)。我可以很容易地发现可能导致问题的函数(当没有其他选择时,Rust会中止执行)、发现无用的内存副本,并收集开发人员的意图。Rust的linter、Clippy有助于统一代码样式,带来了更符合习惯、更一致的代码库。最近两年来我审查了成千上万的合并请求,Rust为我带来了比其他主流编程语言都更高的信心。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust是一种大型而复杂的语言,开发人员很容易在细节上迷失方向。还好我们没必要为了保持效率而了解所有的细节。根据我们的经验,Rust是一种非常有生产力的语言:它具有出色的工具链,可以迫使我们彻底建模问题、节省宝贵的调试时间、解决潜在的生产问题,并且非常便于代码重用(这是生产力的倍增器)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,我觉得有必要澄清“fighting the borrow checker”这种说法,它把Rust编译器说成了一种怪物:以我的经验,这种情况主要发生在初学者中,另外就是很少一部分人试图对代码进行细节优化或探索极限情况时容易碰到它。大多数有经验的Rust开发人员很清楚怎样建模代码可以避免在编译器上浪费时间处理各种问题,并且一眼就能发现那些反模式,就像大多数人都知道如何正确地驾驶汽车来避免事故一样。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"建立一个Rust团队"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在这两年中,我们已经构建了现代化的Kraken后端技术栈的基础、将现有功能重写为Rust、构建了新的Rust服务和功能,还组建了一支由30多名工程师组成的Core Backend团队。一些开发人员一开始应聘的是PHP开发,但加入团队后学会了Rust。值得一提的是,Kraken是一家全球化的远程优先公司,Core Backend团队的工程师来自15个国家,工作地点分布在12国境内。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust吸引了很多热情的开发人员,他们通常对系统编程、分布式系统或加密技术感兴趣。我们目前的Core Backend工程师中有很大一部分是Rust爱好者,他们通过各种Rust在线资源发现了我们的招聘机会,包括Reddit和This Week In Rust(它们多次推荐了我们的招聘信息,谢谢!)。因为这些社区,人们很久以前就知道Kraken在招聘Rust开发人员了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们的Core Backend团队成员需要在竞争激烈的市场中应对具有挑战性的技术和业务问题,在世界各地进行远程工作,而我们提供了与地理位置无关的高额基本薪酬和慷慨的期权。此外,团队成员几乎所有时间都在编写Rust。这两年来应聘的众多候选人很满意这样的条件,使我们得以组建世界一流的工程团队。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们一开始也接纳对Rust感兴趣但缺乏上手经验的开发人员,但我们很快意识到这并不总是可行的,并且学习曲线因人而异。有趣的是,Rust吸引了来自各种语言的开发人员,这些语言差异巨大,有的是静态类型,有的是动态类型。很难说来自哪些背景的人们学习起来会更困难,但有些人在几周内就可以入门,而另一些在几个月后仍然难以上手。习惯依赖文档并且对语义有系统理解的人们最有可能快速成长。像许多快速发展的公司一样,我们需要新员工迅速投入实际问题的工作中。因此,我们要求应聘者提供可证明的Rust经验,并且需要通过测试,检验他们是否全面了解Rust的类型系统以及标准库和常见板条箱的实用知识。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我相信使用Rust可以帮助人们成为更好的开发人员,因为它推动人们重视简洁的设计和精确度。但光是了解Rust并不能让我们成为出色的工程师。我们看到许多候选人对Rust都很满意,但他们在构建后端系统方面经验有限。我们雇用了许多有着巨大潜力的初级开发人员,因为在组建团队时,平衡是成功的关键。经验丰富的开发人员往往是出色的导师:他们通常拥有简化事物的智慧,知道不应该过于信任自己,也明白该如何最大限度地发挥自身对业务线的影响。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"考虑到这种语言可以解决C++、Java或Go的许多痛点,我希望有更多经验丰富的开发人员进入Rust的世界。我之前从事Java开发工作有十多年的经验,向来对过度炒作的新技术保持合理的怀疑态度。但现在我并不想回去用一种素质不及Rust的语言——特别是Rust让我专注于手头的模块,而无需不断考虑许多隐式不变式,例如某个代码段是否是从另一个线程调用的,而我需要让它保持线程安全之类的问题。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们希望随着越来越多的公司(从Discord和Deliveroo到亚马逊和微软)在Rust上加大筹码,我们可以帮助业界发出一个信号,告诉大家Rust的工作机会有很多,并且花时间学习这种语言不会浪费精力。许多经验丰富的开发人员更愿意留在他们擅长的技术栈中,但是有些人可能还是喜欢尝试摆脱自己的舒适区并挑战自我。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Rust很伟大,但不是完美的!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Rust让我们能够构建许多运行良好的高性能生产代码。我们有一个庞大的团队,成员分别负责后端中各种差异巨大的部分。大部分代码都非常健壮:我们还没有经历过Rust核心服务的崩溃或恐慌(大致相当于运行时异常)。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总体而言,我可以说我们只遇到过业务逻辑问题、配置错误问题,并且遇到了一个一般性的性能问题,其与在musl libc上运行的,具有特定内核配置的Tokio相关,不过我们用perf工具定位后就轻松修复了。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"尽管这种语言的确很棒,但也有一些众所周知的局限困扰着我们。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"理想情况下,每个易错函数将具有自己的错误枚举来精确捕获其错误并处理,但实际上它过于冗长,结果导致了不太精确的错误特征(trait)或每个模块使用一个枚举。Rust语言在这方面可以做得更好:有一些倡议和宏对此做了探索。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在设计库箱时,缺乏 specialization 和通用关联类型(generic associated types,GAT)可能会带来很大限制。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们一直在搭配使用async Rust与Future组合器,并在async\/await支持进入nightly版本后立刻开始使用它。这项功能非常棒,使我们能够使用Tokio构建大规模的并发应用程序。我们并不需要花费太多时间来让我们的服务器处理超过10K的并发连接或实现背压。但它还是有一些改进余地:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"与Rust的大多数部分不同,async函数看起来有点像无害的常规函数,但它们可能不会完全执行(更确切地说,它们返回的Future可能不会被轮询完成)。处理清理逻辑时要格外注意,因为逻辑本身目前不能异步。支持异步drop的提案有望提供一个解决方案。如何让这种问题更清晰可见仍然悬而未决;可以让属性清楚地表明Future可以安全地取消,否则就让一个lint警告提醒我们吗?"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"尽管现在的情况有所好转,但异步框架的分裂严重损害了生态系统。如果Rust能够提供一种构造,允许任务调度子系统被抽象出来而无需额外开销,那会是很大的改进。这样人们就可以选择自己喜欢的执行器,并将任务执行器传递给库,或者自行驱动Future。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"静态初始化任务执行器的当前设计使开发人员简单地拉出一个依赖项就能错误地运行多个执行器。线程局部变量的普遍使用加大了调试的困难。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如果能够在特征中设计异步函数而无需装箱,并能引用结果类型,肯定会成为一项重大的性能改进。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们也希望看到围绕io-uring的工作带来巨大的性能改进,同时不至于造成生态系统的进一步分裂。"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在工具链方面,Cargo和Rustup大大简化了设置和编译项目的工作。RustAnalyzer带来了显著的改进,并提供了很棒的IDE体验。编译时间总体变短了:想要更短也是可以的,但考虑到增量构建和sccache,现在这样也不错了。优化构建确实速度很慢,但总体来说为了性能和安全性这是很小的代价。具有许可支持的私有Cargo注册表显然会助力Rust的企业应用。我们一直在使用git依赖项,但缺乏语义版本控制的支持让更新过程变得很痛苦。市面上有一些开源的Cargo注册表可用,但Cargo本身不支持访问令牌或凭证。我们很乐意赞助这项工作。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Kraken热爱Rust"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"总的来说,Rust非常成熟,并且它的大多数痛点在其他主流语言也多多少少会存在。Rust让代码重用起来非常轻松,并使我们能够在不牺牲性能的情况下安全地应对快速变化的大型代码库。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"对我们而言,使用Rust不再是一项实验或赌注。这是我们正在构建的可靠技术,并且Core Backend团队正在寻找熟练的工程师。不得不提的是我们团队在Rust之外的价值观:Core Backend团队利用Rust的工程价值和受Netflix影响的高性能团队文化,进一步扩展了Kraken的文化,以及对我们使命的承诺。我们相信超越代码的工程文化,相信自主权。我们拒绝傲慢自大。我们不断相互学习。不在一个办公室工作让我们面临更大的挑战,而积极进取的人们可以成为优秀的工程师,能够自我驱动、技术精湛,能够在需求和技术解决方案之间架起桥梁,从而自主前行。我们既看重天赋也看重努力,同时在工作与生活之间保持了良好的平衡,维持健康的体魄。我们关心自己在构建的事物,并全力帮助我们的队友取得成功。我们意识到完美是出色成果的敌人(众所周知,Rust开发人员都是完美主义者!😉)。最后,我们相信团队会不断自我完善:如果技术或组织方面出现问题,我们会解决它们。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们的Core Backend团队目前在招募中级和高级后端工程师以及站点可靠性工程师,这些人员可帮助支持和改善我们的运营、工具链和CI。我们还在聘请测试工程师来帮助我们使用Rust和Cucumber测试API。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kraken的其他团队也一直在寻找优秀的工程师,他们选择Rust作为构建强大和快速响应系统的首选工具:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"KrakenDigitalAssetBank是一家特殊用途的托管机构,使用Rust建立现代银行和支付系统,正在寻找高级工程师;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Kraken期货团队两年来一直使用Rust作为主要语言来构建衍生品交易服务,他们以前用的是Java和Kotlin,正在寻找后端工程师;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我们的交易技术团队在建立现货交易的同时,还使用C++和Rust构建大量服务,并正在招聘后端工程师;"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Cryptowatch构建了一个轻量级的桌面交易应用程序,他们也在雇用RustGUI开发人员。"}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"请务必检查我们的其他开放职位!"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最后,我们想帮助Rust成长。我们已经通过Kraken Grants计划赞助了一些开源工作(例如iced GUI框架)。我们很乐意赞助Rust项目或相关关键项目的个人贡献者。如果你正在为Rust生态系统做出重要贡献并需要资金,请与我们联系!同时,RustAnalyzer团队所做的出色工作给我们留下了深刻的印象,这些工作直接让整个社区受益,我们将为该项目捐款5万欧元!"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"原文链接:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https:\/\/blog.kraken.com\/post\/7964\/oxidizing-kraken-improving-kraken-infrastructure-using-rust\/?fileGuid=C3XtwPgtGkgvxpKj"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章