{"id":17870,"date":"2026-02-12T07:32:16","date_gmt":"2026-02-12T15:32:16","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=17870"},"modified":"2026-02-24T11:16:03","modified_gmt":"2026-02-24T19:16:03","slug":"build-a-rate-limiter-with-couchbase-eventing","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rate-limiter-with-couchbase-eventing\/","title":{"rendered":"Criar um limitador de taxa com eventos do Couchbase"},"content":{"rendered":"<h1>Introdu\u00e7\u00e3o<\/h1>\n<p>O Couchbase Server 8.0 apresenta um novo manipulador de fun\u00e7\u00e3o Eventing chamado OnDeploy, que permite que os clientes executem a l\u00f3gica de neg\u00f3cios durante a implanta\u00e7\u00e3o ou retomada da fun\u00e7\u00e3o Eventing sem exigir nenhuma muta\u00e7\u00e3o externa para acion\u00e1-la.<\/p>\n<p>Anteriormente, os clientes com casos de uso que precisavam executar qualquer l\u00f3gica antes de uma fun\u00e7\u00e3o Eventing ser implantada ou retomada tinham algumas op\u00e7\u00f5es, como:<\/p>\n<ol>\n<li>Realizar manualmente a configura\u00e7\u00e3o necess\u00e1ria por conta pr\u00f3pria.<\/li>\n<li>Automatize a configura\u00e7\u00e3o por meio de um script externo antes de acionar a implementa\u00e7\u00e3o ou a retomada da fun\u00e7\u00e3o Eventing.<\/li>\n<\/ol>\n<p>Esses dois m\u00e9todos s\u00e3o complicados e dependem de interven\u00e7\u00e3o externa ou manual.<\/p>\n<p>Os eventos de \u201cimplanta\u00e7\u00e3o\u201d e \u201cretomada\u201d no ciclo de vida da fun\u00e7\u00e3o Eventing marcam os pontos em que ela est\u00e1 prestes a iniciar o processamento de muta\u00e7\u00f5es. Isso faz com que a <code style=\"color: #83c694\">OnDeploy<\/code> adequado para injetar l\u00f3gica que exija a execu\u00e7\u00e3o de qualquer uma das seguintes atividades:<\/p>\n<ol>\n<li>Realize verifica\u00e7\u00f5es antes do voo para garantir que o ambiente esteja configurado corretamente.<\/li>\n<li>Configure caches (por exemplo, tabelas de consulta) para aumentar a efici\u00eancia.<\/li>\n<li>Enviar, coletar e processar dados de diferentes servi\u00e7os externos e do Couchbase.<\/li>\n<li>\u201cAuto-acionar\u201d a fun\u00e7\u00e3o Eventing depois que ela for implementada\/continuada, modificando pelo menos um documento em seu espa\u00e7o-chave de origem.\n<ol type=\"a\">\n<li>Essa muta\u00e7\u00e3o acionar\u00e1 sua <code style=\"color: #83c694\">Sobre a atualiza\u00e7\u00e3o<\/code> e\/ou <code style=\"color: #83c694\">OnDelete<\/code> manipulador.<\/li>\n<li>Esse \u00e9 um caso de uso avan\u00e7ado do <code style=\"color: #83c694\">OnDeploy<\/code> porque, tradicionalmente, a execu\u00e7\u00e3o da fun\u00e7\u00e3o Eventing era restrita a ser acionada somente quando ocorriam altera\u00e7\u00f5es em seu espa\u00e7o de chaves de origem por entidades que n\u00e3o fossem a pr\u00f3pria fun\u00e7\u00e3o Eventing ou pela expira\u00e7\u00e3o do cron\u00f4metro.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<h1>Limitador de taxa<\/h1>\n<p>Nesta postagem, criaremos um limitador de taxa robusto usando o <a href=\"https:\/\/en.wikipedia.org\/wiki\/Token_bucket\">algoritmo de token-bucket<\/a> e o servi\u00e7o Eventing do Couchbase. Ao longo do caminho, voc\u00ea ter\u00e1 experi\u00eancia pr\u00e1tica com o novo manipulador OnDeploy e descobrir\u00e1 como o Eventing simplifica a integra\u00e7\u00e3o com outros servi\u00e7os do Couchbase.<\/p>\n<h2>Projeto de alto n\u00edvel<\/h2>\n<h3>Dimensionamento multidimensional<\/h3>\n<p><span style=\"font-weight: 400\">O cluster de 6 n\u00f3s deve ter os seguintes mapeamentos de servi\u00e7os para n\u00f3s:<\/span><\/p>\n<table>\n<thead>\n<tr style=\"background-color: #fbce90\">\n<th>S.No.<\/th>\n<th>N\u00famero do n\u00f3<\/th>\n<th>Servi\u00e7o(s)<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f3f3f3\">\n<td>1.<\/td>\n<td>0<\/td>\n<td>Dados<\/td>\n<\/tr>\n<tr>\n<td>2.<\/td>\n<td>1<\/td>\n<td>Dados<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>3.<\/td>\n<td>2<\/td>\n<td>Dados<\/td>\n<\/tr>\n<tr>\n<td>4.<\/td>\n<td>3<\/td>\n<td>Eventos, consultas<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>5.<\/td>\n<td>4<\/td>\n<td>Eventos, consultas<\/td>\n<\/tr>\n<tr>\n<td>6.<\/td>\n<td>5<\/td>\n<td>Indexa\u00e7\u00e3o<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"padding-top: 15px\">Alguns pontos a serem observados sobre a configura\u00e7\u00e3o do cluster:<\/p>\n<ul style=\"list-style-type: disc\">\n<li>Usamos 3 n\u00f3s de servi\u00e7o de dados para garantir a redund\u00e2ncia por meio da replica\u00e7\u00e3o de dados.<\/li>\n<li>Executamos o servi\u00e7o Eventing em 2 n\u00f3s para aumentar o paralelismo da fun\u00e7\u00e3o Eventing.\n<ul style=\"list-style-type: circle;padding: 0px !important\">\n<li>Isso \u00e9 feito al\u00e9m de ter v\u00e1rios funcion\u00e1rios para nossa fun\u00e7\u00e3o de eventos.<\/li>\n<\/ul>\n<\/li>\n<li>Os servi\u00e7os com uso intenso de CPU, como Data e Eventing, devem ser mantidos em n\u00f3s de cluster separados.<\/li>\n<li>Precisamos do servi\u00e7o Query porque determinadas opera\u00e7\u00f5es, como a exclus\u00e3o de todos os documentos em um espa\u00e7o-chave, podem ser convenientemente executadas por meio do servi\u00e7o Query.<\/li>\n<li>Precisamos do servi\u00e7o de indexa\u00e7\u00e3o para criar \u00edndices prim\u00e1rios para o bucket Ephemeral.<\/li>\n<\/ul>\n<h3>Espa\u00e7os-chave<\/h3>\n<p>Nosso cluster deve ter os seguintes espa\u00e7os de chave:<\/p>\n<table>\n<tbody>\n<tr>\n<th>S.No.<\/th>\n<th>Nome do balde<\/th>\n<th>Tipo de ca\u00e7amba<\/th>\n<th>Escopo<\/th>\n<th>Cole\u00e7\u00e3o<\/th>\n<th>Descri\u00e7\u00e3o<\/th>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>1<\/td>\n<td>padr\u00e3o<\/td>\n<td>Couchbase<\/td>\n<td>Padr\u00e3o<\/td>\n<td>Padr\u00e3o<\/td>\n<td>\n<ol>\n<li style=\"font-size: 14px\">Usado como o \u201cescopo da fun\u00e7\u00e3o de eventos\u201d.<\/li>\n<li style=\"font-size: 14px\">Usado para armazenar os metadados das Eventing Functions.<\/li>\n<\/ol>\n<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_mobile<\/td>\n<td>-<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_query<\/td>\n<td>-<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>limitador de taxa<\/td>\n<td>Ef\u00eamera<\/td>\n<td>Padr\u00e3o<\/td>\n<td>Padr\u00e3o<\/td>\n<td>-<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_mobile<\/td>\n<td>-<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_query<\/td>\n<td>-<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>my-llm<\/td>\n<td>limites<\/td>\n<td>Armazena o documento que cont\u00e9m o mapeamento de limite de n\u00edvel para taxa.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>my-llm<\/td>\n<td>rastreador<\/td>\n<td>Armazene documentos de contador para acompanhar o uso de usu\u00e1rios individuais.<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>3<\/td>\n<td>my-llm<\/td>\n<td>Couchbase<\/td>\n<td>Padr\u00e3o<\/td>\n<td>Padr\u00e3o<\/td>\n<td>-<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_mobile<\/td>\n<td>-<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>_sistema<\/td>\n<td>_query<\/td>\n<td>-<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>usu\u00e1rios<\/td>\n<td>contas<\/td>\n<td>Armazene os detalhes da conta do usu\u00e1rio, incluindo o \u201cn\u00edvel\u201d.<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td><\/td>\n<td><\/td>\n<td><\/td>\n<td>usu\u00e1rios<\/td>\n<td>eventos<\/td>\n<td>Armazene os eventos do usu\u00e1rio que devem ter a taxa limitada com base no \u201cn\u00edvel\u201d do usu\u00e1rio.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p style=\"padding-bottom: 0px !important\">Observa\u00e7\u00e3o:<\/p>\n<ul>\n<li>O <code style=\"color: #83c694\">limitador de taxa<\/code> balde \u00e9 <code style=\"color: #83c694\">Ef\u00eamera<\/code> porque n\u00e3o precisamos manter esses dados. Usamos os dados desse bucket para rastrear o uso do limite de taxa por usu\u00e1rio e para armazenar em cache o mapeamento de camada para limite de taxa.<\/li>\n<\/ul>\n<h3>Pontos de extremidade externos da API REST<\/h3>\n<p>A fun\u00e7\u00e3o Eventing interage com pontos de extremidade de API externos que fornecem as seguintes funcionalidades:<\/p>\n<ol>\n<li>Forne\u00e7a o mapeamento mais recente de camada para limite de taxa.<\/li>\n<li>Aceitar modifica\u00e7\u00f5es no mapeamento de camada para limite de taxa.<\/li>\n<li>Aceitar solicita\u00e7\u00f5es de entrada que estejam dentro do limite de taxa do usu\u00e1rio por nossa fun\u00e7\u00e3o Eventing.\n<ol type=\"a\">\n<li>Neste projeto, nosso endpoint manter\u00e1 uma contagem dessas solicita\u00e7\u00f5es de entrada.<br \/>\nEssa contagem nos ajudar\u00e1 a verificar se nosso aplicativo limitador de taxa funciona conforme o esperado.<\/li>\n<\/ol>\n<\/li>\n<li>Forne\u00e7a o n\u00famero de solicita\u00e7\u00f5es recebidas que nossa fun\u00e7\u00e3o Eventing considerou estar dentro do limite de taxa do usu\u00e1rio.<\/li>\n<\/ol>\n<p>O link para a especifica\u00e7\u00e3o OpenAPI dos pontos de extremidade da API acima pode ser encontrado <a href=\"https:\/\/github.com\/couchbaselabs\/eventing-rate-limiter\/blob\/master\/openapi\/server-api-spec.yaml\">aqui<\/a>.<\/p>\n<p>Observa\u00e7\u00e3o: o programa em Go que hospeda esses pontos de extremidade da API REST est\u00e1 vinculado no Ap\u00eandice.<\/p>\n<h2>Design de baixo n\u00edvel<\/h2>\n<h3>Configura\u00e7\u00e3o da fun\u00e7\u00e3o Eventing<\/h3>\n<p>Abaixo est\u00e1 uma lista de todas as altera\u00e7\u00f5es que precisamos fazer nas configura\u00e7\u00f5es padr\u00e3o da fun\u00e7\u00e3o Eventing.<\/p>\n<p><strong>Espa\u00e7os-chave<\/strong><\/p>\n<table>\n<thead>\n<tr style=\"background-color: #fbce90\">\n<th>S.No.<\/th>\n<th>Campo<\/th>\n<th>Valor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f3f3f3\">\n<td>1.<\/td>\n<td>Escopo da fun\u00e7\u00e3o<\/td>\n<td>default._default<\/td>\n<\/tr>\n<tr>\n<td>2.<\/td>\n<td>Fonte Keyspace<\/td>\n<td>my-llm.users.events<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>3.<\/td>\n<td>Espa\u00e7o-chave de armazenamento para eventos<\/td>\n<td>default._default._default<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Configura\u00e7\u00f5es<\/strong><\/p>\n<table>\n<thead>\n<tr style=\"background-color: #fbce90\">\n<th>S.No.<\/th>\n<th>Campo<\/th>\n<th>Valor<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f3f3f3\">\n<td>1.<\/td>\n<td>Nome<\/td>\n<td>limitador de taxa my-llm<\/td>\n<\/tr>\n<tr>\n<td>2.<\/td>\n<td>Limite de alimenta\u00e7\u00e3o da implanta\u00e7\u00e3o<\/td>\n<td>A partir de agora<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>3.<\/td>\n<td>Descri\u00e7\u00e3o<\/td>\n<td>Essa fun\u00e7\u00e3o Eventing atua como um limitador de taxa.<\/td>\n<\/tr>\n<tr>\n<td>4.<\/td>\n<td>Trabalhadores<\/td>\n<td>10<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Amarra\u00e7\u00f5es de balde<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th rowspan=\"2\">S.No.<\/th>\n<th rowspan=\"2\">Balde<br \/>\nApelido<\/th>\n<th colspan=\"3\">Espa\u00e7o-chave<\/th>\n<th rowspan=\"2\">Acesso<\/th>\n<\/tr>\n<tr>\n<th>Balde<\/th>\n<th>Escopo<\/th>\n<th>Cole\u00e7\u00e3o<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f3f3f3\">\n<td>1.<\/td>\n<td class=\"left\">Contas de usu\u00e1rio<\/td>\n<td>my-llm<\/td>\n<td>usu\u00e1rios<\/td>\n<td>contas<\/td>\n<td>Somente leitura<\/td>\n<\/tr>\n<tr>\n<td>2.<\/td>\n<td class=\"left\">Limitador de taxa<\/td>\n<td>limitador de taxa<\/td>\n<td>my-llm<\/td>\n<td>rastreador<\/td>\n<td>Ler e escrever<\/td>\n<\/tr>\n<tr style=\"background-color: #f3f3f3\">\n<td>3.<\/td>\n<td class=\"left\">tierLimits<\/td>\n<td>limitador de taxa<\/td>\n<td>my-llm<\/td>\n<td>limites<\/td>\n<td>Ler e escrever<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Vincula\u00e7\u00f5es de URL<\/strong><\/p>\n<table>\n<thead>\n<tr>\n<th class=\"center\">S.No.<\/th>\n<th class=\"left\">Alias de URL<\/th>\n<th class=\"left\">URL<\/th>\n<th class=\"center\">Autentica\u00e7\u00e3o<\/th>\n<th class=\"left\">Nome de usu\u00e1rio<\/th>\n<th class=\"left\">Senha<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"background-color: #f3f3f3\">\n<td class=\"center\">1.<\/td>\n<td class=\"left\">llmEndpoint<\/td>\n<td class=\"left nowrap\">http:\/\/localhost:3054\/my-llm<\/td>\n<td class=\"center\" rowspan=\"2\">B\u00e1sico<\/td>\n<td class=\"left\" rowspan=\"2\">Eventos<\/td>\n<td class=\"left\" rowspan=\"2\">Eventos123<\/td>\n<\/tr>\n<tr>\n<td class=\"center\">2.<\/td>\n<td class=\"left\">tiersEndpoint<\/td>\n<td class=\"left nowrap\">http:\/\/localhost:3054\/tiers<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><strong>Observa\u00e7\u00e3o:<\/strong> As op\u00e7\u00f5es \u201cpermitir cookies\u201d e \u201cvalidar certificado SSL\u201d est\u00e3o desativadas.<\/p>\n<h3>Diagrama completo do fluxo de aplicativos<\/h3>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Complete-Application-Flow-Diagram.png\" alt=\"Complete Application Flow Diagram\" \/><\/p>\n<p>Este diagrama mostra as intera\u00e7\u00f5es entre os manipuladores da fun\u00e7\u00e3o Eventing, os pontos de extremidade da API REST externa e os espa\u00e7os de chave para se comportar como um limitador de taxa com base no algoritmo de token bucket.<br \/>\nNas se\u00e7\u00f5es a seguir, implementaremos o limitador de taxa passo a passo.<\/p>\n<h3><code style=\"color: #83c694\">OnDeploy<\/code> Configura\u00e7\u00e3o<\/h3>\n<h4>Obter e armazenar as camadas do ponto de extremidade da API REST externa<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Get-and-Store-the-Tiers-From-the-External-REST-API-Endpoint.png\" alt=\"Get and Store the Tiers From the External REST API Endpoint\" \/><\/p>\n<p>Quando o <code style=\"color: #83c694\">OnDeploy<\/code> come\u00e7a a ser executado, ele deve primeiro obter o mapeamento de camadas para limite de taxa do ponto de extremidade externo da API REST representado pelo <code style=\"color: #83c694\">tiersEndpoint<\/code> Vincula\u00e7\u00e3o de URL.<br \/>\nA resposta do <code style=\"color: #83c694\">\/tiers<\/code> A API REST externa ser\u00e1 um valor JSON que cont\u00e9m o mapeamento do nome da camada (do tipo <code style=\"color: #83c694\">Cordas<\/code>) para um limite de taxa por hora representado pela contagem total de solicita\u00e7\u00f5es permitidas por hora (ou seja, total_request_count) (do tipo <code style=\"color: #83c694\">n\u00famero<\/code>).<br \/>\nArmazenamos o mapeamento de camadas para limite de taxa no <code style=\"color: #83c694\">rate-limit.my-llm.limits<\/code> espa\u00e7o-chave.<\/p>\n<pre class=\"lang:default decode:true\">function OnDeploy(action) {\r\n    \/\/ ...\r\n\r\n    \/\/ GET the tiers from the `tiersEndpoint`\r\n    const response = curl('GET', tiersEndpoint);\r\n    if (response.status != 200) {\r\n        throw new Error(\"Error(Cannot get tiers): \" + JSON.stringify(response));\r\n    }\r\n    const tiers = response.body;\r\n    log(\"Successfully retrieved the tiers: \" + JSON.stringify(tiers));\r\n\r\n    \/\/ Write the tiers to the `tierLimits` keyspace, in the document with ID `limits`\r\n    tierLimits[\"limits\"] = tiers;\r\n\r\n    \/\/ ...\r\n\r\n    \/\/ Create a timer to run every 24 hours to refresh the tiers\r\n    let timeAfter24hours = new Date();\r\n    timeAfter24hours.setDate(timeAfter24hours.getDate() + 1);\r\n    log(\"Time after 24 hours is: \" + timeAfter24hours);\r\n\r\n    createTimer(updateTierCallback, timeAfter24hours, \"tier-updater\", {});\r\n\r\n   \/\/ ...\r\n}\r\n\r\n\/\/ Function to update the user tiers every 24 hours\r\nfunction updateTierCallback(context) {\r\n    log('From updateTierCallback: timer fired');\r\n\r\n    \/\/ GET the tiers from the `tiersEndpoint`\r\n    const response = curl('GET', tiersEndpoint);\r\n    if (response.status != 200) {\r\n        log(\"Error(Cannot get tiers): \" + JSON.stringify(response));\r\n    } else {\r\n        const tiers = response.body;\r\n        log(\"Successfully retrieved the tiers: \" + JSON.stringify(tiers));\r\n\r\n        \/\/ Write the tiers to the `tierLimits` keyspace, in the document with ID `limits`\r\n        tierLimits[\"limits\"] = tiers;\r\n    }\r\n\r\n    \/\/ Create a timer to run every 24 hours to refresh the tiers\r\n    let timeAfter24hours = new Date();\r\n    timeAfter24hours.setDate(timeAfter24hours.getDate() + 1);\r\n    log(\"Time after 24 hours is: \" + timeAfter24hours);\r\n\r\n    createTimer(updateTierCallback, timeAfter24hours, \"tier-updater\", {});\r\n}\r\n<\/pre>\n<h4>Redefinir todos os rastreadores de limite de taxa ao implantar<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Reset-All-Rate-Limit-Trackers-When-Deploying.png\" alt=\"Reset All Rate Limit Trackers When Deploying\" \/><\/p>\n<p>Em nosso aplicativo, modelamos a desimplanta\u00e7\u00e3o da fun\u00e7\u00e3o Eventing como um desligamento for\u00e7ado; portanto, durante sua implanta\u00e7\u00e3o, exclu\u00edmos todos os documentos que rastreiam o uso do limite de taxa dos usu\u00e1rios. Modelamos a pausa como uma suspens\u00e3o tempor\u00e1ria das atividades de limita\u00e7\u00e3o de taxa; portanto, n\u00e3o limpamos esses documentos no caso de retomada da fun\u00e7\u00e3o Eventing.<\/p>\n<p>Percebeu como tratamos as opera\u00e7\u00f5es de implementa\u00e7\u00e3o e retomada separadamente? <code style=\"color: #83c694\">OnDeploy<\/code> torna esses casos de uso poss\u00edveis porque o Eventing tamb\u00e9m passa um <code style=\"color: #83c694\">raz\u00e3o<\/code> no campo <code style=\"color: #83c694\">a\u00e7\u00e3o<\/code> para o objeto <code style=\"color: #83c694\">OnDeploy<\/code> para especificar se a fun\u00e7\u00e3o Eventing est\u00e1 sendo implantada ou retomada.<\/p>\n<pre class=\"lang:default decode:true\">function OnDeploy(action) {\r\n    \/\/ ...\r\n \r\n    \/\/ If we are deploying, then we should delete all the existing document in the keyspace `rateLimiter`\r\n    if (action.reason === \"deploy\") {\r\n        let results = N1QL(\"DELETE FROM `rate-limiter`.`my-llm`.tracker\");\r\n        results.close();\r\n        log(\"Deleted all the documents in the `rate-limiter`.`my-llm`.tracker keyspace as we are deploying!\");\r\n    }\r\n\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<h4>Redefinir os limites de taxa dos usu\u00e1rios a cada hora<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Reset-the-Users-Rate-Limits-Every-Hour.png\" alt=\"Reset the Users\u2019 Rate Limits Every Hour\" \/><\/p>\n<p>Como estamos implementando um algoritmo de token-bucket, redefinimos os limites de taxa dos usu\u00e1rios a cada hora usando temporizadores - uma funcionalidade do Eventing que \u00e9 essencial para o nosso caso de uso. Criamos o primeiro cron\u00f4metro no <code style=\"color: #83c694\">OnDeploy<\/code> para disparar ap\u00f3s uma hora. Quando o timer-callback for acionado, ele criar\u00e1 um novo timer para ser acionado ap\u00f3s uma hora, e assim por diante, criando um timer autorrecorrente que ser\u00e1 acionado a cada hora, desde que a fun\u00e7\u00e3o Eventing seja implantada.<\/p>\n<p>Observe que esse cron\u00f4metro n\u00e3o exigiu nenhuma muta\u00e7\u00e3o externa para acionar a fun\u00e7\u00e3o Eventing para cri\u00e1-lo. Tudo isso foi feito durante a implanta\u00e7\u00e3o\/retomada no sistema. Tudo isso foi feito durante a implanta\u00e7\u00e3o\/retomada no <code style=\"color: #83c694\">OnDeploy<\/code> manipulador.<\/p>\n<pre class=\"lang:default decode:true\">function OnDeploy(action) {\r\n    \/\/ ...\r\n\r\n    \/\/ Create a timer to run every 1 hour to reset user rate limits\r\n    let timeAfter1Hour = new Date();\r\n    timeAfter1Hour.setHours(timeAfter1Hour.getHours() + 1);\r\n    log(\"Time after 1 hour is: \" + timeAfter1Hour);\r\n\r\n    createTimer(resetRateLimiter, timeAfter1Hour, \"rate-limit-resetter\", {});\r\n\r\n    \/\/ ...\r\n}\r\n\r\n\/\/ Function to reset the rate limits for all users every 1 hour\r\nfunction resetRateLimiter(context) {\r\n    log('From resetRateLimiter: timer fired');\r\n\r\n    let results = N1QL(\"DELETE FROM `rate-limiter`.`my-llm`.tracker\");\r\n    results.close();\r\n\r\n    \/\/ Create a timer to run every 1 hour to reset user rate limits\r\n    let timeAfter1Hour = new Date();\r\n    timeAfter1Hour.setHours(timeAfter1Hour.getHours() + 1);\r\n    log(\"Time after 1 hour is: \" + timeAfter1Hour);\r\n\r\n    createTimer(resetRateLimiter, timeAfter1Hour, \"rate-limit-resetter\", {});\r\n}\r\n<\/pre>\n<h4>Atualizar os limites de taxa de n\u00edvel diariamente<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Refresh-Tier-Rate-Limits-Daily.png\" alt=\"Refresh Tier Rate Limits Daily\" \/><\/p>\n<p>Modelamos nosso aplicativo para permitir altera\u00e7\u00f5es no limite de taxa a cada 24 horas; portanto, nossa fun\u00e7\u00e3o Eventing deve extrair o mapeamento mais recente de camada para limite de taxa do endpoint externo da API REST a cada 24 horas para garantir que os limites de taxa corretos sejam aplicados aos nossos usu\u00e1rios.<\/p>\n<p>Novamente, usamos temporizadores de recorr\u00eancia autom\u00e1tica para obter o mapeamento mais recente de camada para limite de taxa a cada 24 horas.<\/p>\n<pre class=\"lang:default decode:true\">function OnDeploy(action) {\r\n    \/\/ ...\r\n\r\n    \/\/ Create a timer to run every 24 hours to refresh the tiers\r\n    let timeAfter24hours = new Date();\r\n    timeAfter24hours.setDate(timeAfter24hours.getDate() + 1);\r\n    log(\"Time after 24 hours is: \" + timeAfter24hours);\r\n\r\n    createTimer(updateTierCallback, timeAfter24hours, \"tier-updater\", {});\r\n\r\n    \/\/ ...\r\n}\r\n\r\n\/\/ Function to update the user tiers every 24 hours\r\nfunction updateTierCallback(context) {\r\n    log('From updateTierCallback: timer fired');\r\n\r\n    \/\/ GET the tiers from the `tiersEndpoint`\r\n    const response = curl('GET', tiersEndpoint);\r\n    if (response.status != 200) {\r\n        log(\"Error(Cannot get tiers): \" + JSON.stringify(response));\r\n    } else {\r\n        const tiers = response.body;\r\n        log(\"Successfully retrieved the tiers: \" + JSON.stringify(tiers));\r\n\r\n        \/\/ Write the tiers to the `tierLimits` keyspace, in the document with ID `limits`\r\n        tierLimits[\"limits\"] = tiers;\r\n    }\r\n\r\n    \/\/ Create a timer to run every 24 hours to refresh the tiers\r\n    let timeAfter24hours = new Date();\r\n    timeAfter24hours.setDate(timeAfter24hours.getDate() + 1);\r\n    log(\"Time after 24 hours is: \" + timeAfter24hours);\r\n\r\n    createTimer(updateTierCallback, timeAfter24hours, \"tier-updater\", {});\r\n}\r\n<\/pre>\n<h3><code style=\"color: #83c694\">Sobre a atualiza\u00e7\u00e3o<\/code> Configura\u00e7\u00e3o<\/h3>\n<h4>Manipula\u00e7\u00e3o de eventos do usu\u00e1rio<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Handling-User-Events.png\" alt=\"Handling User Events\" \/><\/p>\n<p>Nosso aplicativo ouvir\u00e1 os documentos de solicita\u00e7\u00e3o de entrada do <code style=\"color: #83c694\">my-llm.users.events<\/code> espa\u00e7o-chave. Esses documentos t\u00eam uma ID exclusiva e cont\u00eam dados no formato:<\/p>\n<pre class=\"lang:default decode:true\">{\r\n    \"user_id\": String,\r\n    \"respond_to\": String,\r\n    \"payload\": String,\r\n    \"header\": String\r\n}\r\n<\/pre>\n<p>Se a solicita\u00e7\u00e3o do usu\u00e1rio estiver dentro do limite de taxa, todos os dados do documento, exceto o user_id, ser\u00e3o enviados para o endpoint protegido pelo nosso limitador de taxa.<\/p>\n<h4>Leitura do n\u00edvel do usu\u00e1rio<\/h4>\n<p><img decoding=\"async\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Reading-the-Users-Tier.png\" alt=\"Reading the User\u2019s Tier\" \/><br \/>\nQuando o <code style=\"color: #83c694\">Sobre a atualiza\u00e7\u00e3o<\/code> \u00e9 acionado por um documento de evento de usu\u00e1rio de entrada da etapa anterior, devemos extrair o <code style=\"color: #83c694\">user_id<\/code> campo dele.<br \/>\nUsando o <code style=\"color: #83c694\">user_id<\/code> recuperaremos o documento de detalhes da conta do usu\u00e1rio a partir do campo <code style=\"color: #83c694\">my-llm.users.accounts<\/code> espa\u00e7o-chave. A partir desse documento, extrairemos o valor da vari\u00e1vel <code style=\"color: #83c694\">n\u00edvel<\/code> campo.<\/p>\n<pre class=\"lang:default decode:true\">function OnUpdate(doc, meta, xattrs) {\r\n    \/\/ ...\r\n\r\n    const user_id = doc.user_id;\r\n\r\n    let done = false;\r\n    while (!done) {\r\n        \/\/ Get the tier of the `user_id`\r\n        let userAccountsMeta = {\r\n            \"id\": user_id\r\n        };\r\n        let userAccountsResult = couchbase.get(userAccounts, userAccountsMeta, {\r\n            \"cache\": true\r\n        });\r\n        if (!userAccountsResult.success) {\r\n            throw new Error(\"Error(Unable to get the user's details): \" + JSON.stringify(userAccountsResult));\r\n        }\r\n        const tier = userAccountsResult.doc.tier;\r\n\r\n        \/\/ ...\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<h4>Leitura dos limites de taxa da camada<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Reading-the-Tiers-Rate-Limits.png\" alt=\"Reading the Tier\u2019s Rate Limits\" \/><\/p>\n<p>Obtemos os limites de taxa para a camada do usu\u00e1rio no documento que cont\u00e9m o mapeamento de camadas para limites de taxa, localizado no <code style=\"color: #83c694\">rate-limit.my-llm.limits<\/code> espa\u00e7o-chave.<\/p>\n<pre class=\"lang:default decode:true\">function OnUpdate(doc, meta, xattrs) {\r\n    \/\/ ...\r\n\r\n    while (!done) {\r\n        \/\/ ...\r\n\r\n        \/\/ Get the rate limit for the tier\r\n        let tierLimitsMeta = {\r\n            \"id\": \"limits\"\r\n        };\r\n        let tierLimitsResult = couchbase.get(tierLimits, tierLimitsMeta, {\r\n            \"cache\": true\r\n        });\r\n        if (!tierLimitsResult.success) {\r\n            throw new Error(\"Error(Unable to get the tier limits): \" + JSON.stringify(tierLimitsResult));\r\n        }\r\n        const rateLimit = tierLimitsResult.doc[tier];\r\n\r\n        \/\/ ...\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<h4>Decidir se \u00e9 necess\u00e1rio limitar a taxa da solicita\u00e7\u00e3o e atualizar o uso do limite de taxa do usu\u00e1rio<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Decide-Whether-to-Rate-Limit-the-Request-Update-the-Users-Rate-Limit-Usage.png\" alt=\"Decide Whether to Rate Limit the Request &amp; Update the User\u2019s Rate Limit Usage\" \/><\/p>\n<p>Dado o limite de taxa do usu\u00e1rio, agora verificamos seu uso atual para decidir se ele pode fazer uma solicita\u00e7\u00e3o. O limitador de taxa rastreia o uso de cada usu\u00e1rio com um documento contador no <code style=\"color: #83c694\">rate-limit.my-llm.tracker<\/code> espa\u00e7o-chave. Criamos esse contra-documento sob demanda para cada <code style=\"color: #83c694\">user_id<\/code> para armazenar a contagem de solicita\u00e7\u00f5es desse usu\u00e1rio para a janela atual, antes que o limite do token bucket seja atualizado. Se o uso de um usu\u00e1rio atingir ou exceder o limite de sua camada, bloquearemos sua solicita\u00e7\u00e3o. Caso contr\u00e1rio, n\u00f3s a encaminhamos para o endpoint protegido. Por fim, atualizamos o uso do limite de taxa do usu\u00e1rio em seu documento de contador correspondente no <code style=\"color: #83c694\">rate-limit.my-llm.tracker<\/code> espa\u00e7o-chave.<\/p>\n<pre class=\"lang:default decode:true\">function OnUpdate(doc, meta, xattrs) {\r\n    \/\/ ...\r\n\r\n    while (!done) {\r\n        \/\/ ...\r\n\r\n        \/\/ Try to get the rate limit count for the `user_id`\r\n        const userIDMeta = {\r\n            \"id\": user_id\r\n        };\r\n        const result = couchbase.get(rateLimiter, userIDMeta);\r\n\r\n        \/\/ If the rate limit count for the `user_id` does not exist. Try to create it.\r\n        while (!result.success) {\r\n            couchbase.insert(rateLimiter, userIDMeta, {\r\n                \"count\": 0\r\n            });\r\n            result = couchbase.get(rateLimiter, userIDMeta);\r\n        }\r\n\r\n        \/\/ Assign the counter document's `count` and `meta` to local variables for convenience\r\n        const counterDocCount = result.doc.count;\r\n        const counterDocMeta = result.meta;\r\n\r\n        \/\/ Check if the counter has hit the rate limit\r\n        \/\/ We use &gt;= instead of == to handle the edge case where the tier limits have reduced\r\n        \/\/ but the tier tracker documents have not yet been deleted.\r\n        if (counterDocCount &gt;= rateLimit) {\r\n            log(\"User with ID '\" + user_id + \"' hit their rate limit of \" + rateLimit + \"!\");\r\n            done = true;\r\n            continue;\r\n        }\r\n\r\n        \/\/ Update the count in the document\r\n        let res = couchbase.mutateIn(rateLimiter, counterDocMeta, [\r\n            couchbase.MutateInSpec.replace(\"count\", counterDocCount + 1),\r\n        ]);\r\n        \/\/ ...\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<h4>Enviar a solicita\u00e7\u00e3o \u201cdentro do limite\u201d para o ponto de extremidade desejado<\/h4>\n<p><img decoding=\"async\" style=\"border: 1px solid\" src=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Send-the-within-the-limit-Request-to-the-Desired-Endpoint.png\" alt=\"Send the \u201cwithin the limit\u201d Request to the Desired Endpoint\" \/><\/p>\n<p>As solicita\u00e7\u00f5es do usu\u00e1rio, dentro dos limites de taxa da camada correspondente, s\u00e3o enviadas para o endpoint da API REST protegido por nosso limitador de taxa.<\/p>\n<pre class=\"lang:default decode:true\">function OnUpdate(doc, meta, xattrs) {\r\n    \/\/ ...\r\n\r\n    while (!done) {\r\n        \/\/ ...\r\n\r\n        done = res.success;\r\n        if (done) {\r\n            \/\/ POST the request to the `llmEndpoint`\r\n            delete doc.user_id;\r\n            const response = curl('POST', llmEndpoint, doc);\r\n            if (response.status != 200) {\r\n                throw new Error(\"Error(MyLLM endpoint is not working): \" + response.status);\r\n            }\r\n        }\r\n    }\r\n    \/\/ ...\r\n}\r\n<\/pre>\n<h1>Testando nosso aplicativo<\/h1>\n<p>Agora que implementamos nosso limitador de taxa, podemos criar o ambiente para execut\u00e1-lo e test\u00e1-lo:<\/p>\n<ol>\n<li>Execute o programa Go para carregar um conjunto de amostra de 100 usu\u00e1rios.<\/li>\n<li>Execute o programa Go para iniciar o servidor HTTP que fornece as APIs REST externas com as quais nossa fun\u00e7\u00e3o Eventing interage.<\/li>\n<li>Implante a fun\u00e7\u00e3o Eventing.<\/li>\n<li>Para acionar a fun\u00e7\u00e3o Eventing, devemos executar o programa Go para carregar documentos de eventos do usu\u00e1rio em seu espa\u00e7o de chave de origem, ou seja, <code style=\"color: #83c694\">my-llm.users.events<\/code>.<\/li>\n<li>Para obter o n\u00famero de solicita\u00e7\u00f5es de usu\u00e1rios que chegam ao endpoint externo da API REST protegido por nosso limitador de taxa, voc\u00ea deve enviar um <code style=\"color: #83c694\">OBTER<\/code> solicita\u00e7\u00e3o para o <code style=\"color: #83c694\">\/my-llm<\/code> ponto final.<\/li>\n<\/ol>\n<h1>Conclus\u00e3o<\/h1>\n<p>Esta postagem mostrou como usar o novo manipulador de eventos do Couchbase, <code style=\"color: #83c694\">OnDeploy<\/code>, para criar um limitador de taxa de token-bucket - destacando o poder e a flexibilidade do Couchbase Eventing para desenvolver solu\u00e7\u00f5es integradas e aut\u00f4nomas.<br \/>\nDe forma mais ampla, ele demonstra uma mudan\u00e7a no desenvolvimento de aplicativos: criar aplicativos a partir do pr\u00f3prio banco de dados. Isso permite solu\u00e7\u00f5es personalizadas para diversos requisitos, tudo dentro da plataforma Couchbase.<\/p>\n<h1>Ap\u00eandice<\/h1>\n<p>C\u00f3digo completo de eventos: <a href=\"https:\/\/github.com\/couchbaselabs\/eventing-rate-limiter\/blob\/master\/eventing\/eventing-function.js\">Clique aqui<\/a><br \/>\nC\u00f3digo Go do servidor: <a href=\"https:\/\/github.com\/couchbaselabs\/eventing-rate-limiter\/blob\/master\/server\/server.go\">Clique aqui<\/a><br \/>\nC\u00f3digo Go do cliente: <a href=\"https:\/\/github.com\/couchbaselabs\/eventing-rate-limiter\/blob\/master\/event-generator\/event-generator.go\">Clique aqui<\/a><br \/>\nC\u00f3digo Go do carregador de usu\u00e1rio: <a href=\"https:\/\/github.com\/couchbaselabs\/eventing-rate-limiter\/blob\/master\/user-loader\/user-loader.go\">Clique aqui<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Introduction Couchbase Server 8.0 introduces a new Eventing function handler called OnDeploy that allows customers to run business logic during Eventing function deployment or resumption without requiring any external mutation to trigger it. Earlier, customers with use cases that needed [&hellip;]<\/p>","protected":false},"author":85695,"featured_media":17881,"comment_status":"open","ping_status":"open","sticky":true,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1816],"tags":[],"ppma_author":[10171],"class_list":["post-17870","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v26.8) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Build a Rate Limiter With Couchbase Eventing - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rate-limiter-with-couchbase-eventing\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Build a Rate Limiter With Couchbase Eventing\" \/>\n<meta property=\"og:description\" content=\"Introduction Couchbase Server 8.0 introduces a new Eventing function handler called OnDeploy that allows customers to run business logic during Eventing function deployment or resumption without requiring any external mutation to trigger it. Earlier, customers with use cases that needed [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rate-limiter-with-couchbase-eventing\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-02-12T15:32:16+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-02-24T19:16:03+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1256\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Rishit Chaudhary, Software Engineer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Rishit Chaudhary, Software Engineer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/\"},\"author\":{\"name\":\"Rishit Chaudhary, Software Engineer\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a63068d4f974ee8c1df6808fd7ad0d7d\"},\"headline\":\"Build a Rate Limiter With Couchbase Eventing\",\"datePublished\":\"2026-02-12T15:32:16+00:00\",\"dateModified\":\"2026-02-24T19:16:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/\"},\"wordCount\":1657,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png\",\"articleSection\":[\"Couchbase Server\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/\",\"name\":\"Build a Rate Limiter With Couchbase Eventing - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png\",\"datePublished\":\"2026-02-12T15:32:16+00:00\",\"dateModified\":\"2026-02-24T19:16:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png\",\"width\":2400,\"height\":1256},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Build a Rate Limiter With Couchbase Eventing\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a63068d4f974ee8c1df6808fd7ad0d7d\",\"name\":\"Rishit Chaudhary, Software Engineer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/af670362d7fe103aec32309e743e0794\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg\",\"caption\":\"Rishit Chaudhary, Software Engineer\"},\"url\":\"https:\/\/www.couchbase.com\/blog\/pt\/author\/rishitchaudhary\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Build a Rate Limiter With Couchbase Eventing - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rate-limiter-with-couchbase-eventing\/","og_locale":"pt_BR","og_type":"article","og_title":"Build a Rate Limiter With Couchbase Eventing","og_description":"Introduction Couchbase Server 8.0 introduces a new Eventing function handler called OnDeploy that allows customers to run business logic during Eventing function deployment or resumption without requiring any external mutation to trigger it. Earlier, customers with use cases that needed [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/build-a-rate-limiter-with-couchbase-eventing\/","og_site_name":"The Couchbase Blog","article_published_time":"2026-02-12T15:32:16+00:00","article_modified_time":"2026-02-24T19:16:03+00:00","og_image":[{"width":2400,"height":1256,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png","type":"image\/png"}],"author":"Rishit Chaudhary, Software Engineer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Rishit Chaudhary, Software Engineer","Est. reading time":"10 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/"},"author":{"name":"Rishit Chaudhary, Software Engineer","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a63068d4f974ee8c1df6808fd7ad0d7d"},"headline":"Build a Rate Limiter With Couchbase Eventing","datePublished":"2026-02-12T15:32:16+00:00","dateModified":"2026-02-24T19:16:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/"},"wordCount":1657,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png","articleSection":["Couchbase Server"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/","url":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/","name":"Build a Rate Limiter With Couchbase Eventing - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png","datePublished":"2026-02-12T15:32:16+00:00","dateModified":"2026-02-24T19:16:03+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/02\/Build-a-Rate-Limiter-With-Couchbase-Eventing.png","width":2400,"height":1256},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/build-a-rate-limiter-with-couchbase-eventing\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Build a Rate Limiter With Couchbase Eventing"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/a63068d4f974ee8c1df6808fd7ad0d7d","name":"Rishit Chaudhary, engenheiro de software","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/af670362d7fe103aec32309e743e0794","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg","caption":"Rishit Chaudhary, Software Engineer"},"url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/rishitchaudhary\/"}]}},"authors":[{"term_id":10171,"user_id":85695,"is_guest":0,"slug":"rishitchaudhary","display_name":"Rishit Chaudhary, Software Engineer","avatar_url":{"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg","url2x":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2026\/01\/Rishit-Chaudhary.jpeg"},"0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/17870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/85695"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=17870"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/17870\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/17881"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=17870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=17870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=17870"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=17870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}