λ³λ ¬ μμ μ€ν λ° ν₯μλ μ ν리μΌμ΄μ μ±λ₯μ μν΄ λͺ¨λ μ컀 μ€λ λ νμ μ¬μ©νμ¬ JavaScriptμμ ν¨μ¨μ μΈ μ컀 μ€λ λ κ΄λ¦¬λ₯Ό νμν©λλ€.
JavaScript λͺ¨λ μ컀 μ€λ λ ν: ν¨μ¨μ μΈ μ컀 μ€λ λ κ΄λ¦¬
μ΅μ JavaScript μ ν리μΌμ΄μ μ κ³μ° μ§μ½μ μΈ μμ λλ I/O λ°μ΄λ μμ μ μ²λ¦¬ν λ μ’ μ’ μ±λ₯ λ³λͺ© νμμ μ§λ©΄ν©λλ€. JavaScriptμ λ¨μΌ μ€λ λ νΉμ±μ λ©ν° μ½μ΄ νλ‘μΈμλ₯Ό μμ ν νμ©νλ λ₯λ ₯μ μ νν μ μμ΅λλ€. λ€νν Node.jsμ Worker Threadsμ λΈλΌμ°μ μ Web Workersμ λμ μ λ³λ ¬ μ€νμ μν λ©μ»€λμ¦μ μ 곡νμ¬ JavaScript μ ν리μΌμ΄μ μ΄ μ¬λ¬ CPU μ½μ΄λ₯Ό νμ©νκ³ μλ΅μ±μ ν₯μμν¬ μ μλλ‘ ν©λλ€.
μ΄ λΈλ‘κ·Έ κ²μλ¬Όμμλ μ컀 μ€λ λλ₯Ό ν¨μ¨μ μΌλ‘ κ΄λ¦¬νκ³ νμ©νκΈ° μν κ°λ ₯ν ν¨ν΄μΈ JavaScript λͺ¨λ μ컀 μ€λ λ νμ κ°λ μ μμΈν μ΄ν΄λ΄ λλ€. μ€λ λ ν μ¬μ©μ μ΄μ μ μ΄ν΄λ³΄κ³ ꡬν μΈλΆ μ¬νμ λ Όμνλ©° μ¬μ©λ²μ μ€λͺ νλ μ€μ μμ λ₯Ό μ 곡ν©λλ€.
μ컀 μ€λ λ μ΄ν΄
μ컀 μ€λ λ νμ λν μΈλΆ μ¬νμ μ΄ν΄λ³΄κΈ° μ μ JavaScriptμ μ컀 μ€λ λ κΈ°λ³Έ μ¬νμ κ°λ΅νκ² κ²ν ν΄ λ³΄κ² μ΅λλ€.
μ컀 μ€λ λλ 무μμ λκΉ?
μ컀 μ€λ λλ κΈ°λ³Έ μ€λ λμ λμμ μ€νλ μ μλ λ 립μ μΈ JavaScript μ€ν 컨ν μ€νΈμ λλ€. κΈ°λ³Έ μ€λ λλ₯Ό μ°¨λ¨νκ³ UI κ³ μ λλ μ±λ₯ μ νλ₯Ό μΌμΌν€μ§ μκ³ λ³λ ¬λ‘ μμ μ μννλ λ°©λ²μ μ 곡ν©λλ€.
μ컀 μ ν
- μΉ μ컀: μΉ λΈλΌμ°μ μμ μ¬μ©ν μ μμΌλ©° μ¬μ©μ μΈν°νμ΄μ€λ₯Ό λ°©ν΄νμ§ μκ³ λ°±κ·ΈλΌμ΄λ μ€ν¬λ¦½νΈ μ€νμ νμ©ν©λλ€. κΈ°λ³Έ λΈλΌμ°μ μ€λ λμμ κ³Όλν κ³μ°μ μ€νλ‘λνλ λ° μ€μν©λλ€.
- Node.js μ컀 μ€λ λ: Node.jsμ λμ λμ΄ μλ² μΈ‘ μ ν리μΌμ΄μ μμ JavaScript μ½λμ λ³λ ¬ μ€νμ κ°λ₯νκ² ν©λλ€. μ΄λ μ΄λ―Έμ§ μ²λ¦¬, λ°μ΄ν° λΆμ λλ μ¬λ¬ λμ μμ² μ²λ¦¬μ κ°μ μμ μ νΉν μ€μν©λλ€.
μ£Όμ κ°λ
- 격리: μ컀 μ€λ λλ κΈ°λ³Έ μ€λ λμ λΆλ¦¬λ λ©λͺ¨λ¦¬ 곡κ°μμ μλνμ¬ κ³΅μ λ°μ΄ν°μ λν μ§μ μ μΈ μ‘μΈμ€λ₯Ό λ°©μ§ν©λλ€.
- λ©μμ§ μ λ¬: κΈ°λ³Έ μ€λ λμ μ컀 μ€λ λ κ°μ ν΅μ μ λΉλκΈ° λ©μμ§ μ λ¬μ ν΅ν΄ μ΄λ£¨μ΄μ§λλ€.
postMessage()λ©μλλ λ°μ΄ν°λ₯Ό 보λ΄λ λ° μ¬μ©λκ³onmessageμ΄λ²€νΈ νΈλ€λ¬λ λ°μ΄ν°λ₯Ό μμ ν©λλ€. μ€λ λ κ°μ μ λ¬λ λ λ°μ΄ν°λ₯Ό μ§λ ¬ν/μμ§λ ¬νν΄μΌ ν©λλ€. - λͺ¨λ μ컀: ES λͺ¨λ(
import/exportꡬ문)μ μ¬μ©νμ¬ μμ±λ μ컀μ λλ€. ν΄λμ μ€ν¬λ¦½νΈ μ컀μ λΉν΄ λ λμ μ½λ κ΅¬μ± λ° μ’ μμ± κ΄λ¦¬λ₯Ό μ 곡ν©λλ€.
μ컀 μ€λ λ ν μ¬μ©μ μ΄μ
μ컀 μ€λ λλ λ³λ ¬ μ€νμ μν κ°λ ₯ν λ©μ»€λμ¦μ μ 곡νμ§λ§ μ§μ κ΄λ¦¬νλ κ²μ 볡μ‘νκ³ λΉν¨μ¨μ μΌ μ μμ΅λλ€. κ° μμ μ λν΄ μ컀 μ€λ λλ₯Ό μμ±νκ³ μμ νλ©΄ μλΉν μ€λ²ν€λκ° λ°μν μ μμ΅λλ€. μ¬κΈ°μ μ컀 μ€λ λ νμ΄ μλν©λλ€.
μ컀 μ€λ λ νμ νμ± μνλ‘ μ μ§λκ³ μμ μ μ€νν μ€λΉκ° λ 미리 μμ±λ μ컀 μ€λ λ λͺ¨μμ λλ€. μμ μ μ²λ¦¬ν΄μΌ ν λ νμ μ μΆλμ΄ μ¬μ© κ°λ₯ν μ컀 μ€λ λμ ν λΉλ©λλ€. μμ μ΄ μλ£λλ©΄ μ컀 μ€λ λκ° νλ‘ λμκ° λ€λ₯Έ μμ μ μ²λ¦¬ν μ€λΉκ° λ©λλ€.
μ컀 μ€λ λ ν μ¬μ©μ μ₯μ :
- μ€λ²ν€λ κ°μ: κΈ°μ‘΄ μ컀 μ€λ λλ₯Ό μ¬μ¬μ©ν¨μΌλ‘μ¨ κ° μμ μ λν΄ μ€λ λλ₯Ό μμ±νκ³ μμ νλ μ€λ²ν€λκ° μ κ±°λμ΄ νΉν μλͺ μ΄ μ§§μ μμ μ κ²½μ° μλΉν μ±λ₯ ν₯μμΌλ‘ μ΄μ΄μ§λλ€.
- ν₯μλ 리μμ€ κ΄λ¦¬: νμ λμ μ컀 μ€λ λ μλ₯Ό μ ννμ¬ κ³Όλν 리μμ€ μλΉ λ° μ μ¬μ μΈ μμ€ν κ³ΌλΆνλ₯Ό λ°©μ§ν©λλ€. μ΄λ μμ μ±μ 보μ₯νκ³ κ³ΌλΆν μνμμ μ±λ₯ μ νλ₯Ό λ°©μ§νλ λ° μ€μν©λλ€.
- κ°μνλ μμ κ΄λ¦¬: νμ μμ μ κ΄λ¦¬νκ³ μμ½νκΈ° μν μ€μ μ§μ€μ λ©μ»€λμ¦μ μ 곡νμ¬ μ ν리μΌμ΄μ λ‘μ§μ λ¨μννκ³ μ½λ μ μ§ κ΄λ¦¬μ±μ ν₯μμν΅λλ€. κ°λ³ μ컀 μ€λ λλ₯Ό κ΄λ¦¬νλ λμ νκ³Ό μνΈ μμ©ν©λλ€.
- μ μ΄λ λμμ±: νΉμ μ€λ λ μλ‘ νμ ꡬμ±νμ¬ λ³λ ¬ μ²λ¦¬ μ λλ₯Ό μ ννκ³ λ¦¬μμ€ κ³ κ°μ λ°©μ§ν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ¬μ© κ°λ₯ν νλμ¨μ΄ 리μμ€μ μμ λΆνμ νΉμ±μ λ°λΌ μ±λ₯μ λ―ΈμΈ μ‘°μ ν μ μμ΅λλ€.
- ν₯μλ μλ΅μ±: μμ μ μ컀 μ€λ λλ‘ μ€νλ‘λν¨μΌλ‘μ¨ κΈ°λ³Έ μ€λ λκ° μλ΅μ±μ μ μ§νμ¬ μνν μ¬μ©μ κ²½νμ 보μ₯ν©λλ€. μ΄λ UI μλ΅μ±μ΄ μ€μν λνν μ ν리μΌμ΄μ μ νΉν μ€μν©λλ€.
JavaScript λͺ¨λ μ컀 μ€λ λ ν ꡬν
JavaScript λͺ¨λ μ컀 μ€λ λ νμ ꡬνμ μ΄ν΄λ³΄κ² μ΅λλ€. ν΅μ¬ κ΅¬μ± μμλ₯Ό λ€λ£¨κ³ ꡬν μΈλΆ μ¬νμ μ€λͺ νλ μ½λ μμ λ₯Ό μ 곡ν©λλ€.
ν΅μ¬ κ΅¬μ± μμ
- μ컀 ν ν΄λμ€: μ΄ ν΄λμ€λ μ컀 μ€λ λ ν κ΄λ¦¬λ₯Ό μν λ‘μ§μ μΊ‘μνν©λλ€. μ컀 μ€λ λλ₯Ό μμ±, μ΄κΈ°ν λ° μ¬νμ©νλ μν μ ν©λλ€.
- μμ λκΈ°μ΄: μ€νμ κΈ°λ€λ¦¬λ μμ μ 보κ΄νλ λκΈ°μ΄μ λλ€. μμ μ νμ μ μΆλ λ λκΈ°μ΄μ μΆκ°λ©λλ€.
- μ컀 μ€λ λ λνΌ: κΈ°λ³Έ μ컀 μ€λ λ κ°μ²΄λ₯Ό λννμ¬ μ컀μ μνΈ μμ©νκΈ° μν νΈλ¦¬ν μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€. μ΄ λνΌλ λ©μμ§ μ λ¬, μ€λ₯ μ²λ¦¬ λ° μμ μλ£ μΆμ μ μ²λ¦¬ν μ μμ΅λλ€.
- μμ μ μΆ λ©μ»€λμ¦: νμ μμ μ μ μΆνκΈ° μν λ©μ»€λμ¦μΌλ‘, μΌλ°μ μΌλ‘ μ컀 ν ν΄λμ€μ λ©μλμ λλ€. μ΄ λ©μλλ μμ μ λκΈ°μ΄μ μΆκ°νκ³ μ¬μ© κ°λ₯ν μ컀 μ€λ λμ ν λΉνλλ‘ νμ μ νΈλ₯Ό 보λ λλ€.
μ½λ μμ (Node.js)
λͺ¨λ μ컀λ₯Ό μ¬μ©νλ Node.jsμμ κ°λ¨ν μ컀 μ€λ λ ν ꡬνμ μλ λ€μκ³Ό κ°μ΅λλ€.
// worker_pool.js
import { Worker } from 'worker_threads';
class WorkerPool {
constructor(numWorkers, workerFile) {
this.numWorkers = numWorkers;
this.workerFile = workerFile;
this.workers = [];
this.taskQueue = [];
this.availableWorkers = [];
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker(workerFile, { type: 'module' });
const workerWrapper = {
worker,
isBusy: false
};
this.workers.push(workerWrapper);
this.availableWorkers.push(workerWrapper);
worker.on('message', (message) => {
// Handle task completion
workerWrapper.isBusy = false;
this.availableWorkers.push(workerWrapper);
this.processTaskQueue();
});
worker.on('error', (error) => {
console.error('Worker error:', error);
});
worker.on('exit', (code) => {
if (code !== 0) {
console.error(`Worker stopped with exit code ${code}`);
}
});
}
}
runTask(task) {
return new Promise((resolve, reject) => {
this.taskQueue.push({ task, resolve, reject });
this.processTaskQueue();
});
}
processTaskQueue() {
if (this.taskQueue.length === 0 || this.availableWorkers.length === 0) {
return;
}
const workerWrapper = this.availableWorkers.shift();
const { task, resolve, reject } = this.taskQueue.shift();
workerWrapper.isBusy = true;
workerWrapper.worker.postMessage(task);
workerWrapper.worker.once('message', (result) => {
resolve(result);
});
workerWrapper.worker.once('error', (error) => {
reject(error);
});
}
close() {
this.workers.forEach(workerWrapper => workerWrapper.worker.terminate());
}
}
export default WorkerPool;
// worker.js
import { parentPort } from 'worker_threads';
parentPort.on('message', (task) => {
// Simulate a computationally intensive task
const result = task * 2; // Replace with your actual task logic
parentPort.postMessage(result);
});
// main.js
import WorkerPool from './worker_pool.js';
const numWorkers = 4; // Adjust based on your CPU core count
const workerFile = './worker.js';
const pool = new WorkerPool(numWorkers, workerFile);
async function main() {
const tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const results = await Promise.all(
tasks.map(async (task) => {
try {
const result = await pool.runTask(task);
console.log(`Task ${task} result: ${result}`);
return result;
} catch (error) {
console.error(`Task ${task} failed:`, error);
return null;
}
})
);
console.log('All tasks completed:', results);
pool.close(); // Terminate all workers in the pool
}
main();
μ€λͺ :
- worker_pool.js: μ컀 μ€λ λ μμ±, μμ
λκΈ°μ΄ λ° μμ
ν λΉμ κ΄λ¦¬νλ
WorkerPoolν΄λμ€λ₯Ό μ μν©λλ€.runTaskλ©μλλ μμ μ λκΈ°μ΄μ μ μΆνκ³processTaskQueueλ μ¬μ© κ°λ₯ν μ컀μ μμ μ ν λΉν©λλ€. λν μ컀 μ€λ₯ λ° μ’ λ£λ₯Ό μ²λ¦¬ν©λλ€. - worker.js: μ΄κ²μ μ컀 μ€λ λ μ½λμ
λλ€.
parentPort.on('message')λ₯Ό μ¬μ©νμ¬ κΈ°λ³Έ μ€λ λμμ λ©μμ§λ₯Ό μμ νκ³ , μμ μ μννκ³ ,parentPort.postMessage()λ₯Ό μ¬μ©νμ¬ κ²°κ³Όλ₯Ό λ€μ 보λ λλ€. μ 곡λ μμμλ μμ λ μμ μ 2λ₯Ό κ³±ν©λλ€. - main.js:
WorkerPoolμ¬μ© λ°©λ²μ 보μ¬μ€λλ€. μ§μ λ μ컀 μλ‘ νμ λ§λ€κ³pool.runTask()λ₯Ό μ¬μ©νμ¬ μμ μ νμ μ μΆν©λλ€.Promise.all()μ μ¬μ©νμ¬ λͺ¨λ μμ μ΄ μλ£λ λκΉμ§ κΈ°λ€λ¦° λ€μ νμ λ«μ΅λλ€.
μ½λ μμ (μΉ μ컀)
λμΌν κ°λ μ΄ λΈλΌμ°μ μ μΉ μ컀μλ μ μ©λ©λλ€. κ·Έλ¬λ ꡬν μΈλΆ μ¬νμ λΈλΌμ°μ νκ²½μΌλ‘ μΈν΄ μ½κ° λ€λ¦ λλ€. λ€μμ κ°λ μ κ°μμ λλ€. μλ²(μ: `npx serve` μ¬μ©)λ₯Ό ν΅ν΄ νμΌμ μ 곡νμ§ μμΌλ©΄ λ‘컬μμ μ€νν λ CORS λ¬Έμ κ° λ°μν μ μμ΅λλ€.
// worker_pool.js (for browser)
class WorkerPool {
constructor(numWorkers, workerFile) {
this.numWorkers = numWorkers;
this.workerFile = workerFile;
this.workers = [];
this.taskQueue = [];
this.availableWorkers = [];
for (let i = 0; i < numWorkers; i++) {
const worker = new Worker(workerFile, { type: 'module' });
const workerWrapper = {
worker,
isBusy: false
};
this.workers.push(workerWrapper);
this.availableWorkers.push(workerWrapper);
worker.onmessage = (event) => {
// Handle task completion
workerWrapper.isBusy = false;
this.availableWorkers.push(workerWrapper);
this.processTaskQueue();
};
worker.onerror = (error) => {
console.error('Worker error:', error);
};
}
}
runTask(task) {
return new Promise((resolve, reject) => {
this.taskQueue.push({ task, resolve, reject });
this.processTaskQueue();
});
}
processTaskQueue() {
if (this.taskQueue.length === 0 || this.availableWorkers.length === 0) {
return;
}
const workerWrapper = this.availableWorkers.shift();
const { task, resolve, reject } = this.taskQueue.shift();
workerWrapper.isBusy = true;
workerWrapper.worker.postMessage(task);
workerWrapper.worker.onmessage = (event) => {
resolve(event.data);
};
workerWrapper.worker.onerror = (error) => {
reject(error);
};
}
close() {
this.workers.forEach(workerWrapper => workerWrapper.worker.terminate());
}
}
export default WorkerPool;
// worker.js (for browser)
self.onmessage = (event) => {
const task = event.data;
// Simulate a computationally intensive task
const result = task * 2; // Replace with your actual task logic
self.postMessage(result);
};
// main.js (for browser, included in your HTML)
import WorkerPool from './worker_pool.js';
const numWorkers = 4; // Adjust based on your CPU core count
const workerFile = './worker.js';
const pool = new WorkerPool(numWorkers, workerFile);
async function main() {
const tasks = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const results = await Promise.all(
tasks.map(async (task) => {
try {
const result = await pool.runTask(task);
console.log(`Task ${task} result: ${result}`);
return result;
} catch (error) {
console.error(`Task ${task} failed:`, error);
return null;
}
})
);
console.log('All tasks completed:', results);
pool.close(); // Terminate all workers in the pool
}
main();
λΈλΌμ°μ μ μ£Όμ μ°¨μ΄μ :
- μΉ μ컀λ
new Worker(workerFile)μ μ¬μ©νμ¬ μ§μ μμ±λ©λλ€. - λ©μμ§ μ²λ¦¬λ
worker.onmessageλ°self.onmessage(μ컀 λ΄)λ₯Ό μ¬μ©ν©λλ€. - Node.jsμ
worker_threadsλͺ¨λμparentPortAPIλ λΈλΌμ°μ μμ μ¬μ©ν μ μμ΅λλ€. - νΉν JavaScript λͺ¨λ(
type="module")μ κ²½μ° νμΌμ΄ μ¬λ°λ₯Έ MIME μ νμΌλ‘ μ 곡λλμ§ νμΈνμμμ€.
μ€μ μμ λ° μ¬μ© μ¬λ‘
μ컀 μ€λ λ νμ΄ μ±λ₯μ ν¬κ² ν₯μμν¬ μ μλ μ€μ μμ λ° μ¬μ© μ¬λ‘λ₯Ό μ΄ν΄λ³΄κ² μ΅λλ€.
μ΄λ―Έμ§ μ²λ¦¬
ν¬κΈ° μ‘°μ , νν°λ§ λλ νμ λ³νκ³Ό κ°μ μ΄λ―Έμ§ μ²λ¦¬ μμ μ κ³μ° μ§μ½μ μΌ μ μμ΅λλ€. μ΄λ¬ν μμ μ μ컀 μ€λ λλ‘ μ€νλ‘λνλ©΄ κΈ°λ³Έ μ€λ λκ° μλ΅μ±μ μ μ§νμ¬ νΉν μΉ μ ν리μΌμ΄μ μμ λ μνν μ¬μ©μ κ²½νμ μ 곡ν©λλ€.
μ: μ¬μ©μκ° μ΄λ―Έμ§λ₯Ό μ λ‘λνκ³ νΈμ§ν μ μλ μΉ μ ν리μΌμ΄μ . μ΄λ―Έμ§ ν¬κΈ° μ‘°μ λ° νν° μ μ©μ μ컀 μ€λ λμμ μννμ¬ μ΄λ―Έμ§λ₯Ό μ²λ¦¬νλ λμ UI κ³ μ μ λ°©μ§ν μ μμ΅λλ€.
λ°μ΄ν° λΆμ
λκ·λͺ¨ λ°μ΄ν° μΈνΈλ₯Ό λΆμνλ λ°λ μκ°μ΄ μ€λ κ±Έλ¦¬κ³ λ¦¬μμ€κ° λ§μ΄ μλͺ¨λ μ μμ΅λλ€. μ컀 μ€λ λλ₯Ό μ¬μ©νμ¬ λ°μ΄ν° μ§κ³, ν΅κ³ κ³μ° λλ κΈ°κ³ νμ΅ λͺ¨λΈ νλ ¨κ³Ό κ°μ λ°μ΄ν° λΆμ μμ μ λ³λ ¬νν μ μμ΅λλ€.
μ: μ¬λ¬΄ λ°μ΄ν°λ₯Ό μ²λ¦¬νλ λ°μ΄ν° λΆμ μ ν리μΌμ΄μ . μ΄λ νκ· , μΆμΈ λΆμ λ° μν νκ°μ κ°μ κ³μ°μ μ컀 μ€λ λλ₯Ό μ¬μ©νμ¬ λ³λ ¬λ‘ μνν μ μμ΅λλ€.
μ€μκ° λ°μ΄ν° μ€νΈλ¦¬λ°
κΈμ΅ μμΈ λλ μΌμ λ°μ΄ν°μ κ°μ μ€μκ° λ°μ΄ν° μ€νΈλ¦Όμ μ²λ¦¬νλ μ ν리μΌμ΄μ μ μ컀 μ€λ λμ μ΄μ μ λ릴 μ μμ΅λλ€. μ컀 μ€λ λλ₯Ό μ¬μ©νμ¬ κΈ°λ³Έ μ€λ λλ₯Ό μ°¨λ¨νμ§ μκ³ λ€μ΄μ€λ λ°μ΄ν° μ€νΈλ¦Όμ μ²λ¦¬νκ³ λΆμν μ μμ΅λλ€.
μ: κ°κ²© μ λ°μ΄νΈ λ° μ°¨νΈλ₯Ό νμνλ μ€μκ° μ£Όμ μμ₯ μμΈ. λ°μ΄ν° μ²λ¦¬, μ°¨νΈ λ λλ§ λ° κ²½κ³ μλ¦Όμ μ컀 μ€λ λμμ μ²λ¦¬νμ¬ λ°μ΄ν° λ³Όλ₯¨μ΄ λ§μ κ²½μ°μλ UIκ° μλ΅μ±μ μ μ§νλλ‘ ν μ μμ΅λλ€.
λ°±κ·ΈλΌμ΄λ μμ μ²λ¦¬
μ¦κ°μ μΈ μ¬μ©μ μνΈ μμ©μ΄ νμνμ§ μμ λ°±κ·ΈλΌμ΄λ μμ μ μ컀 μ€λ λλ‘ μ€νλ‘λν μ μμ΅λλ€. μλ‘λ μ΄λ©μΌ 보λ΄κΈ°, λ³΄κ³ μ μμ± λλ μμ½λ λ°±μ μν λ±μ΄ μμ΅λλ€.
μ: μ£Όκ° μ΄λ©μΌ λ΄μ€λ ν°λ₯Ό 보λ΄λ μΉ μ ν리μΌμ΄μ . μ΄λ©μΌ 보λ΄κΈ° νλ‘μΈμ€λ μ컀 μ€λ λμμ μ²λ¦¬νμ¬ κΈ°λ³Έ μ€λ λκ° μ°¨λ¨λμ§ μκ³ μΉ μ¬μ΄νΈκ° μλ΅μ±μ μ μ§νλλ‘ ν μ μμ΅λλ€.
μ¬λ¬ λμ μμ² μ²λ¦¬ (Node.js)
Node.js μλ² μ ν리μΌμ΄μ μμ μ컀 μ€λ λλ₯Ό μ¬μ©νμ¬ μ¬λ¬ λμ μμ²μ λ³λ ¬λ‘ μ²λ¦¬ν μ μμ΅λλ€. μ΄λ νΉν κ³μ° μ§μ½μ μΈ μμ μ μννλ μ ν리μΌμ΄μ μ κ²½μ° μ 체 μ²λ¦¬λμ κ°μ νκ³ μλ΅ μκ°μ μ€μΌ μ μμ΅λλ€.
μ: μ¬μ©μ μμ²μ μ²λ¦¬νλ Node.js API μλ². μ΄λ―Έμ§ μ²λ¦¬, λ°μ΄ν° μ ν¨μ± κ²μ¬ λ° λ°μ΄ν°λ² μ΄μ€ 쿼리λ μ컀 μ€λ λμμ μ²λ¦¬νμ¬ μλ²κ° μ±λ₯ μ ν μμ΄ λ λ§μ λμ μμ²μ μ²λ¦¬ν μ μμ΅λλ€.
μ컀 μ€λ λ ν μ±λ₯ μ΅μ ν
μ컀 μ€λ λ νμ μ΄μ μ κ·Ήλννλ €λ©΄ μ±λ₯μ μ΅μ ννλ κ²μ΄ μ€μν©λλ€. λ€μμ λͺ κ°μ§ νκ³Ό κΈ°μ μ λλ€.
- μ μ ν μ컀 μ μ ν: μ΅μ μ μ컀 μ€λ λ μλ μ¬μ© κ°λ₯ν CPU μ½μ΄ μμ μμ λΆνμ νΉμ±μ λ°λΌ λ€λ¦ λλ€. μΌλ°μ μΈ κ²½ν λ²μΉμ CPU μ½μ΄ μμ λμΌν μ컀 μλ‘ μμν λ€μ μ±λ₯ ν μ€νΈλ₯Ό κΈ°λ°μΌλ‘ μ‘°μ νλ κ²μ λλ€. Node.jsμ `os.cpus()`μ κ°μ λꡬλ μ½μ΄ μλ₯Ό κ²°μ νλ λ° λμμ΄ λ μ μμ΅λλ€. μ€λ λλ₯Ό κ³Όλνκ² μ»€λ°νλ©΄ 컨ν μ€νΈ μ ν μ€λ²ν€λκ° λ°μνμ¬ λ³λ ¬ μ²λ¦¬μ μ΄μ μ΄ λ¬΄ν¨νλ μ μμ΅λλ€.
- λ°μ΄ν° μ μ‘ μ΅μν: κΈ°λ³Έ μ€λ λμ μ컀 μ€λ λ κ°μ λ°μ΄ν° μ μ‘μ μ±λ₯ λ³λͺ© νμμ΄ λ μ μμ΅λλ€. μ컀 μ€λ λ λ΄μμ μ΅λν λ§μ λ°μ΄ν°λ₯Ό μ²λ¦¬νμ¬ μ μ‘ν΄μΌ νλ λ°μ΄ν° μμ μ΅μνν©λλ€. κ°λ₯ν κ²½μ° μ€λ λ κ°μ λ°μ΄ν°λ₯Ό μ§μ 곡μ νκΈ° μν΄ SharedArrayBuffer(μ μ ν λκΈ°ν λ©μ»€λμ¦ ν¬ν¨)λ₯Ό μ¬μ©νλ κ²μ κ³ λ €νλ 보μ μν₯ λ° λΈλΌμ°μ νΈνμ±μ μκ³ μμ΄μΌ ν©λλ€.
- μμ μΈλΆμ± μ΅μ ν: κ°λ³ μμ μ ν¬κΈ°μ 볡μ‘μ±μ μ±λ₯μ μν₯μ μ€ μ μμ΅λλ€. λκ·λͺ¨ μμ μ λ μκ³ κ΄λ¦¬νκΈ° μ¬μ΄ λ¨μλ‘ λΆν νμ¬ λ³λ ¬ μ²λ¦¬λ₯Ό κ°μ νκ³ μ₯κΈ° μ€ν μμ μ μν₯μ μ€μ λλ€. κ·Έλ¬λ μμ μμ½ λ° ν΅μ μ μ€λ²ν€λκ° λ³λ ¬ μ²λ¦¬μ μ΄μ μ λ₯κ°ν μ μμΌλ―λ‘ λ무 λ§μ μμ μμ μ λ§λ€μ§ λ§μμμ€.
- μ°¨λ¨ μμ λ°©μ§: μμ»€κ° λ€λ₯Έ μμ μ μ²λ¦¬νμ§ λͺ»νλλ‘ μ컀 μ€λ λ λ΄μμ μ°¨λ¨ μμ μ μννμ§ λ§μμμ€. λΉλκΈ° I/O μμ κ³Ό λΉμ°¨λ¨ μκ³ λ¦¬μ¦μ μ¬μ©νμ¬ μ컀 μ€λ λκ° μλ΅μ±μ μ μ§νλλ‘ ν©λλ€.
- μ±λ₯ λͺ¨λν°λ§ λ° νλ‘νμΌλ§: μ±λ₯ λͺ¨λν°λ§ λꡬλ₯Ό μ¬μ©νμ¬ λ³λͺ© νμμ μλ³νκ³ μ컀 μ€λ λ νμ μ΅μ νν©λλ€. Node.jsμ κΈ°λ³Έ νλ‘νμΌλ¬ λλ λΈλΌμ°μ κ°λ°μ λꡬμ κ°μ λꡬλ CPU μ¬μ©λ, λ©λͺ¨λ¦¬ μλΉ λ° μμ μ€ν μκ°μ λν ν΅μ°°λ ₯μ μ 곡ν μ μμ΅λλ€.
- μ€λ₯ μ²λ¦¬: μ컀 μ€λ λ λ΄μμ λ°μνλ μ€λ₯λ₯Ό catchνκ³ μ²λ¦¬νκΈ° μν΄ κ°λ ₯ν μ€λ₯ μ²λ¦¬ λ©μ»€λμ¦μ ꡬνν©λλ€. catchλμ§ μμ μ€λ₯λ μ컀 μ€λ λμ μ μ¬μ μΌλ‘ μ 체 μ ν리μΌμ΄μ μ μΆ©λμν¬ μ μμ΅λλ€.
μ컀 μ€λ λ νμ λμ
μ컀 μ€λ λ νμ κ°λ ₯ν λꡬμ΄μ§λ§ JavaScriptμμ λμμ± λ° λ³λ ¬ μ²λ¦¬λ₯Ό λ¬μ±νλ λ°λ λ체 μ κ·Ό λ°©μμ΄ μμ΅λλ€.
- Promise λ° Async/Awaitλ₯Ό μ¬μ©ν λΉλκΈ° νλ‘κ·Έλλ°: λΉλκΈ° νλ‘κ·Έλλ°μ μ¬μ©νλ©΄ μ컀 μ€λ λλ₯Ό μ¬μ©νμ§ μκ³ λ λΉμ°¨λ¨ μμ μ μνν μ μμ΅λλ€. Promise λ° async/awaitλ λΉλκΈ° μ½λλ₯Ό μ²λ¦¬νλ λ³΄λ€ κ΅¬μ‘°νλκ³ μ½κΈ° μ¬μ΄ λ°©λ²μ μ 곡ν©λλ€. μ΄λ μΈλΆ 리μμ€(μ: λ€νΈμν¬ μμ², λ°μ΄ν°λ² μ΄μ€ 쿼리)λ₯Ό κΈ°λ€λ¦¬λ I/O λ°μ΄λ μμ μ μ ν©ν©λλ€.
- WebAssembly (Wasm): WebAssemblyλ μΉ λΈλΌμ°μ μμ λ€λ₯Έ μΈμ΄(μ: C++, Rust)λ‘ μμ±λ μ½λλ₯Ό μ€νν μ μλ μ΄μ§ λͺ λ Ήμ΄ νμμ λλ€. Wasmμ νΉν μ컀 μ€λ λμ κ²°ν©λ λ κ³μ° μ§μ½μ μΈ μμ μ λν΄ μλΉν μ±λ₯ ν₯μμ μ 곡ν μ μμ΅λλ€. μ ν리μΌμ΄μ μ CPU μ§μ½μ μΈ λΆλΆμ μ컀 μ€λ λ λ΄μμ μ€νλλ Wasm λͺ¨λλ‘ μ€νλ‘λν μ μμ΅λλ€.
- μλΉμ€ μ컀: μ£Όλ‘ μΉ μ ν리μΌμ΄μ μμ μΊμ± λ° λ°±κ·ΈλΌμ΄λ λκΈ°νμ μ¬μ©λλ μλΉμ€ μ컀λ λ²μ© λ°±κ·ΈλΌμ΄λ μ²λ¦¬μλ μ¬μ©ν μ μμ΅λλ€. κ·Έλ¬λ μ£Όλ‘ κ³μ° μ§μ½μ μΈ μμ 보λ€λ λ€νΈμν¬ μμ² λ° μΊμ±μ μ²λ¦¬νλλ‘ μ€κ³λμμ΅λλ€.
- λ©μμ§ λκΈ°μ΄ (μ: RabbitMQ, Kafka): λΆμ° μμ€ν μ κ²½μ° λ©μμ§ λκΈ°μ΄μ μ¬μ©νμ¬ μμ μ λ³λμ νλ‘μΈμ€ λλ μλ²λ‘ μ€νλ‘λν μ μμ΅λλ€. μ΄λ₯Ό ν΅ν΄ μ ν리μΌμ΄μ μ μνμΌλ‘ νμ₯νκ³ λλμ μμ μ μ²λ¦¬ν μ μμ΅λλ€. μ΄λ μΈνλΌ μ€μ λ° κ΄λ¦¬κ° νμν λ³΄λ€ λ³΅μ‘ν μ루μ μ λλ€.
- μλ²λ¦¬μ€ ν¨μ (μ: AWS Lambda, Google Cloud Functions): μλ²λ¦¬μ€ ν¨μλ₯Ό μ¬μ©νλ©΄ μλ²λ₯Ό κ΄λ¦¬νμ§ μκ³ λ ν΄λΌμ°λμμ μ½λλ₯Ό μ€νν μ μμ΅λλ€. μλ²λ¦¬μ€ ν¨μλ₯Ό μ¬μ©νμ¬ κ³μ° μ§μ½μ μΈ μμ μ ν΄λΌμ°λλ‘ μ€νλ‘λνκ³ μ ν리μΌμ΄μ μ μ£Όλ¬ΈνμΌλ‘ νμ₯ν μ μμ΅λλ€. μ΄λ λλ¬Όκ±°λ μλΉν 리μμ€κ° νμν μμ μ μ ν©ν μ΅μ μ λλ€.
κ²°λ‘
JavaScript λͺ¨λ μ컀 μ€λ λ νμ μ컀 μ€λ λλ₯Ό κ΄λ¦¬νκ³ λ³λ ¬ μ€νμ νμ©νκΈ° μν κ°λ ₯νκ³ ν¨μ¨μ μΈ λ©μ»€λμ¦μ μ 곡ν©λλ€. μ€λ²ν€λλ₯Ό μ€μ΄κ³ 리μμ€ κ΄λ¦¬λ₯Ό κ°μ νλ©° μμ κ΄λ¦¬λ₯Ό λ¨μνν¨μΌλ‘μ¨ μ컀 μ€λ λ νμ JavaScript μ ν리μΌμ΄μ μ μ±λ₯κ³Ό μλ΅μ±μ ν¬κ² ν₯μμν¬ μ μμ΅λλ€.
μ컀 μ€λ λ νμ μ¬μ©ν μ§ μ¬λΆλ₯Ό κ²°μ ν λ λ€μ μμλ₯Ό κ³ λ €νμμμ€.
- μμ μ 볡μ‘μ±: μ컀 μ€λ λλ μ½κ² λ³λ ¬νν μ μλ CPU λ°μ΄λ μμ μ κ°μ₯ μ μ©ν©λλ€.
- μμ λΉλ: μμ μ΄ μμ£Ό μ€νλλ κ²½μ° μ컀 μ€λ λλ₯Ό μμ±νκ³ μμ νλ μ€λ²ν€λκ° μλΉν μ μμ΅λλ€. μ€λ λ νμ μ΄λ₯Ό μννλ λ° λμμ΄ λ©λλ€.
- 리μμ€ μ μ½ μ‘°κ±΄: μ¬μ© κ°λ₯ν CPU μ½μ΄ λ° λ©λͺ¨λ¦¬λ₯Ό κ³ λ €νμμμ€. μμ€ν μ΄ μ²λ¦¬ν μ μλ κ²λ³΄λ€ λ λ§μ μ컀 μ€λ λλ₯Ό λ§λ€μ§ λ§μμμ€.
- λ체 μ루μ : λΉλκΈ° νλ‘κ·Έλλ°, WebAssembly λλ κΈ°ν λμμ± κΈ°μ μ΄ νΉμ μ¬μ© μ¬λ‘μ λ μ ν©νμ§ νκ°νμμμ€.
μ컀 μ€λ λ νμ μ΄μ κ³Ό ꡬν μΈλΆ μ¬νμ μ΄ν΄ν¨μΌλ‘μ¨ κ°λ°μλ μ΄λ₯Ό ν¨κ³Όμ μΌλ‘ νμ©νμ¬ κ³ μ±λ₯, μλ΅μ± λ° νμ₯ κ°λ₯ν JavaScript μ ν리μΌμ΄μ μ ꡬμΆν μ μμ΅λλ€.
μνλ μ±λ₯ ν₯μμ λ¬μ±νκ³ μλμ§ νμΈνκΈ° μν΄ μ컀 μ€λ λλ₯Ό μ¬μ©νκ±°λ μ¬μ©νμ§ μκ³ μ ν리μΌμ΄μ μ μ² μ ν ν μ€νΈνκ³ λ²€μΉλ§νΉνλ κ²μ μμ§ λ§μμμ€. μ΅μ μ ꡬμ±μ νΉμ μμ λΆν λ° νλμ¨μ΄ 리μμ€μ λ°λΌ λ€λ₯Ό μ μμ΅λλ€.
SharedArrayBuffer λ° Atomics(λκΈ°νμ©)μ κ°μ κ³ κΈ κΈ°μ μ λν μΆκ° μ°κ΅¬λ μ컀 μ€λ λλ₯Ό μ¬μ©ν λ μ±λ₯ μ΅μ νλ₯Ό μν ν¨μ¬ λ ν° μ μ¬λ ₯μ μ΄ μ μμ΅λλ€.