Trong quá trình vận hành hệ thống và hỗ trợ khách hàng quản trị dịch vụ, các máy chủ lâu lâu hay bị treo dịch vụ, dịch vụ bị tắt (services stop), và bạn cũng biết hệ thống thì đòi hỏi cách dịch vụ phải luôn luôn online. Thông thường lỗi này máy chủ thiếu tài nguyên (resources) nên các kill các process.
Thường mình hay gặp nhất ở các VPS khách hàng với lỗi OOM (Out of memory), thiếu tài nguyên RAM. Mình dùng lệnh dmesg
để check sơ bộ. Nếu các dịch vụ khác bị stop bạn có thể vào /var/log để kiểm tra thêm.
[root@sv.local.linuxcanban.com~]# dmesg
[13784267.946710] Out of memory in UB 2844: OOM killed process 1968 (mysqld) score 0 vm:1767928kB, rss:102780kB, swap:527836kB
[13806166.053265] Out of memory in UB 2844: OOM killed process 5889 (mysqld) score 0 vm:1777520kB, rss:33176kB, swap:314276kB
[13806170.976511] Out of memory in UB 2844: OOM killed process 5846 (php-fpm) score 0 vm:329920kB, rss:37732kB, swap:84896kB
[13815932.543655] Out of memory in UB 2844: OOM killed process 12722 (mysqld) score 0 vm:1777528kB, rss:43744kB, swap:327912kB
[13815937.812526] Out of memory in UB 2844: OOM killed process 20416 (mysqld) score 0 vm:234944kB, rss:137512kB, swap:0kB
Để khắc phục một số tình trạng này mình sẽ hướng dẫn bạn viết một script nhỏ để thay bạn start các dịch vụ khi stop. Nhưng trước tiên hãy kiểm tra các dịch vụ trước như sau.
Kiểm tra trạng thái dịch vụ.
Có rất nhiều lệnh để kiểm tra các trạng thái dịch vụ của bạn có chạy hay không, thường mình hay dùng lệnh ps và netstat để kiểm tra. Các lệnh này đi kèm các option và bạn cần thêm vào option để có hiệu lực khi nhập.
- Ví dụ: Mình dùng 2 lệnh ps và netstat để kiểm tra trạng thái mysqld.
2 lệnh đều trả về kết quả là 1 có nghĩa dịch vụ đang chạy.
[root@sv ~]# ps -ef | awk '{ print $8 }' | grep mysqld | wc -l 1 [root@sv ~]# netstat -tulpn | awk '{ print $7 }' | grep mysqld | wc -l 1 [root@sv ~]#
Chú thích lệnh:
ps -ef
: nó sẽ xuất ra màn hình tất cả các process đang chạy cùng thông tin của process đó.| awk '{ print $8 }'
: lấy ra cột thứ 8 trong kết quả lênh ps -ef| grep mysqld
: lấy ra những dòng có chữ mysqld| wc -l
: đếm số dòng có chữ mysqld
Lệnh start services
Trên hệ thống linux có nhiều cách để start dịch vụ, như systemctl start
, services mysqld restart
. Nhưng nếu dịch vụ quản lý trong /etc/init.d
bạn có thể dùng /etc/init.d/mysql start
để start dịch vụ.
Tìm hiểu về init.d
/etc/init.d
chứa các tập lệnh được sử dụng bởi các công cụ khởi động System V (SysVinit). Đây là gói quản lý dịch vụ truyền thống dành cho Linux, chứa init
chương trình (quy trình đầu tiên được chạy khi kernel đã khởi tạo xong) cũng như một số cơ sở hạ tầng để khởi động và dừng dịch vụ và định cấu hình chúng. Cụ thể, tập tin trong /etc/init.d
những kịch bản shell mà đáp ứng start
, stop
, restart
, và (khi được hỗ trợ) reload
lệnh để quản lý một dịch vụ cụ thể. Các tập lệnh này có thể được gọi trực tiếp hoặc (phổ biến nhất) thông qua một số trình kích hoạt khác (thường là sự hiện diện của một liên kết tượng trưng trong /etc/rc?.d/
).
Bắt đầu viết script
Bạn hãy tạo 1 file auto-start-services.sh
sau đó bạn các đoạn mã sau vào, bạn có thể dùng vi
vim
nano
để soạn thảo. Mình dùng vi để soạn thảo như sau.
vi /bin/auto-start-services.sh
Sau đó dán nội dung sau vào.
- Lưu ý: Bên dưới là mình thực hiện start mysqld, nếu bạn cần start các dịch vụ khác như httpd, nginx thì hãy thay vào nhé.
#!/bin/bash service=mysqld ## gán service= tên dịch vụ là mysqld if (( $(ps -ef | awk '{ print $8 }' | grep mysqld | wc -l) > 0 )) ## Nếu kiểm tra kết quả trả về 1 thì bỏ qua, trả về 0 sẽ start lại dịch vụ then echo "$service ready running" else /etc/init.d/$service start fi
Sau khi dán vào bạn thực hiện chmod lại file
chmod +x /bin/auto-start-services.sh
Tạo crontab để tự động chạy.
Bước cuối cùng bạn hãy tạo một cron để hệ thống tự động check, ví dụ bên dưới mình tạo cron 5 phút chạy một lần. Bạn chạy lệnh crontab -
e sau đó dán vào nội dung như sau.
*/5 * * * * sh /bin/auto-start-services.sh
Như vây là cứ mỗi 5 phút sẽ chạy một lần, dịch vụ stop sẽ tự động start lên lại.