> 웹 프론트엔드 > JS 튜토리얼 > BullMQ를 사용한 SvelteKit의 백그라운드 작업

BullMQ를 사용한 SvelteKit의 백그라운드 작업

Linda Hamilton
풀어 주다: 2025-01-26 08:32:11
원래의
278명이 탐색했습니다.

SvelteKit 앱이 이메일 전송, 이미지 크기 조정, 데이터 처리 등의 작업에 어려움을 겪고 있나요? BullMQ를 사용하면 이러한 무거운 작업을 백그라운드로 오프로드하고 앱을 매우 빠른 속도로 유지할 수 있습니다. 이 게시물에서는 전문가처럼 설정하고 실제 작업을 처리하는 방법을 보여 드리겠습니다. 뛰어들어 보세요!

tl;dr Hooks.server.js에서 BullMQ 작업자를 설정합니다. 예시를 확인해보세요

BullMQ란 무엇입니까?

BullMQ는 Redis로 작업 대기열을 생성하고 관리하기 위한 Node.js 라이브러리입니다. 시간이 많이 소요되는 작업을 백그라운드에서 효율적으로 실행하는 데 도움이 됩니다. BullMQ는 재시도, 작업 예약, 동시성 제어 등의 기능이 내장되어 있어 앱의 복잡한 워크플로를 간단하고 안정적으로 처리할 수 있습니다.

1단계: 종속성 설치

먼저 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)을 업데이트하는 것을 잊지 마세요.

2단계: 작업 대기열 및 프로세서 설정

다음으로 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);
};

로그인 후 복사

그런 다음 /jobs를 방문하여 게시판 대시보드를 확인하세요

bull-board dashboard

위 내용은 BullMQ를 사용한 SvelteKit의 백그라운드 작업의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿