What is Process Management?
Process management in Node.js is about controlling your application's lifecycle.
It includes:
- Starting and stopping applications
- Restarting after crashes
- Monitoring performance
- Handling system signals
- Managing environment variables
Accessing Process Information
The process object gives you details about and control over the current Node.js process.
Here are some useful properties:
// Process identification
console.log('Process ID (PID):', process.pid);
// Platform information
console.log('Platform:', process.platform);
console.log('Node.js version:', process.version);
// Memory usage (in bytes)
console.log('Memory usage:', process.memoryUsage());
// Command line arguments
console.log('Arguments:', process.argv);
Exiting a Process
You can control when your Node.js program stops using these methods:
1. Normal Exit
// Exit with success (status code 0)
process.exit();
// Or explicitly
process.exit(0);
2. Exit with Error
// Exit with error (status code 1)
process.exit(1);
3. Before Exit Event
// Run cleanup before exiting
process.on('beforeExit', (code) => {
console.log('About to exit with code:', code);
});
Handling Process Events
Node.js processes can respond to system signals and events.
Here are the most common ones:
1. Handling Ctrl+C (SIGINT)
// Handle Ctrl+C
process.on('SIGINT', () => {
console.log('\nGot SIGINT. Press Control-D to exit.');
// Perform cleanup if needed
process.exit(0);
2. Handling Process Termination (SIGTERM)
process.on('SIGTERM', () => {
console.log('Received SIGTERM. Cleaning up...');
// Perform cleanup if needed
process.exit(0);
});
2. Handling Process Termination (SIGTERM)
process.on('SIGTERM', () => {
console.log('Received SIGTERM. Cleaning up...');
server.close(() => {
console.log('Server closed');
process.exit(0);
});
});
3. Uncaught Exceptions
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
// Perform cleanup if needed
process.exit(1); // Exit with error
});
Process Managers
For production environments, use a process manager to keep your application running smoothly.
PM2 is the most popular choice:
1. Install PM2 Globally
npm install -g pm2
2. Basic PM2 Commands
# Start an application
pm2 start app.js
# List all running applications
pm2 list
# Monitor resources
pm2 monit
# View application logs
pm2 logs
# Stop an application
pm2 stop app_name
# Restart an application
pm2 restart app_name
# Delete an application from PM2
pm2 delete app_name
3. PM2 Configuration
Create an ecosystem file for advanced configuration:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'my-app',
script: 'app.js',
instances: 'max',
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development',
},
env_production: {
NODE_ENV: 'production',
}
}]
};
PM2 provides many other features like load balancing, monitoring, and log management.
Environment Variables
Environment variables are key-value pairs that configure your application's behavior in different environments.
Accessing Environment Variables
// Get a specific environment variable
const apiKey = process.env.API_KEY;
// Set a default value if not defined
const port = process.env.PORT || 3000;
// Check if running in production
const isProduction = process.env.NODE_ENV === 'production';
// List all environment variables
console.log('Environment variables:', process.env);
Loading Environment Variables from .env File
# Install dotenv package
npm install dotenv
Note: Best Practices for Environment Variables: Never commit sensitive data to version control Use
.envfor local development Set environment variables in production through your hosting platform Document all required environment variables in your README
Child Processes
Node.js can run system commands and other scripts using the child_process module.
1. Execute a Simple Command
const { exec } = require('child_process');
exec('ls -la', (error, stdout, stderr) => {
if (error) {
console.error(`Error: ${error.message}`);
return;
}
if (stderr) {
console.error(`stderr: ${stderr}`);
return;
}
console.log(`Output: ${stdout}`);
});
2. Using spawn for Large Output
const { spawn } = require('child_process');
// Better for large data output
const child = spawn('find', ['/', '-type', 'f']);
child.stdout.on('data', (data) => {
console.log(`Found file: ${data}`);
});
child.stderr.on('data', (data) => {
console.error(`Error: ${data}`);
});
child.on('close', (code) => {
console.log(`Child process exited with code ${code}`);
});
Process Monitoring and Performance
1. Memory Usage
// Get memory usage in MB
function getMemoryUsage() {
const used = process.memoryUsage();
return {
rss: `${Math.round(used.rss / 1024 / 1024 * 100) / 100} MB`,
heapTotal: `${Math.round(used.heapTotal / 1024 / 1024 * 100) / 100} MB`,
heapUsed: `${Math.round(used.heapUsed / 1024 / 1024 * 100) / 100} MB`,
external: `${Math.round(used.external / 1024 / 1024 * 100) / 100} MB`
};
}
// Monitor memory usage every 5 seconds
setInterval(() => {
console.log('Memory usage:', getMemoryUsage());
}, 5000);
2. CPU Usage
const startUsage = process.cpuUsage();
// Do some CPU-intensive work
for (let i = 0; i < 1000000000; i++) {}
const endUsage = process.cpuUsage(startUsage);
console.log('CPU usage (user):', endUsage.user / 1000, 'ms');
console.log('CPU usage (system):', endUsage.system / 1000, 'ms');
Key Takeaways
- Process Object: Access system and process information
- Process Control: Start, stop, and manage application lifecycle
- Environment Variables: Configure app behavior across different environments
- Child Processes: Run system commands and other scripts
- Error Handling: Handle uncaught exceptions and rejections
- Signals: Respond to system signals like SIGINT and SIGTERM
- PM2: Essential for production process management
- Performance Monitoring: Track memory and CPU usage
Effective process management is crucial for building reliable and maintainable Node.js applications, especially in production environments.