仅用8台虚拟机处理每日数十亿笔交易?PayPal咋做到的?
ccwgpt 2024-10-15 08:55 20 浏览 0 评论
“PayPal如何仅用8台虚拟机扩展至每日处理数十亿交易?”看到这篇文章的时候,被这一惊人壮举给震撼,现在一起看看具体的实践历程。
1998年12月,在美国的加利福尼亚州,一个工程师团队为手持设备开发安全软件,然而他们最开始的商业模式失败了。
于是,他们转而创建了一项在线支付服务,并将其命名为PayPal。
PayPal的创立初期,用户就迎来了暴增,于是团队购置了更新的硬件来扩大规模。
然而,用户增长一直呈现爆炸性趋势,并在接下来的两年达到每天100万笔交易。因此,团需要通过1000多台虚拟机上运行服务,以实现扩展。
虽然他们解决了可扩展性,但是也带来了一些新的问题:
爆炸性增长带来的问题
1、网络架构扩展
随着请求量的增长,完成请求所需的网络传输路径变得更加复杂,导致处理延迟的增加。网络架构的扩展需求随之上升,这使得维护成本相应增加。
2、维护开销
随着更多服务器的加入,整个基础设施的复杂度也随之提高。服务器的部署和提供服务所需的时间变得更长。同时,实现基础设施的自动化扩展变得更加具有挑战性,监控和其他管理任务的难度也随之上升。
3、资源效率
服务器的CPU使用率下降,导致整体处理能力降低,这不仅造成了资源的浪费,同时也增加了运营成本。
如何解决这些问题?
采用Actor模型
PayPal认识到现有的代码在利用硬件能力方面是低效的,所以他们将简单性和可扩展性作为首要目标。
因此,他们转向了基于Akka框架的Actor模型。
1、Actor模型介绍
这种范式转变使得并行处理成为可能,且优化了硬件使用。
Actor模型作为并行计算的概念框架,其中计算的基本单位被称为actor。下面介绍Actor模型如何提升的可扩展性:
1)高效的资源利用
Actor作为轻量级对象,相较于线程,其资源消耗更少,因此能够轻松地创建数百万个实例。线程会被动态地分配给这些Actor以处理消息,且每个线程会依次处理多个Actor的任务。线程的数量会根据CPU核心的数量进行扩展,从而有效地管理大量并发的Actor。
线程会被动态地分配给Actor,用于顺序处理消息。线程的数量会根据CPU核心的数量成比例地扩展,从而有效地管理大量的并发Actor。
2)隔离状态管理
在Actor模型中,每个实例都保持隔离和私有,避免共享内存资源。Actor之间通过发送简洁且不可变的数据包来实现通信,这些数据包通过网络进行传输。
每个Actor都配备了一个消息队列,它按照先进先出(FIFO)的原则来处理消息流。在应用服务器上维护本地状态,这有助于减少对分布式缓存或数据库的网络请求,从而提高系统的整体性能。
PayPal采用了一致性哈希算法来确保客户端能够被路由到相同的服务器,以保持会话的连续性。
3)并发处理的高效性
Actor模型支持多个Actor的并行操作,每个Actor独立地按顺序处理其接收到的消息。这种方法确保了在任何给定时间,每个Actor只处理一个消息,从而优化了并行处理。异步消息处理机制消除了等待响应的需求,简化了并发控制。
PayPal利用Akka框架的函数式编程特性,增强了应用的可扩展性,避免了副作用,并简化了开发和测试过程。Actor模型的可插拔代码片段进一步简化了系统的扩展,允许Actor在本地或远程环境中无缝运行,无需复杂的系统配置。
3)容错机制的健壮性
Actor模型通过创建和监督其他Actor来维护系统的容错性。如果一个Actor失败,其监督者可以选择重新启动该Actor或将消息转发给其他Actor。
错误信息会传递给监督者,这保证了错误处理的优雅性,同时避免了代码的不必要复杂化。因此,Actor模型建立了一个弹性的系统框架,用于有效管理内部故障。
最终,PayPal通过Actor模型成功地以极高的效率处理了每天十亿笔交易,仅使用了少量的虚拟机资源。这一成果不仅解决了先前的技术挑战,还展示了精心设计的并发模型在提升系统可扩展性和性能方面的潜力。
现在,我们已经对理论有了足够的了解——让我们开始实际编码,深入了解Go语言中的Actor模型,并观察其在实际应用中的表现。
2、Go中的Actor模型
Go语言提供了一种并发编程范式,即Actor模型,它将程序分解为独立的Actor单元。每个Actor拥有自己的状态和行为逻辑。Go语言特有的goroutines和channels机制,为实现轻量级的Actor模型提供了便利。
在这种模型下,Actor被视为自包含的并发单元,它们通过交换消息来实现相互之间的通信。Goroutines作为Actor的实现方式,而channels则用于Actor间的信息传递。每个Actor独立维护自己的状态,并且能够异步地处理接收到的消息。
要在Go中应用Actor模型,常见的做法是为每个Actor分配一个goroutine,并通过channels来传递消息,从而实现Actor之间的交互。这些消息将指导接收Actor执行特定的操作或行为。
以下是一个简单的Go程序示例,用以展示Actor模型的基本概念:
package main
import (
"fmt"
"sync"
)
// Actor represents an actor with its own state and a channel for receiving messages.
type Actor struct {
state int
mailbox chan int
}
// NewActor creates a new actor with an initial state.
func NewActor(initialState int) *Actor {
return &Actor{
state: initialState,
mailbox: make(chan int),
}
}
// ProcessMessage processes a message by updating the actor's state.
func (a *Actor) ProcessMessage(message int) {
fmt.Printf("Actor %d processing message: %d\n", a.state, message)
a.state += message
}
// Run simulates the actor's runtime by continuously processing messages from the mailbox.
func (a *Actor) Run(wg *sync.WaitGroup) {
defer wg.Done()
for {
message := <-a.mailbox
a.ProcessMessage(message)
}
}
// System represents the actor system managing multiple actors.
type System struct {
actors []*Actor
}
// NewSystem creates a new actor system with a given number of actors.
func NewSystem(numActors int) *System {
system := &System{}
for i := 1; i <= numActors; i++ {
actor := NewActor(i)
system.actors = append(system.actors, actor)
go actor.Run(nil)
}
return system
}
// SendMessage sends a message to a randomly selected actor in the system.
func (s *System) SendMessage(message int) {
actorIndex := message % len(s.actors)
s.actors[actorIndex].mailbox <- message
}
func main() {
// Create an actor system with 3 actors.
actorSystem := NewSystem(3)
// Send messages to the actors concurrently.
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go func(message int) {
defer wg.Done()
actorSystem.SendMessage(message)
}(i)
}
// Wait for all messages to be processed.
wg.Wait()
}
该程序构建了一个基础的Actor系统,由三个Actor组成。消息以并发方式发送给各个Actor,每个Actor根据接收到的消息来更新自己的状态。此示例展示了Actor模型中的状态隔离、并发处理能力和消息传递机制。
以下是该Go程序的预期输出:
Actor 3 processing message: 5
Actor 8 processing message: 2
Actor 1 processing message: 3
Actor 2 processing message: 1
Actor 3 processing message: 4
请注意,由于goroutines的执行顺序可能不同,具体的输出结果可能会有所变化。这里提供的只是一个基础示例。在实际应用中,你可能还需要考虑Actor的生命周期管理、监督策略以及Actor模型的其他高级特性。
实际上,存在一些开源库,例如:github.com/AsynkronIT/protoactor-go,它们为Go语言提供了更为成熟的Actor模型实现方式。
结语
本文讲述了PayPal从早期到人气飙升增加虚拟机,到后来引入Actor并发模型以提升性能,解决了网络带宽及高昂成本的问题,实现仅用8台虚拟机处理每日数十亿笔交易的实践历程。
希望借此实践,让大家了解支付系统处理大规模任务的一些经验,也欢迎大家再评论区进行交流。
作者丨Neo Kim
来源丨网址:https://medium.com/@nidhey29/how-did-paypal-handle-a-billion-daily-transactions-with-eight-virtual-machines-76b09ce5455c
dbaplus社群欢迎广大技术人员投稿,投稿邮箱:editor@dbaplus.cn
相关推荐
- RACI矩阵:项目管理中的角色与责任分配利器
-
作者:赵小燕RACI矩阵RACI矩阵是项目管理中的一种重要工具,旨在明确团队在各个任务中的角色和职责。通过将每个角色划分为负责人、最终责任人、咨询人和知情人四种类型,RACI矩阵确保每个人都清楚自己...
- 在弱矩阵组织中,如何做好项目管理工作?「慕哲制图」
-
慕哲出品必属精品系列在弱矩阵组织中,如何做好项目管理工作?【慕哲制图】-------------------------------慕哲制图系列0:一图掌握项目、项目集、项目组合、P2、商业分析和NP...
- Scrum模式:每日站会(Daily Scrum)
-
定义每日站会(DailyScrum)是一个Scrum团队在进行Sprint期间的日常会议。这个会议的主要目的是为了应对Sprint计划中的不断变化,确保团队能够有效应对挑战并达成Sprint目标。为...
- 大家都在谈论的敏捷开发&Scrum,到底是什么?
-
敏捷开发作为一种开发模式,近年来深受研发团队欢迎,与瀑布式开发相比,敏捷开发更轻量,灵活性更高,在当下多变环境下,越来越多团队选择敏捷开发。什么是敏捷?敏捷是一种在不确定和变化的环境中,通过创造和响应...
- 敏捷与Scrum是什么?(scrum敏捷开发是什么)
-
敏捷是一种思维模式和哲学,它描述了敏捷宣言中的一系列原则。另一方面,Scrum是一个框架,规定了实现这种思维方式的角色,事件,工件和规则/指南。换句话说,敏捷是思维方式,Scrum是规定实施敏捷哲学的...
- 敏捷项目管理与敏捷:Scrum流程图一览
-
敏捷开发中的Scrum流程通常可以用一个简单的流程图来表示,以便更清晰地展示Scrum框架的各个阶段和活动。以下是一个常见的Scrum流程图示例:这个流程图涵盖了Scrum框架的主要阶段和活动,其中包...
- Mockito 的最佳实践(mock方法)
-
记得以前面试的时候,面试官问我,平常开发过程中自己会不会测试?我回答当然会呀,自己写的代码怎么不测呢。现在想想我好像误会他的意思了,他应该是想问我关于单元测试,集成测试以及背后相关的知识,然而当时说到...
- EffectiveJava-5-枚举和注解(java枚举的作用与好处)
-
用enum代替int常量1.int枚举:引入枚举前,一般是声明一组具名的int常量,每个常量代表一个类型成员,这种方法叫做int枚举模式。int枚举模式是类型不安全的,例如下面两组常量:性别和动物种...
- Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
-
Maven简介Maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行”。Maven是一个跨平台的项目管理工具。主要服务于基于Java平台的项目构建、依赖管理和项目信息管理。仔...
- Java单元测试框架PowerMock学习(java单元测试是什么意思)
-
前言高德的技术大佬在谈论方法论时说到:“复杂的问题要简单化,简单的问题要深入化。”这句话让我感触颇深,这何尝不是一套编写代码的方法——把一个复杂逻辑拆分为许多简单逻辑,然后把每一个简单逻辑进行深入实现...
- Spring框架基础知识-第六节内容(Spring高级话题)
-
Spring高级话题SpringAware基本概念Spring的依赖注入的最大亮点是你所有的Bean对Spring容器的存在是没有意识的。但是在实际的项目中,你的Bean必须要意识到Spring容器...
- Java单元测试浅析(JUnit+Mockito)
-
作者:京东物流秦彪1.什么是单元测试(1)单元测试环节:测试过程按照阶段划分分为:单元测试、集成测试、系统测试、验收测试等。相关含义如下:1)单元测试:针对计算机程序模块进行输出正确性检验工作...
- 揭秘Java代码背后的质检双侠:JUnit与Mockito!
-
你有没有发现,现在我们用的手机App、逛的网站,甚至各种智能设备,功能越来越复杂,但用起来却越来越顺畅,很少遇到那种崩溃、卡顿的闹心事儿?这背后可不是程序员一拍脑袋写完代码就完事儿了!他们需要一套严谨...
- 单元测试框架哪家强?Junit来帮忙!
-
大家好,在前面的文章中,给大家介绍了以注解和XML的方式分别实现IOC和依赖注入。并且我们定义了一个测试类,通过测试类来获取到了容器中的Bean,具体的测试类定义如下:@Testpublicvoid...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- mfc框架 (52)
- abb框架断路器 (48)
- ui自动化框架 (47)
- beego框架 (52)
- java框架spring (58)
- grpc框架 (65)
- ppt框架 (48)
- 内联框架 (52)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)