后端开发性能挑 战与系统设计竞赛
rinha-de-backend-2024-q1是一个后端系统设计挑战项目,要求开发者实现高性能的交易和账户查询API。项目设置了严格的并发和资源限制,考验参与者在负载均衡、并发控制和数据一致性方面的技能。这个平台为后端开发者提供了实践和提升系统设计能力的机会。
后端擂台赛是一项以挑战形式分享知识为主要目标的比赛!这是第二届。提交作品的截止日期是2024年3月10日23:59:59,结果将于2024年3月14日19:00在YouTube上通过直播公布。
本届擂台赛的主要主题是关于贷记和借记(信贷)的并发控制,灵感来自于同行@lucascs和@kmyokoyama在这条和这条评论中对这条推文的回应。
如果你想更深入地了解擂台赛的精神,请查看第一届的仓库。
要参与,您需要开发一个具有以下端点的HTTP API:
请求
POST /clientes/[id]/transacoes
{ "valor": 1000, "tipo" : "c", "descricao" : "descricao" }
其中
[id]
(在URL中)必须是一个整数,表示客户的标识。valor
必须是一个正整数,表示分(我们不处理分的分数)。例如,10元相当于1000分。tipo
只能是c
表示信用或d
表示借记。descricao
必须是1到10个字符的字符串。
所有字段都是必填的。响应
HTTP 200 OK
{ "limite" : 100000, "saldo" : -9098 }
其中
limite
必须是客户的注册限额。saldo
必须是交易完成后的新余额。
成功的交易请求的HTTP状态码必须是200!规则 借记交易绝不能使客户的余额低于其可用限额。例如,限额为1000(10元)的客户余额绝不应低于-1000(-10元)。在这种情况下,-1001或更低的余额 意味着后端竞赛中的不一致!
如果借记请求会导致余额不一致,API应返回HTTP状态码422,并且不完成交易!这种情况下的响应体不会被测试,您可以选择如何表示它。如果有效载荷字段不符合规范,例如descricao
字段超过10个字符或tipo
字段不是c
或d
,也应返回HTTP 422。如果valor
字段指定了非整数,您可以返回HTTP 422或400。
如果URL中的[id]
属性是不存在的客户标识,API应返回HTTP状态码404。这种情况下的响应体不会被测试,您可以选择如何表示它。如果API返回类似HTTP 200并在响应体中表示未找到客户,或者返回无响应体的HTTP 204,我将极度沮丧,后端竞赛将永远取消。
请求
GET /clientes/[id]/extrato
其中
[id]
(在URL中)必须是一个代表客户标识的整数。响应
HTTP 200 OK
{ "saldo": { "total": -9098, "data_extrato": "2024-01-17T02:34:41.217753Z", "limite": 100000 }, "ultimas_transacoes": [ { "valor": 10, "tipo": "c", "descricao": "descricao", "realizada_em": "2024-01-17T02:34:38.543030Z" }, { "valor": 90000, "tipo": "d", "descricao": "descricao", "realizada_em": "2024-01-17T02:34:38.543030Z" } ] }
其中
saldo
total
必须是客户当前的总余额(不仅仅是以下显示的最近交易)。data_extrato
必须是查询对账单的日期/时间。limite
必须是客户的注册限额。ultimas_transacoes
是按日期/时间降序排列的交易列表,包含最多10笔最近交易,具有以下内容:
valor
必须是交易金额。tipo
必须是 c
表示贷记,d
表示借记。descricao
必须是交易期间提供的描述。realizada_em
必须是交易的执行日期/时间。规则
如果URL中的 [id]
属性是不存在的客户标识,API必须返回HTTP状态代码404。在这种情况下,响应体不会被测试,你可以选择如何表示它。你已经知道如果你的API返回2XX范围内的东西会发生什么,对吧?谢谢。
为了在测试中强调并发性,应该只登记和测试少数客户。因此,测试前必须预先登记以下五位客户,包括他们的ID、限额和初始余额 - 这一点至关重要!
ID | 限额 | 初始余额 |
---|---|---|
1 | 100000 | 0 |
2 | 80000 | 0 |
3 | 1000000 | 0 |
4 | 10000000 | 0 |
5 | 500000 | 0 |
注意:请勿特意登记ID为6的客户,因为测试的一部分是验证ID为6的客户确实不存在,且API会返回HTTP 404错误!
与之前的后端竞赛一样,你需要将你的API和其他使用的组件容器化为docker-compose格式,遵守CPU和内存资源限制,最低架构配置,以及制品结构和提交流程(你的内容需要提交什么、在哪里提交、何时提交)。
你可以个人提交,也可以2人组队、3人组队,甚至50人组队。没有人数限制。你和/或你的团队可以提交多个作品,只要API不同即可。
要参与,只需在本存储库中创建一个拉取请求,在participantes中包含一个子目录,其中包含以下文件:
docker-compose.yml
- 可由docker-compose
解释的文件,其中包含组成您的API的服务声明,遵守CPU/内存限制和最小架构。README.md
- 至少包括您的姓名、使用的技术、API源代码存储库的链接,以及如果获胜时的联系方式。您可以自由添加其他信息,如网站链接等。nginx.conf
、banco.sql
等。
这里有一个提交示例可以帮助您。
重要! 所有在docker-compose.yml
中声明的服务必须公开可用!否则,将无法执行测试。为此,您可以在hub.docker.com上创建一个账户来提供您的镜像。这些镜像通常格式为<user>/<image>:<tag> - 例如,zanfranceschi/rinha-api:latest
。
上一届比赛中的一个常见错误是将镜像声明为本地存在。这对于构建镜像的人可能是正确的(在本地进行了构建),但对于执行测试的服务器来说并非如此!
重要! 必须将包含API源代码的存储库设为公开访问,并在提交的README.md
文件中提供信息。毕竟,后端擂台赛的主要目标是分享知识!
Ana的提交/拉取请求示例可能包含以下文件:├─ participantes/
| ├─ ana-01/
| | ├─ docker-compose.yml
| | ├─ nginx.config
| | ├─ sql/
| | | ├─ ddl.sql
| | | ├─ dml.sql
| | ├─ README.md
提交拉取请求的截止日期/时间是2024-03-10T23:59:59-03:00
。在此日期/时间之后,任何拉取请求都将被自动拒绝。
请注意,在截止日期/时间之前,您可以提交任意数量的拉取请求!
这里所说的"API"指的是为了使处理HTTP请求的服务能够运行而涉及的所有服务,如负载均衡器、数据库和HTTP服务器。
你的API至少需要包含以下服务:
flowchart TD G(压力测试 - Gatling) -.-> LB(负载均衡器 / 端口9999) subgraph 你的应用 LB -.-> API1(API - 实例01) LB -.-> API2(API - 实例02) API1 -.-> Db[(数据库)] API2 -.-> Db[(数据库)] end
注意:你可以使用额外的组件,如果你想的话。但请记住,CPU和内存的限制必须遵守以下规则:所有服务声明的限制总和不得超过1.5个CPU单位和550MB内存!请使用常识和诚信,不要添加一个关系型数据库和一个Redis,然后只使用Redis作为存储 - 毕竟,Rinha只是一个促进学习而非不公平竞争的小游戏。
在您的docker-compose.yml文件中,您应该限制所有服务,使它们的总和不超过以下限制:
deploy.resources.limits.cpu
1.5 – 所有服务之间分配的一个半CPU单位deploy.resources.limits.memory
550MB – 所有服务之间分配的550兆字节内存
注:请使用MB
作为内存计量单位;这样可以更容易验证限制。# docker-compose.yml文件中某个服务配置的部分示例 ... nginx: image: nginx:latest volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - api01 - api02 ports: - "9999:9999" deploy: resources: limits: cpus: "0.17" memory: "10MB" ...
以下仅为示例文件,以便你不必从零开始,如果遇到任何困难或只是想加快 API 的构建过程。显然,你可以根据自己的需要进行修改,但要遵守之前解释的所有限制。再次强调,你不一定要使用关系型数据库 - 以下示例仅作说明用途。
docker-compose.yml
version: "3.5" services: api01: &api # 请记住,你的 HTTP 服务必须托管在公开可访问的仓库中! # 例如:hub.docker.com image: ana/minha-api-matadora:latest hostname: api01 environment: - DB_HOSTNAME=db # 除了负载均衡器的端口外,不需要暴露任何其他端口, # 但人们通常会这样做以便在开发阶段测试他们的 API 并连接到数据库。 ports: - "8081:8080" depends_on: - db deploy: resources: limits: cpus: "0.6" memory: "200MB" api02: # 这个语法重用了 'api01' 中声明的内容。 <<: *api hostname: api02 environment: - DB_HOSTNAME=db ports: - "8082:8080" nginx: image: nginx:latest volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - api01 - api02 ports: # 负载均衡器必须暴露/使用 9999 端口! - "9999:9999" deploy: resources: limits: cpus: "0.17" memory: "10MB" db: image: postgres:latest hostname: db environment: - POSTGRES_PASSWORD=123 - POSTGRES_USER=admin - POSTGRES_DB=rinha ports: - "5432:5432" volumes: - ./script.sql:/docker-entrypoint-initdb.d/script.sql deploy: resources: limits: # 请注意,这里声明的所有服务限制总和 # 是 1.5 个 CPU 单位和 550MB 内存。 # 这里的分配只是一个例子 - 你可以根据需要进行分配。 cpus: "0.13" memory: "140MB" # 使用 `bridge` 模式应该适合测试中使用的负载。 # 上一版本受益于 host 模式,因为请求量相对较高,网络虚拟化成为瓶颈, # 但这种模式配置更复杂。你可以自由选择想要的模式, # 只要不与操作系统中常用的端口冲突即可。 networks: default: driver: bridge name: rinha-nginx-2024q1
script.sql
-- 在这里放置初始脚本 CREATE TABLE... DO $$ BEGIN INSERT INTO clientes (nome, limite) VALUES ('o barato sai caro', 1000 * 100), ('zan corp ltda', 800 * 100), ('les cruders', 10000 * 100), ('padaria joia de cocaia', 100000 * 100), ('kid mais', 5000 * 100); END; $$
nginx.conf
events { worker_connections 1000; } http { access_log off; sendfile on; upstream api { server api01:8080; server api02:8080; } server { listen 9999; # 还记得必须使用 9999 端口吗? location / { proxy_pass http://api; } } }
与上一版本一样,本次仍将使用Gatling工具进行性能测试。在开发阶段执行测试可以帮助发现潜在的问题和瓶颈,这一点非常重要。测试脚本可在本仓库的load-test目录中找到。
要了解环境详情(操作系统和软件版本),请访问测试环境规格。
请注意,测试将在Linux x64环境中执行。因此,如果您的开发环境使用不同的架构,您需要按以下方式构建Docker镜像:
$ docker buildx build --platform linux/amd64
例如:
$ docker buildx build --platform linux/amd64 -t ana/minha-api-matadora:latest .
以下是快速执行测试的说明:
$GATLING_HOME/bin/gatling.sh
和Windows上的%GATLING_HOME%\bin\gatling.bat
。./executar-teste-local.sh
脚本(如果在Windows上,则使用./executar-teste-local.ps1
)./executar-teste-local.sh
(如果在Windows上,则运行./executar-teste-local.ps1
)./load-test/user-files/results
中。请随意修改模拟以测试不同方面和场景。请不要在提交的pull request中包含这些更改!
不客气 :)
在上一届Rinha中,测试在容器启动后几秒钟就开始了,由于CPU和内存限制,并非所有服务都能在如此短的时间内准备好接收请求。在本届中,测试开始前,一个脚本将在最多40秒内每2秒检查一次API是否正确响应(通过GET /clientes/1/extrato
)。因此,请确保所有服务在40秒内能够接收请求!
模拟中包含了一个超出性能测试常规范围的余额/限额逻辑测试。我这样写只是因为后端Rinha 的特殊性。通常情况下,请避免在性能测试中这样做,因为这不是推荐的做法。逻辑测试应该与源代码一起以单元测试或集成测试的形式进行!
惊喜!:)
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。
字节跳动发布的AI编程神器IDE
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时 语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号