restartとreloadの違いを調べてみた

## 勉強前イメージ

restartは一度プロセスをすべて落としてから起動させる
reloadは設定ファイルの読み込みって感じ。
ただ何が違うのかよくわかってない。
たまにreloadじゃだめでrestartしないと...みたいな場面あった気がする

## 調査

### restartとreloadの違い

- restart
	- 起動中のUnitを停止後、起動する
	- 再起動で失敗する場合は、起動しない
- reload
	- Unitに対して設定ファイルの再起動を促す
		- 対象のUnitがreload動作に対応している必要がある
	- 再読み込みで失敗する場合は停止しないので、稼働状態のまま続けられる

### reload:失敗しても起動状態 / restart:失敗したらfaild の検証

- 検証概要

1. httpdのインストールを行う
2. httpdを起動させる
3. 設定ファイルに故意に読み込みが失敗する文字列を追加
4. restart or reloadする

この検証であれば、restartは失敗するが、reloadはサービスが落ちない。

#### 1.httpdのインストールを行う

```
yum install -y httpd
```

#### 2. httpdを起動させる

```
systemctl start httpd.service
systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 金 2020-12-04 21:08:11 JST; 1s ago
   ....
```

#### 3. 設定ファイルに故意に読み込みが失敗する文字列を追加

```
vi /etc/httpd/conf/httpd.conf 
==========
追加
test
==========
```

```
[root@localhost ~]# head /etc/httpd/conf/httpd.conf 
test
#
# This is the main Apache HTTP server configuration file.  It contains the
# configuration directives that give the server its instructions.
# See <URL:http://httpd.apache.org/docs/2.4/> for detailed information.
# In particular, see 
# <URL:http://httpd.apache.org/docs/2.4/mod/directives.html>
# for a discussion of each configuration directive.
#
# Do NOT simply read the instructions in here without understanding
```

config testを行ったらもちろんエラーになってる

```
[root@localhost ~]# httpd -t
AH00526: Syntax error on line 1 of /etc/httpd/conf/httpd.conf:
Invalid command 'test', perhaps misspelled or defined by a module not included in the server configuration
```

#### 4. restart or reloadする

- reload

reloadでエラーになってるけど、statusはactiveのまま。

```
# reload前にstatus確認
[root@localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 金 2020-12-04 21:08:11 JST; 3min 32s ago
     Docs: man:httpd(8)
           man:apachectl(8)
 Main PID: 17309 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─17309 /usr/sbin/httpd -DFOREGROUND
           ├─17310 /usr/sbin/httpd -DFOREGROUND
           ├─17311 /usr/sbin/httpd -DFOREGROUND
           ├─17312 /usr/sbin/httpd -DFOREGROUND
           ├─17313 /usr/sbin/httpd -DFOREGROUND
           └─17314 /usr/sbin/httpd -DFOREGROUND

12月 04 21:08:11 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
12月 04 21:08:11 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
```

```
# reload を行う
[root@localhost ~]# systemctl reload httpd.service
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
```

```
# reload後にstatus確認
[root@localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) (Result: exit-code) since 金 2020-12-04 21:08:11 JST; 3min 44s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 17329 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=1/FAILURE)
 Main PID: 17309 (httpd)
   Status: "Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─17309 /usr/sbin/httpd -DFOREGROUND
           ├─17310 /usr/sbin/httpd -DFOREGROUND
           ├─17311 /usr/sbin/httpd -DFOREGROUND
           ├─17312 /usr/sbin/httpd -DFOREGROUND
           ├─17313 /usr/sbin/httpd -DFOREGROUND
           └─17314 /usr/sbin/httpd -DFOREGROUND

12月 04 21:08:11 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
12月 04 21:08:11 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
12月 04 21:11:49 localhost.localdomain systemd[1]: Reloading The Apache HTTP Server.
12月 04 21:11:49 localhost.localdomain httpd[17329]: AH00526: Syntax error on line 1 of /etc/httpd/conf/httpd.conf:
12月 04 21:11:49 localhost.localdomain httpd[17329]: Invalid command 'test', perhaps misspelled or defined by a module not included in the server configuration
12月 04 21:11:49 localhost.localdomain systemd[1]: httpd.service: control process exited, code=exited status=1
12月 04 21:11:49 localhost.localdomain systemd[1]: Reload failed for The Apache HTTP Server.
```

- restart

エラーになる までは一緒。
ただ再起動後のstatusはfailedになってる。

```
# restart前にstatus確認
[root@localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 金 2020-12-04 21:16:23 JST; 1s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 17373 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
  Process: 17360 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
 Main PID: 17378 (httpd)
   Status: "Processing requests..."
   CGroup: /system.slice/httpd.service
           ├─17378 /usr/sbin/httpd -DFOREGROUND
           ├─17379 /usr/sbin/httpd -DFOREGROUND
           ├─17380 /usr/sbin/httpd -DFOREGROUND
           ├─17381 /usr/sbin/httpd -DFOREGROUND
           ├─17382 /usr/sbin/httpd -DFOREGROUND
           └─17383 /usr/sbin/httpd -DFOREGROUND

12月 04 21:16:23 localhost.localdomain systemd[1]: Stopped The Apache HTTP Server.
12月 04 21:16:23 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
12月 04 21:16:23 localhost.localdomain systemd[1]: Started The Apache HTTP Server.
```

```
# restart
[root@localhost ~]# systemctl restart httpd.service
Job for httpd.service failed because the control process exited with error code. See "systemctl status httpd.service" and "journalctl -xe" for details.
```

```
# restart後にstatus確認
[root@localhost ~]# systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 金 2020-12-04 21:17:00 JST; 11s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 17392 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=0/SUCCESS)
  Process: 17360 ExecReload=/usr/sbin/httpd $OPTIONS -k graceful (code=exited, status=0/SUCCESS)
  Process: 17397 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 17397 (code=exited, status=1/FAILURE)

12月 04 21:17:00 localhost.localdomain systemd[1]: Starting The Apache HTTP Server...
12月 04 21:17:00 localhost.localdomain httpd[17397]: AH00526: Syntax error on line 1 of /etc/httpd/conf/httpd.conf:
12月 04 21:17:00 localhost.localdomain httpd[17397]: Invalid command 'test', perhaps misspelled or defined by a module not included in the server configuration
12月 04 21:17:00 localhost.localdomain systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
12月 04 21:17:00 localhost.localdomain systemd[1]: Failed to start The Apache HTTP Server.
12月 04 21:17:00 localhost.localdomain systemd[1]: Unit httpd.service entered failed state.
12月 04 21:17:00 localhost.localdomain systemd[1]: httpd.service failed.
```

#### 結論

reloadは設定ファイルの再読み込みがだめでもactiveのままだが、
restartは設定ファイルの再読み込みが正しく出来なかったら起動しない


### reloadは対象のUnitがreload動作に対応している必要がある

reloadは動作に対応している必要があると記載があったのですが、どこに記載があるか見ていきます。
まず、reloadが存在する `httpd.service` 、
次に、reloadが存在しない `chronyd.service` のUnitのファイルを見ていきます。

- reloadが存在する場合の設定ファイル(httpd)

`ExecReload=` というのがreloadを読み込んだときの動作です。

```text:/usr/lib/systemd/system/httpd.service
[root@localhost system]# cat /usr/lib/systemd/system/httpd.service 
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

実際にhttpdのreloadを叩いてみても設定ファイルに不備がなければ基本的には何も出力されません

```
[root@localhost ~]# systemctl reload httpd.service
[root@localhost ~]# 
```

- reloadが存在する場合の設定ファイル(chronyd)

以下がreloadが存在しない場合の設定ファイルです。
httpdでは存在した、 `ExecReload` の記述がありません。

```text:/usr/lib/systemd/system/chronyd.service
[root@localhost ~]# cat /usr/lib/systemd/system/chronyd.service 
[Unit]
Description=NTP client/server
Documentation=man:chronyd(8) man:chrony.conf(5)
After=ntpdate.service sntp.service ntpd.service
Conflicts=ntpd.service systemd-timesyncd.service
ConditionCapability=CAP_SYS_TIME

[Service]
Type=forking
PIDFile=/var/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full

[Install]
WantedBy=multi-user.target
```

実際にchronyでreloadを叩いてみてもchronyのユニットではreloadのジョブでは適応出来ないと言われてしまいました。

```
[root@localhost ~]# systemctl reload chronyd.service
Failed to reload chronyd.service: Job type reload is not applicable for unit chronyd.service.
See system logs and 'systemctl status chronyd.service' for details.
```

もちろんrestartはきちんと実行されます。

```
[root@localhost ~]# systemctl restart chronyd.service
[root@localhost ~]# 
```

## 勉強後イメージ

知りたかったのは、こういうときはreloadで出来て、こういうときはrestartじゃないとだめって言うのやったけど
ミドルウェアの設定で違うのかな...そうだよね...
この前、systemdの勉強したからなんとなくイメージがすっと入ってきた。
今まで設定ファイルまで見ることなかったけど、見たほうがイメージ湧くね。
あと、最近なんとなく書き方汚いからみずらい。。。自分で書いといてなんやけど

## 参考

- [【systemctl】の使い方 〜オプション一覧,自動起動,list-units/list-unit-filesの見方, reloadとrestartの違い, runningとexitedの違い〜](https://milestone-of-se.nesuke.com/sv-basic/linux-basic/systemctl/#)
- [「Systemd」を理解する ーシステム管理編ー](http://equj65.net/tech/systemd-manage/)
- [Systemd メモ書き](https://qiita.com/a_yasui/items/f2d8b57aa616e523ede4)
- [Systemd入門(4) - serviceタイプUnitの設定ファイル](https://enakai00.hatenablog.com/entry/20130917/1379374797)
- [Systemd入門(4) - serviceタイプUnitの設定ファイル](https://enakai00.hatenablog.com/entry/20130917/1379374797)