Workers + KV 연동으로 User-Agent 카운트하기
1. KV 네임스페이스 만들기
- Storage & Database - KV 메뉴로 이동합니다.
- +Create 을 버튼을 누릅니다.

- Name에 이름을 적당히 입력하고 Add 버튼을 누릅니다.

- KV 네임스페이스가 만들어지면 리스트에서 ID를 확인합니다.

2. Workers 생성하기
프로젝트를 생성합니다.
$ npm create cloudflare@latest
이후 인터렉티브하게 진행합니다.
프로젝트 이름(user-agent-kv) 을 입력합니다.
╭ Create an application with Cloudflare Step 1 of 3
│
╰ In which directory do you want to create your application? also used as application name
./user-agent-kv
Hello World example 을 선택합니다.
What would you like to start with?
● Hello World example
○ Framework Starter
○ Application Starter
○ Template from a GitHub repo
◁ Go back
Select from barebones examples to get started with Workers
Hello World Worker 를 선택합니다.
Which template would you like to use?
● Hello World Worker
○ Hello World Worker Using Durable Objects
◁ Go back
Get started with a basic Worker in the language of your choice
JavaScript 를 선택합니다.
Which language do you want to use?
○ TypeScript
● JavaScript
○ Python (beta)
◁ Go back
Yes 를 선택합니다.
Do you want to use git for version control?
Yes / No
No 를 선택합니다.
Do you want to deploy your application?
Yes / No
3. Workers 작성하기
프로젝트 디렉터리가 생성된 것을 확인하고 vscode 등으로 프로젝트를 엽니다.
wrangler.toml를 수정합니다.
[[kv_namespaces]]
binding = "USER_AGENT_STORE"
id = "631c190fe8014e6e97ce624d2974d8d3"
kv_namespaces 부분의 주석을 풀고 binding에 적당한 이름을 넣고, id 에는 만들어둔 KV네임스페이스의 ID를 입력합니다.
src/index.js 의 내용을 모두 지우고 아래 코드로 수정합니다.
위에서 binding 부분에 넣어준 바인딩이름을 env.XXX.put(), env.XXX.list(), env.XXX.get(), env.XXX.delete() 부분과 일치시킵니다.
export default {
async fetch(request, env, ctx) {
// 백그라운드 작업을 비동기적으로 실행
ctx.waitUntil(handleBackgroundTasks(request, env));
// 오리진 서버로 요청 전달
return fetch(request);
},
};
// 현재 시간 (UTC) 반환
const CURRENT_TIME = () => Date.now();
const ONE_HOUR = 60 * 60 * 1000; // 1시간 (밀리초)
// 1. User-Agent 저장 함수
async function storeUserAgent(request, env) {
const userAgent = request.headers.get("User-Agent") || "Unknown-UA";
const currentTime = CURRENT_TIME();
await env.USER_AGENT_STORE.put(userAgent, currentTime.toString());
}
// 2. 만료된 데이터 삭제 함수
async function cleanExpiredEntries(env) {
const keys = await env.USER_AGENT_STORE.list();
const now = CURRENT_TIME();
for (const entry of keys.keys) {
const storedTime = await env.USER_AGENT_STORE.get(entry.name);
if (storedTime) {
const timeElapsed = now - parseInt(storedTime, 10);
if (timeElapsed > ONE_HOUR) {
await env.USER_AGENT_STORE.delete(entry.name);
}
}
}
}
// 3. KV 데이터 개수 확인 함수
async function getDataCount(env) {
const keys = await env.USER_AGENT_STORE.list();
console.log(`현재 저장된 데이터 개수: ${keys.keys.length}`);
}
// 백그라운드 작업 실행 함수
async function handleBackgroundTasks(request, env) {
try {
await storeUserAgent(request, env); // User-Agent 저장
await cleanExpiredEntries(env); // 만료된 데이터 삭제
await getDataCount(env); // 데이터 개수 확인
} catch (error) {
console.error("백그라운드 작업 중 오류 발생:", error);
}
}
4. Workers 배포
배포합니다.
$ npm run deploy
배포된 Workers를 확인하고 해당 Worker 링크를 누릅니다.
Settings - Bindings 에서 KV namespace가 잘 바인딩 되어 있는지 확인합니다.
그런 후 Domains & Routes 에서 +Add 링크를 누릅니다.
Route 를 선택합니다.
Zone을 선택하고 어떤 경로로 요청이 들어오면 Workers가 실행될지 Route를 입력한 후 Add route 버튼을 누릅니다.
Route가 잘 설정되었는지 확인합니다.
5. 테스트
(예: cfa.bgfoo.com)
Logs 탭에서 로그를 확인합니다.
(로그표시에 시간지연이 좀 있습니다.)
KV 메뉴 - 해당 KV Namespace로 이동해서 KV Pairs를 확인합니다.
유저에이전트가 저장된 것을 확인할 수 있습니다.
6. Workers의 제한사항
아래 링크에서 확인할 수 있습니다.
7. KV의 제한사항
아래 링크에서 확인할 수 있습니다.