How To Configure a Linux Service to Start Automatically After a Crash or Reboot – Part 2: Reference
Đây là phần hai của chủ đề. Phần một bao gồm các khái niệm quản lý dịch vụ Linux chung như init daemon và runlevels. Bài viết kết thúc bằng một bài thực hành quản lý dịch vụ trong systemd. Ở đây, bạn sẽ sử dụng các file `targets`, `wants`, `requires`, và `unit`. Phần hai sẽ cung cấp một ví dụ thực tế với cơ sở dữ liệu MySQL.
- Một máy chủ chạy CentOS 8, bao gồm cả người dùng non-root với đặc quyền sudo. Để cài đặt tất cả những thứ này bạn có thể tạo một Cloud Server chạy CentOS 8.
- Cài đặt MySQL.
Cấu hình MySQL để tự khởi động sau khi khởi động bằng `systemd`
Khi đã cài đặt MySQL, kiểm tra trạng thái dịch vụ:
$ sudo systemctl status mysqld.service
Output sẽ cho thấy rằng dịch vụ đang chạy, nhưng daemon bị disabled:
Output
mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service;disabled; vendor preset: disabled)
Active: active (running) since Thu 2020-12-24 23:48:56 UTC; 1h 6min ago
Process: 30423 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 30294 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)
Process: 30270 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 30378 (mysqld)
Status: "Server is operational"
Tasks: 40 (limit: 4763)
Nếu dịch vụ đang enabled, tạm thời ta sẽ disabled đi, bằng câu lệnh sau:
$ sudo systemctl disable mysqld.service
Tiếp theo, chạy lệnh này để kiểm tra nếu xem MySQL có được [multi-user.target](http://multi-user.target) truy cập hay không:
$ sudo systemctl show --property "Wants" multi-user.target | fmt -10 | grep mysql
Không có gì trả về. Bây giờ hãy kiểm tra xem liên kết có tồn tại không:
$ sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
Một thông báo xuất hiện cho biết file này không tồn tại:
Output
ls: cannot access '/etc/systemd/system/multi-user.target.wants/mysql*': No such file or directory
Bây giờ, hãy khởi động lại máy chủ và kiểm tra dịch vụ MySQL.
Ta sẽ enabled lại dịch vụ MySQL:
sudo systemctl enable mysqld.service
Lúc này, hệ thống sẽ tạo một symlink như sau `/etc/systemd/system/multi-user.target.wants/`:
Output
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
Chạy lại lệnh ls để xác nhận lại điều này:
sudo ls -l /etc/systemd/system/multi-user.target.wants/mysql*
Output của lệnh trên như sau là đã thành công
Output
lrwxrwxrwx 1 root root 38 Aug 1 04:43 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service
Bật hoặc tắt dịch vụ systemd sẽ tạo hoặc xóa symlink khỏi thư mục của target mặc định.
Nếu bạn muốn, hãy khởi động lại Cloud Server một lần nữa và hãy chạy lệnh ps -ef để kiểm tra process của mysql có đang chạy hay không:
ps -ef | grep mysql
Lệnh này sẽ cung cấp thông tin về process MySQL đang chạy:
[secondary_label Output]\
mysql 851 1 2 04:26 ? 00:00:02 /usr/libexec/mysqld --basedir=/usr
Bây giờ ta đã cấu hình MySQL để tự động khởi động sau khi reboot. Tiếp theo chúng ta sẽ thiết lập trong trường hợp gặp sự cố với Cloud Server
Cấu hình MySQL để tự động khởi động khi gặp sự cố dùng `systemd`
Mặc định, MySQL được cấu hình để tự động khởi động lại sau khi gặp sự cố. Chúng ta hãy thử tắt nó đi nhé:
Mở unit file dịch vụ MySQL bằng vi:
$ sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service
Nội dung file cấu hình sẽ như sau:
[Unit]
Description=MySQL 8.0 database server
After=syslog.target
After=network.target
[Service]
Type=notify
User=mysql
Group=mysql
ExecStartPre=/usr/libexec/mysql-check-socke
ExecStartPre=/usr/libexec/mysql-prepare-db-dir %n
`# Note: we set --basedir to prevent probes that might trigger SELinux alarms,`
`# per bug #547485`
ExecStart=/usr/libexec/mysqld --basedir=/usr
ExecStartPost=/usr/libexec/mysql-check-upgrade
ExecStopPost=/usr/libexec/mysql-wait-stop
`# Give a reasonable amount of time for the server to start up/shut down`
TimeoutSec=300
`# Place temp files in a secure directory, not /tmp`
PrivateTmp=true
Restart=on-failure
RestartPreventExitStatus=1
`# Sets open_files_limit`
LimitNOFILE = 10000
`# Set enviroment variable MYSQLD_PARENT_PID. This is required for SQL restart command.`
Environment=MYSQLD_PARENT_PID=1
[Install]
WantedBy=multi-user.target
Như ta có thể thấy giá trị của tham số **Restart** được đặt là **********************on-failure**********************. Điều này có nghĩa là dịch vụ MySQL sẽ khởi động lại khi nhận được các mã lỗi không thành công hoặc thời gian chờ quá lâu.
Dưới đây là bảng thể hiện danh sách giá trị cho tham số Restart và các trạng thái exit mà các tham số này thực hiện Restart lại service
Trong unit file dịch vụ systemd, hai tham số - `Restart` and `RestartSec` - kiểm soát hành vi sự cố. Tham số đầu tiên chỉ định thời điểm khởi động lại dịch vụ và tham số thứ hai xác định khoảng thời gian dịch vụ sẽ đợi trước khi khởi động lại.
Để kiếm tra hành vi sự cố hãy dừng tiến trình MySQL bằng kill -9 signal. Trong trường hợp của chúng tôi , PID chính là 851; hay thay thế PID của bạn:
Chờ vài giây sau đó kiểm tra trạng thái:
$ sudo systemctl status mysqld.service
Đầu ra sẽ hiện thị MySQL đã khởi động lại với PID mới :
Output
mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2020-12-25 04:47:48 UTC; 55s ago
Process: 1420 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
Process: 1559 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 1476 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS)Process: 1451 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 1513 (mysqld)
Status: "Server is operational"
...
Tiếp theo mở lại unit file:
$ sudo vi /etc/systemd/system/multi-user.target.wants/mysqld.service
Comment lại tham số cấu hình Restart trong unit file của daemon MySQL và lưu lại. Điều này sẽ vô hiệu hóa hành vi khởi động lại:
``# Restart=on-failure``
Sau đó, reload lại systemd và khởi động lại dịch vụ mysqld:
$ sudo systemctl daemon-reload
$ sudo systemctl restart mysqld.service
Ta tìm PID chính của dịch vụ bằng cách chạy lệnh này:
$ sudo systemctl status mysqld.service
Output
. . .
Main PID: 1895 (mysqld)
Dùng lệnh kill -9 với PID chính của MySQL trong môi trường của bạn:
sudo kill -9 1895
Kiểm tra trạng thái cho MySQL:
sudo systemctl status mysqld.service
Output hiển thị dịch vụ đã bị lỗi và Exit:
Output
mysqld.service - MySQL 8.0 database server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: **failed** (Result: signal) since Fri 2020-12-25 05:07:22 UTC; 1min 14s ago
Process: 1976 ExecStopPost=/usr/libexec/mysql-wait-stop (code=exited, status=0/SUCCESS)
Process: 1940 ExecStartPost=/usr/libexec/mysql-check-upgrade (code=exited, status=0/SUCCESS)
Process: 1895 ExecStart=/usr/libexec/mysqld --basedir=/usr (code=killed, signal=KILL)
Process: 1858 ExecStartPre=/usr/libexec/mysql-prepare-db-dir mysqld.service (code=exited, status=0/SUCCESS
Process: 1833 ExecStartPre=/usr/libexec/mysql-check-socket (code=exited, status=0/SUCCESS)
Main PID: 1895 (code=**killed**, signal=KILL)
...
Ta vừa mô phỏng sự cố trong đó dịch vụ đã dừng và không hoạt động trở lại. Do ta đã thiết lập systemd không khởi động lại dịch vụ sau bị stop bởi lỗi. Nếu bạn sửa mysql.service unit file để bỏ comment tham số Restart, lưu nó , reload daemon systemctl và cuối cùng khởi động lại dịch vụ để khôi phục lại cấu hình mặc định.
Đây là cách ta có thể cấu hình dịch vụ systemd để tự khởi động sau sự cố. Tất cả những gì ta phải làm là thêm tham số `Restart`(và tùy chọn `RestartSec`) trong phần `[Service]` của service unit file.
Phần kết luận
Trong phần hai này, ta đã tìm hiểu về các daemon quản lý dịch vụ được sử dụng ở Linux.
Sau đó ta đã biết được các nguyên tắc cơ bản của systemd và áp dụng vào một ví dụ thực tế: cấu hình cơ sở dữ liệu để tự động khởi động lại sau khi reboot hoặc gặp sự cố.
Phạm Thanh Long
Pho Tue SoftWare Solutions JSC là Nhà Cung cấp dịch Trung Tâm Dữ Liệu, Điện Toán Đám Mây Và Phát Triển Phần Mềm Hàng Đầu Việt Nam. Hệ Thống Data Center Đáp Ứng Mọi Nhu Cầu Với Kết Nối Internet Nhanh, Băng Thông Lớn, Uptime Lên Đến 99,99% Theo Tiêu Chuẩn TIER III-TIA 942.
Leave a comment
Your email address will not be published. Required fields are marked *