How To Configure a Linux Service to Start Automatically After a Crash or Reboot – Part 2: Reference

1158
04-05-2023
How To Configure a Linux Service to Start Automatically After a Crash or Reboot – Part 2: Reference

Giới thiệu

Đâ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 Bizfly Cloud Server chạy CentOS 8.

- Cài đặt MySQL.

>> Có thể bạn quan tâm: Mysql là gì? Tổng hợp thông tin chi tiết nhất về 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

How To Configure a Linux Service to Start Automatically After a Crash or Reboot – Part 2: Reference - Ảnh 1.

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:

$ sudo kill -9 851

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ố.

>> Có thể bạn quan tâm: Tìm hiểu về Process trong Linux

SHARE