Công việc nền tảng NodeJS
Phân phối công việc bị trì hoãn trong nodejs. Resque là một hệ thống công việc nền được hỗ trợ bởi Redis (phiên bản 2. 6. 0 trở lên bắt buộc). Nó bao gồm hàng đợi ưu tiên, plugin, khóa, công việc bị trì hoãn, v.v. Dự án này rất có ý kiến nhưng tương thích với API với Resque và Sidekiq (hãy cẩn thận). Chúng tôi cũng triển khai một số plugin Resque phổ biến, bao gồm resque-scheduler và resque-retry Show
Tài liệu API đầy đủ cho gói này được tạo tự động từ options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };4 thông qua nhánh typedoc và được xuất bản lên https. // nút-resque. anh hùng hành động. com/ Nhà máy Resque (Cách thức hoạt động)Tổng quanResque là một hệ thống xử lý tác vụ dựa trên hàng đợi có thể được coi là một nhà máy kiểu "Kanban". Công nhân trong nhà máy này mỗi người chỉ có thể làm một Công việc tại một thời điểm. Họ lấy Công việc từ Hàng đợi và hoàn thành chúng (hoặc thất bại). Mỗi công việc có hai phần. hướng dẫn về cách hoàn thành công việc (hàm options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };5) và bất kỳ thông tin đầu vào nào cần thiết để hoàn thành Công việc hàng đợiTrong ví dụ về nhà máy của chúng tôi, Hàng đợi tương tự như băng tải. Công việc được đặt trên dây đai (Hàng đợi) và được giữ theo thứ tự chờ Công nhân đến lấy chúng. Có ba loại hàng đợi. hàng đợi công việc thường xuyên, hàng đợi công việc bị trì hoãn và hàng đợi công việc thất bại. Hàng đợi công việc bị trì hoãn chứa các định nghĩa công việc dự định sẽ được thực hiện tại hoặc trong một thời gian xác định. Hàng đợi Công việc Thất bại là nơi Công nhân đặt bất kỳ Công việc nào bị lỗi trong quá trình thực hiện công nhânCông nhân của chúng tôi là trái tim của nhà máy. Mỗi Công nhân được chỉ định một hoặc nhiều Hàng đợi để kiểm tra công việc. Sau khi nhận một Công việc từ Hàng đợi, Công nhân cố gắng hoàn thành Công việc. Nếu thành công, họ quay lại để kiểm tra thêm công việc từ Hàng đợi. Tuy nhiên, nếu có lỗi, Công nhân sẽ ghi lại công việc và thông tin đầu vào của công việc đó trong Hàng đợi Công việc Không thành công trước khi quay lại để thực hiện thêm công việc Người lập kế hoạchBộ lập lịch có thể được coi là một loại Công nhân chuyên biệt. Không giống như các Công nhân khác, Trình lập lịch biểu không thực thi bất kỳ Công việc nào, thay vào đó, nó quản lý Hàng đợi Công việc bị trì hoãn. Vì các định nghĩa Công việc được thêm vào Hàng đợi Công việc bị Trì hoãn, chúng phải chỉ định khi nào chúng có thể sẵn sàng để thực hiện. Bộ lập lịch liên tục kiểm tra xem liệu có bất kỳ Công việc bị trì hoãn nào đã sẵn sàng để thực thi hay không. Khi một Công việc bị trì hoãn sẵn sàng để thực thi, Trình lập lịch biểu sẽ đặt một phiên bản mới của Công việc đó vào Hàng đợi đã xác định của nó Tài liệu APIBạn có thể đọc tài liệu API cho Node Resque @ node-resque. anh hùng hành động. com. Chúng được tạo tự động từ nhánh chính thông qua TypeDoc Ghi chú phiên bản
Cách sử dụngTôi học tốt nhất bằng các ví dụ import { Worker, Plugins, Scheduler, Queue } from "node-resque"; async function boot() { // //////////////////////// // SET UP THE CONNECTION // // //////////////////////// const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: null, port: 6379, database: 0, // namespace: 'resque', // looping: true, // options: {password: 'abc'}, }; // /////////////////////////// // DEFINE YOUR WORKER TASKS // // /////////////////////////// let jobsToComplete = 0; const jobs = { add: { plugins: [Plugins.JobLock], pluginOptions: { JobLock: { reEnqueue: true }, }, perform: async (a, b) => { await new Promise((resolve) => { setTimeout(resolve, 1000); }); jobsToComplete--; tryShutdown(); const answer = a + b; return answer; }, }, subtract: { perform: (a, b) => { jobsToComplete--; tryShutdown(); const answer = a - b; return answer; }, }, }; // just a helper for this demo async function tryShutdown() { if (jobsToComplete === 0) { await new Promise((resolve) => { setTimeout(resolve, 500); }); await scheduler.end(); await worker.end(); process.exit(); } } // ///////////////// // START A WORKER // // ///////////////// const worker = new Worker( { connection: connectionDetails, queues: ["math", "otherQueue"] }, jobs ); await worker.connect(); worker.start(); // //////////////////// // START A SCHEDULER // // //////////////////// const scheduler = new Scheduler({ connection: connectionDetails }); await scheduler.connect(); scheduler.start(); // ////////////////////// // REGISTER FOR EVENTS // // ////////////////////// worker.on("start", () => { console.log("worker started"); }); worker.on("end", () => { console.log("worker ended"); }); worker.on("cleaning_worker", (worker, pid) => { console.log(`cleaning old worker ${worker}`); }); worker.on("poll", (queue) => { console.log(`worker polling ${queue}`); }); worker.on("ping", (time) => { console.log(`worker check in @ ${time}`); }); worker.on("job", (queue, job) => { console.log(`working job ${queue} ${JSON.stringify(job)}`); }); worker.on("reEnqueue", (queue, job, plugin) => { console.log(`reEnqueue job (${plugin}) ${queue} ${JSON.stringify(job)}`); }); worker.on("success", (queue, job, result, duration) => { console.log( `job success ${queue} ${JSON.stringify(job)} >> ${result} (${duration}ms)` ); }); worker.on("failure", (queue, job, failure, duration) => { console.log( `job failure ${queue} ${JSON.stringify( job )} >> ${failure} (${duration}ms)` ); }); worker.on("error", (error, queue, job) => { console.log(`error ${queue} ${JSON.stringify(job)} >> ${error}`); }); worker.on("pause", () => { console.log("worker paused"); }); scheduler.on("start", () => { console.log("scheduler started"); }); scheduler.on("end", () => { console.log("scheduler ended"); }); scheduler.on("poll", () => { console.log("scheduler polling"); }); scheduler.on("leader", () => { console.log("scheduler became leader"); }); scheduler.on("error", (error) => { console.log(`scheduler error >> ${error}`); }); scheduler.on("cleanStuckWorker", (workerName, errorPayload, delta) => { console.log( `failing ${workerName} (stuck for ${delta}s) and failing job ${errorPayload}` ); }); scheduler.on("workingTimestamp", (timestamp) => { console.log(`scheduler working timestamp ${timestamp}`); }); scheduler.on("transferredJob", (timestamp, job) => { console.log(`scheduler enquing job ${timestamp} >> ${JSON.stringify(job)}`); }); // ////////////////////// // CONNECT TO A QUEUE // // ////////////////////// const queue = new Queue({ connection: connectionDetails }, jobs); queue.on("error", function (error) { console.log(error); }); await queue.connect(); await queue.enqueue("math", "add", [1, 2]); await queue.enqueue("math", "add", [1, 2]); await queue.enqueue("math", "add", [2, 3]); await queue.enqueueIn(3000, "math", "subtract", [2, 1]); jobsToComplete = 4; } boot(); // and when you are done // await queue.end() // await scheduler.end() // await worker.end() Giao diện yêu cầu nút. Hàng đợi, Công nhân và Trình lập lịch biểuCó 3 lớp học chính trong options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };6. Hàng đợi, Công nhân và Trình lập lịch biểu
Tùy chọn cấu hình
options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, }; Lưu ý rằng khi sử dụng hàng đợi const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end()7
Băm cấu hình được chuyển đến const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end()8, const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end()9 hoặc // assume you already initialized redis client before // the "redis" key can be IORedis.Redis or IORedis.Cluster instance const redisClient = new Redis(); const connectionDetails = { redis: redisClient }; // or const redisCluster = new Cluster(); const connectionDetails = { redis: redisCluster }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done await worker.end();0 cũng có thể có tùy chọn // assume you already initialized redis client before // the "redis" key can be IORedis.Redis or IORedis.Cluster instance const redisClient = new Redis(); const connectionDetails = { redis: redisClient }; // or const redisCluster = new Cluster(); const connectionDetails = { redis: redisCluster }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done await worker.end();1 const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end() Bạn cũng có thể chuyển trực tiếp ứng dụng khách redis // assume you already initialized redis client before // the "redis" key can be IORedis.Redis or IORedis.Cluster instance const redisClient = new Redis(); const connectionDetails = { redis: redisClient }; // or const redisCluster = new Cluster(); const connectionDetails = { redis: redisCluster }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done await worker.end(); ghi chú
Nếu bạn muốn tìm hiểu thêm về cách chạy Node-Resque với docker, vui lòng xem các ví dụ tại đây. https. //github. com/actionhero/node-resque/tree/master/examples/docker const name = os.hostname() + ":" + process.pid + "+" + counter; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math", name: name }, jobs ); Worker#performInlineKHÔNG SỬ DỤNG NÀY TRONG SẢN XUẤT. Trong các bài kiểm tra hoặc trường hợp đặc biệt, bạn có thể muốn xử lý/xử lý một công việc trực tuyến. Để làm như vậy, bạn có thể sử dụng const name = os.hostname() + ":" + process.pid + "+" + counter; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math", name: name }, jobs );4. Nếu bạn đang có kế hoạch chạy một công việc thông qua #performInline, thì cũng không nên bắt đầu công việc này cũng như không nên sử dụng các trình phát sự kiện để giám sát công việc này. Phương pháp này cũng sẽ không ghi vào redis, bao gồm lỗi ghi nhật ký, sửa đổi số liệu thống kê của resque, v.v. Quản lý hàng đợiconst queue = new NodeResque.Queue({ connection: connectionDetails, jobs }); await queue.connect(); Có thể tìm thấy tài liệu API cho các phương thức chính mà bạn sẽ sử dụng để sắp xếp các công việc cần thực hiện tại @ node-resque. anh hùng hành động. com Quản lý công việc thất bạiĐôi khi, công việc/công nhân của bạn có thể thất bại. Công nhân yêu cầu sẽ chuyển các công việc thất bại sang hàng đợi const name = os.hostname() + ":" + process.pid + "+" + counter; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math", name: name }, jobs );1 đặc biệt sẽ lưu trữ các đối số ban đầu của công việc của bạn, dấu vết ngăn xếp thất bại và siêu dữ liệu bổ sung Bạn có thể làm việc với những công việc thất bại này bằng các phương pháp sau const name = os.hostname() + ":" + process.pid + "+" + counter; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math", name: name }, jobs );6
const name = os.hostname() + ":" + process.pid + "+" + counter; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math", name: name }, jobs );8
thất bại trong công việcChúng tôi sử dụng mẫu thử/bắt để phát hiện lỗi trong công việc của bạn. Nếu bất kỳ công việc nào đưa ra một ngoại lệ chưa được phát hiện, nó sẽ bị bắt và trọng tải của công việc được chuyển đến hàng đợi lỗi để kiểm tra. Không sử dụng tên miền, hoặc bất kỳ phương pháp nào khác để "bắt" sự cố quy trình Tải trọng lỗi trông giống như { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' } const queue = new NodeResque.Queue({ connection: connectionDetails, jobs }); await queue.connect();2
const queue = new NodeResque.Queue({ connection: connectionDetails, jobs }); await queue.connect();5
Quản lý công nhân thất bạitự độngTheo mặc định, bộ lập lịch sẽ kiểm tra các worker chưa ping redis trong 60 phút. Nếu điều này xảy ra, chúng tôi sẽ cho rằng quá trình bị lỗi và xóa nó khỏi redis. Nếu nhân viên này đang thực hiện một công việc, chúng tôi sẽ xếp công việc đó vào hàng đợi thất bại để kiểm tra sau. Mỗi worker có một bộ đếm thời gian chạy trong đó nó cập nhật một khóa trong redis mỗi const queue = new NodeResque.Queue({ connection: connectionDetails, jobs }); await queue.connect();8 (mặc định. 5 giây). Nếu công việc của bạn chậm, nhưng không đồng bộ, sẽ không có vấn đề gì. Tuy nhiên, nếu công việc của bạn tiêu tốn 100% CPU của quy trình, bộ đếm thời gian này có thể không kích hoạt Để sửa đổi kiểm tra 60 phút, hãy thay đổi const queue = new NodeResque.Queue({ connection: connectionDetails, jobs }); await queue.connect();9 khi định cấu hình bộ lập lịch của bạn, tức là const scheduler = new NodeResque.Scheduler({ stuckWorkerTimeout: (1000 * 60 * 60) // 1 hour, in ms connection: connectionDetails }) Đặt { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }0 của trình lập lịch trình của bạn để tắt hành vi này const scheduler = new NodeResque.Scheduler({ stuckWorkerTimeout: false // will not fail jobs which haven't pinged redis connection: connectionDetails }) thủ côngĐôi khi một công nhân gặp sự cố là một cách nghiêm trọng và không có thời gian/cơ hội để thông báo cho redis rằng họ đang rời khỏi nhóm (điều này xảy ra mọi lúc đối với các nhà cung cấp PAAS như Heroku). Khi điều này xảy ra, bạn không chỉ cần trích xuất công việc từ trạng thái "đang làm việc" của nhân viên zombie hiện tại mà còn phải xóa nhân viên bị mắc kẹt. Để hỗ trợ bạn trong những trường hợp khó khăn này, có sẵn { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }1 Vì không có 'nhịp tim' trong resque nên ứng dụng không thể biết được công nhân đã làm việc lâu hay đã chết. Bạn được yêu cầu cung cấp "tuổi" cho thời gian một công nhân đã "làm việc" và tất cả những người lớn hơn độ tuổi đó sẽ bị xóa và công việc họ đang làm được chuyển sang hàng đợi lỗi (khi đó bạn có thể sử dụng { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }2 Nếu bạn biết tên của một worker cần được xóa, bạn cũng có thể gọi trực tiếp { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }3 và điều đó cũng sẽ xóa worker đó và chuyển bất kỳ công việc nào mà nó đang thực hiện vào hàng đợi lỗi. Phương pháp này sẽ vẫn tiếp tục đối với các công nhân chỉ làm lại một phần, cho thấy lỗi kết nối trước đó. Trong trường hợp này, công việc mà người lao động đang làm bị mất không thể phục hồi được lịch trình công việcBạn có thể muốn sử dụng node-resque để lên lịch công việc mỗi phút/giờ/ngày, giống như hệ thống CRON phân tán. Có một số gói nút tuyệt vời để giúp bạn với điều này, như lịch trình nút và nút-cron. Node-resque giúp bạn có thể sử dụng gói bạn chọn để lên lịch công việc với Giả sử bạn đang chạy node-resque trên nhiều máy, bạn sẽ cần đảm bảo rằng chỉ một trong số các quy trình của bạn thực sự lên lịch cho các công việc. Để giúp bạn làm điều này, bạn có thể kiểm tra quy trình lập lịch biểu nào hiện đang đóng vai trò là người dẫn đầu và chỉ gắn cờ cho quy trình lập lịch trình chính để chạy lịch trình. Một ví dụ đầy đủ có thể được tìm thấy tại /examples/scheduledJobs. ts, nhưng phần có liên quan là const NodeResque = require("node-resque"); const schedule = require("node-schedule"); const queue = new NodeResque.Queue({ connection: connectionDetails }, jobs); const scheduler = new NodeResque.Scheduler({ connection: connectionDetails }); await scheduler.connect(); scheduler.start(); schedule.scheduleJob("10,20,30,40,50 * * * * *", async () => { // do this job every 10 seconds, CRON style // we want to ensure that only one instance of this job is scheduled in our environment at once, // no matter how many schedulers we have running if (scheduler.leader) { console.log(">>> enqueuing a job"); await queue.enqueue("time", "ticktock", new Date().toString()); } }); bổ sungCũng giống như resque của ruby, bạn có thể viết worker plugin. Họ trông như thế này. 4 cái móc bạn có là const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end()3, const connectionDetails = { pkg: "ioredis", host: "127.0.0.1", password: "", port: 6379, database: 0, namespace: "resque", // Also allow array of strings }; const worker = new NodeResque.Worker( { connection: connectionDetails, queues: "math" }, jobs ); worker.on("error", (error) => { // handler errors }); await worker.connect(); worker.start(); // and when you are done // await worker.end()4, { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }6 và { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }7. Các plugin là { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }8 mở rộng { worker: 'busted-worker-3', queue: 'busted-queue', payload: { class: 'busted_job', queue: 'busted-queue', args: [ 1, 2, 3 ] }, exception: 'ERROR_NAME', error: 'I broke', failed_at: 'Sun Apr 26 2015 14:00:44 GMT+0100 (BST)' }9 options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };0 Và sau đó plugin của bạn có thể được gọi trong một công việc như thế này options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };1 ghi chú
options = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };2 Các plugin được bao gồm trong gói này là
nhiều công nhânoptions = { looping: true, timeout: 5000, queues: "*", name: os.hostname() + ":" + process.pid, };6 cung cấp một trình bao bọc xung quanh lớp const scheduler = new NodeResque.Scheduler({ stuckWorkerTimeout: false // will not fail jobs which haven't pinged redis connection: connectionDetails })3 sẽ tự động điều chỉnh số lượng công nhân yêu cầu. Điều này sẽ xử lý nhiều công việc cùng một lúc miễn là có CPU nhàn rỗi trong vòng lặp sự kiện. Ví dụ: nếu bạn có một công việc chậm gửi email qua SMTP (với chi phí thấp), chúng tôi có thể xử lý nhiều công việc cùng một lúc, nhưng nếu bạn có một hoạt động nặng về toán học, chúng tôi sẽ xử lý 1. const scheduler = new NodeResque.Scheduler({ stuckWorkerTimeout: false // will not fail jobs which haven't pinged redis connection: connectionDetails })4 xử lý việc này bằng cách sinh ra ngày càng nhiều công nhân có yêu cầu nút và quản lý nhóm Nút js hoạt động ở chế độ nền như thế nào?Nút. js duy trì một nhóm công nhân. Các hoạt động chạy trong thời gian dài được chuyển sang nhóm công nhân này và nhóm sự kiện chỉ xử lý phản hồi từ nhóm công nhân này khi hoàn thành nhiệm vụ . Nhóm công nhân làm việc với hệ điều hành để thực hiện các công việc nặng nhọc và quản lý lập lịch các nhiệm vụ.
Tôi có thể kiếm một công việc với Nodejs không?Triển vọng công việc và lĩnh vực ứng dụng cho sự nghiệp trong Node. js. Việc làm của nhà phát triển phần mềm luôn có nhu cầu . Phát triển front-end, phát triển UX/UI, quản lý máy chủ cũng như phát triển back-end, tất cả các lĩnh vực phụ này đều có nhu cầu về lực lượng lao động có trình độ và kỹ năng tốt.
Nút JS có chạy ở chế độ nền không?Chạy nút trong nền - Sử dụng PM2
. Trình quản lý quy trình này có bộ cân bằng tải tích hợp cho phép ứng dụng nút js tồn tại mãi mãi mà không có thời gian chết ngay cả khi máy chủ khởi động lại. Để cài đặt PM2 trên toàn cầu, hãy chạy lệnh npm install pm2 -g trong một thiết bị đầu cuối. You can run PM2 on all Linux, Windows & macOS. This process manager has a built-in load balancer which allow the node js app keep alive forever without downtime even if the server restart. To install PM2 globally run the command npm install pm2 -g in a terminal.
Công việc nền có sử dụng hàng đợi không?Các công việc nền không phải lúc nào cũng được máy chủ ứng dụng xếp hàng . Một công nhân đang xử lý một công việc cũng có thể xếp hàng một công việc khác. Trong khi họ xếp hàng công việc dựa trên các sự kiện như tương tác của người dùng hoặc một số dữ liệu bị thay đổi, bộ lập lịch có thể xếp hàng công việc dựa trên thời gian (ví dụ: để sao lưu hàng ngày). |