SvelteKit 앱이 이메일 전송, 이미지 크기 조정, 데이터 처리 등의 작업에 어려움을 겪고 있나요? BullMQ를 사용하면 이러한 무거운 작업을 백그라운드로 오프로드하고 앱을 매우 빠른 속도로 유지할 수 있습니다. 이 게시물에서는 전문가처럼 설정하고 실제 작업을 처리하는 방법을 보여 드리겠습니다. 뛰어들어 보세요!
tl;dr Hooks.server.js에서 BullMQ 작업자를 설정합니다. 예시를 확인해보세요
BullMQ는 Redis로 작업 대기열을 생성하고 관리하기 위한 Node.js 라이브러리입니다. 시간이 많이 소요되는 작업을 백그라운드에서 효율적으로 실행하는 데 도움이 됩니다. BullMQ는 재시도, 작업 예약, 동시성 제어 등의 기능이 내장되어 있어 앱의 복잡한 워크플로를 간단하고 안정적으로 처리할 수 있습니다.
먼저 ioredis(node.js용 Redis 클라이언트)와 Bullmq를 설치합니다.
pnpm i -D ioredis bullmq
Vercel과 같은 서버리스 환경에서 Bullmq 대기열에 작업을 추가할 수 있더라도 작업자는 기존의 오래 지속되는 node.js 서버에서 실행되어야 합니다. 따라서 어댑터 자동을 어댑터 노드로 교체하세요:
pnpm rm @sveltejs/adapter-auto && pnpm i -D @sveltejs/adapter-node
새로 설치된 노드 어댑터로 Svelte 구성(svelte.config.js)을 업데이트하는 것을 잊지 마세요.
다음으로 BullMQ 작업 대기열과 해당 프로세서를 설정해 보겠습니다. src/lib/server/ 디렉터리에 .js 파일을 만듭니다.
// src/lib/server/background-jobs.js import { REDIS_URL } from "$env/static/private"; import { Queue, Worker } from "bullmq"; import IORedis from "ioredis"; const Q_NAME = "q"; export const jobsQueue = new Queue(Q_NAME, { connection: new IORedis(REDIS_URL), }); const sleep = (t) => new Promise((resolve) => setTimeout(resolve, t * 100)); export const setupBullMQProcessor = () => { new Worker( Q_NAME, async (job) => { for (let i = 0; i <= 100; i++) { await sleep(Math.random()); await job.updateProgress(i); await job.log(`Processing job at interval ${i}`); if (Math.random() * 200 < 1) throw new Error(`Random error at ${i}`); } return `This is the return value of job (${job.id})`; }, // https://docs.bullmq.io/bull/patterns/persistent-connections#maxretriesperrequest { connection: new IORedis(REDIS_URL, { maxRetriesPerRequest: null }) } ); };
여기서 큐 Q_NAME의 작업을 수신하고 처리하기 위해 BullMQ 작업자를 인스턴스화하는 유틸리티 함수도 만들었습니다.
hoos.server.js 파일에서 최상위 수준이나 init 후크 내에서 이 함수를 호출해야 합니다.
// src/hooks.server.js // ... import { building } from "$app/environment"; import { setupBullMQProcessor } from "$lib/server/background-jobs"; // ... if (!building) { setupBullMQProcessor(); } // ...
!building 검사는 빌드 중에 작업자 설정(그리고 Redis 연결)을 건너뛰어 프로세스 속도를 높입니다.
? BullMQ는 이제 SvelteKit 앱에서 사용할 준비가 되었습니다 ?
설정을 테스트하기 위해 작업을 대기열에 추가하는 POST 엔드포인트를 생성해 보겠습니다.
// src/routes/+server.ts import { jobsQueue } from "$lib/server/background-jobs"; export const POST = async () => { const { id: jobId } = await jobsQueue.add("job", {}); /* The following code passes the job's progress to the client as a stream. If you don't need to update the client with the progress, you can skip the following. You can also use web-sockets or polling for that. */ const stream = new ReadableStream({ async pull(controller) { const job = await jobsQueue.getJob(jobId); controller.enqueue( JSON.stringify( job.failedReason ? { error: job.failedReason } : job.returnvalue ? { data: job.returnvalue } : { progress: job.progress } ) ); controller.enqueue("\n"); if (job.finishedOn) { controller.close(); } // wait for 1-second before sending the next status update await new Promise((r) => setTimeout(r, 1e3)); }, }); return new Response(stream, { headers: { "content-type": "text/plain" }, }); };
그리고 프런트엔드에서 위 엔드포인트를 트리거하고 이어서 작업 상태를 표시하는 버튼을 추가해 보겠습니다.
<!-- src/routes/+page.svelte --> <script> let result = $state(); $inspect(result); const handleClick = async () => { const response = await fetch("/", { method: "post" }); const reader = await response.body.getReader(); while (true) { const { done, value } = await reader.read(); if (done) break; result = JSON.parse(new TextDecoder().decode(value)); } setTimeout(() => (result = undefined), 3e3); }; </script> {#if result?.error} <div> <p>Here is the output:</p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173785153552047.jpg" class="lazy" alt="background jobs demo using sveltekit and bullmq" loading="lazy" style="max-width:90%" style="max-width:90%" data-animated="true"></p> <hr> <h3> Bonus ? </h3> <p>You can also mount a bull-board dashboard in your SvelteKit app for easy monitoring of background jobs.</p> <p>Install bull-board dependencies<br> </p> <pre class="brush:php;toolbar:false">pnpm i -D @bull-board/api @bull-board/hono @hono/node-server hono
hoos.server.js를 수정하세요.
// src/hooks.server.js import { building } from "$app/environment"; import { jobsQueue, setupBullMQProcessor } from "$lib/server/background-jobs"; import { createBullBoard } from "@bull-board/api"; import { BullMQAdapter } from "@bull-board/api/bullMQAdapter"; import { HonoAdapter } from "@bull-board/hono"; import { serveStatic } from "@hono/node-server/serve-static"; import { Hono } from "hono"; if (!building) { setupBullMQProcessor(); } const bullboard = (() => { const serverAdapter = new HonoAdapter(serveStatic); createBullBoard({ queues: [new BullMQAdapter(jobsQueue)], serverAdapter, }); const app = new Hono({ strict: false }); const basePath = "/jobs"; serverAdapter.setBasePath(basePath); app.route(basePath, serverAdapter.registerPlugin()); return app; })(); export const handle = async ({ event, resolve }) => { if (event.url.pathname.match(/^\/jobs($|\/)/)) { return bullboard.fetch(event.request); } return resolve(event); };
그런 다음
위 내용은 BullMQ를 사용한 SvelteKit의 백그라운드 작업의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!