Go - Run an application using systemd

发布时间 2023-09-22 10:09:15作者: ZhangZhihuiAAA

The systemd tool fits our simple case of requiring the application to start on server boot-up as well as ensuring that the application is restarted in the case that it crashes. Some configuration work is needed to accomplish this, which will be demonstrated
in the following sample configurations. 

First, we would need to create the following service file that would be managed by systemd. Let us say if our application to be managed on the server would be called on golang-app. With that in mind, we would save the configuration file in /etc/ systemd/system/golang-app.service. The configuration file would look as follows:

[Unit]
Description=Golang Application
Requires=network-online.target
After=network-online.target
[Service] User=golang-app Group=golang-app Restart=on-failure ExecStart=/usr/local/bin/golang-app KillSignal=SIGTERM
[Install] WantedBy=multi-user.target

In the Unit section of the preceding file, it contains the Description field, which we will see when we check the status of the service via command line. The Requires and After section is set such that the application only starts once networking in the server is properly started. We would want to avoid a situation where the application fails to start due to networking not yet fully up since the application is a web application. Networking being up is somewhat a prerequisite for the application to be running successfully.

In general, we would not want to have the application based on actual human users. Instead, we can create some sort of system user that would be tied to running this application. In our case, we can create a new user called golang-app, which would be in charge of running this application.

The next important parameter will be the Restart field. The restart field indicates when the application should be restarted. In some cases, we would not want this application to restart (assuming that we want to prevent some form of data corruption—maybe a developer needs to be involved to check for this). If this is the case, the Restart field should have the value of no, but this is not applicable for our case. We would want the application to restart when the application crashes—the on-failure value might be suitable for our case.

The more critical field would be the ExecStart, which is basically the field in the configuration file where we would identify which is the binary that we wish to run for this application. The path here should be an absolute file path so that would mean we cannot use file paths that would look something like this: “./” or ../golang-app.

Kill signals are essentially small pieces of data that an application can respond to if it has been coded for it and is sent while stopping the application. A SigTerm kill signal is a somewhat gentle way of telling the application that it is going to be shut down, and it should run shutdown procedures if it understands such signals. Some shutdown procedures that an application could do would be to stop accepting new requests or redirect currently happening requests to another servers. An alternative Kill signal would be SigKill, which would immediately kill the application without giving the application to cleanup and will stop the application without any pause.

scp -i ~/.ssh/new_user ./app new_user@<server>:app

zzh@ZZHPC:~$ sudo useradd golang-app
zzh@ZZHPC:~$ groups golang-app
golang-app : golang-app

sudo mv app /usr/local/bin/golang-app

sudo chown golang-app:golang-app /usr/local/bin/golang-app

sudo systemctl daemon-reload

sudo systemctl status golang-app

sudo systemctl start golang-app

The usual next steps when trying to debug the application would be the following:
• Read the logs of the application.
• Notice that we have not written in the configuration file where the log file would be at. So where would logs for the application be?
When applications are run, it is usually paired together with another utility called journald. Journald is a utility that mainly focuses on collecting and maintaining logs and is a somewhat centralized way of managing logs across applications on the server. Any application that is maintained and managed via the system will have its logs likewise managed by journald. And similar to systemd, the journald utility is managed via a command called journalctl.

$ sudo journalctl -u golang-app

$ sudo journalctl -u golang-app --since "1 minute ago"

$ sudo journalctl -u golang-app -g "start"

Once the application is up and running, curl commands that do HTTP requests against the server can be done, after which the logs can then be inspected further in order to understand how the application is behaving as it processes the HTTP requests.