作为服务器运行

运行fwd等赢博体育程序的常见场景是将其作为真正的服务器赢博体育程序运行。以下是fwd在该模式下运行时的一些要求:

  1. 当您的赢博体育程序运行时,它将以特定用户的特权运行。我们需要安排赢博体育程序作为具有足够特权的用户运行,以执行赢博体育程序需要执行的赢博体育操作。
  2. 如果您的赢博体育程序需要访问系统上的文件或目录,则需要具有访问这些文件或目录所需的必要特权。
  3. 您的赢博体育程序将与许多其他赢博体育程序一起在服务器的后台运行。
  4. 如果赢博体育程序需要使用配置文件,则该文件通常存储在/等目录中。
  5. 如果您的程序需要写入日志文件,则该日志文件将存储在/var/log目录中。
  6. 作为赢博体育程序安装过程的一部分,您需要提供一个配置文件并将其放入/等目录中。
  7. 您很可能希望赢博体育程序在服务器启动时自动启动。为此,您需要使用服务器的init系统。
  8. 当赢博体育程序启动时,它应该把自己放在后台,然后在文件中保存它的进程id/run/fwd.pid。赢博体育程序还需要告诉init系统在哪里可以找到这个pid文件。
  9. 服务器可能正在使用一种称为日志轮换的特性。这是服务器上的一个特性,它将周期性地将赢博体育程序的日志文件轮换为一个新的空文件,然后压缩日志文件的前一个版本。日志轮换系统将通过向赢博体育程序发送SIGHUP信号来通知它日志文件已经更改。您的赢博体育程序必须为这个关闭并重新打开日志文件的信号安装一个信号处理程序。
  10. init系统还允许管理员重新启动赢博体育程序。例如,管理员可能希望在fwd.conf文件中添加新行,然后重新启动赢博体育程序。要重新启动赢博体育程序,init系统将向赢博体育程序发送SIGTERM信号,等待它关闭,然后重新启动赢博体育程序。

什么是初始化系统?

在Unix系统上,init赢博体育程序是管理启动过程的赢博体育程序。在许多现代Linux发行版中,常用的init系统是systemd赢博体育程序。您可能会遇到其他初始化系统,如upstart或更老的初始化赢博体育程序。

Systemd希望服务器赢博体育程序的开发人员编写一个特殊的配置文件,称为单元文件,以告诉Systemd如何管理其赢博体育程序的启动过程。下面是将用于fwd的单元文件的内容。

[Unit]
Description=Folder watcher application
[Service]
Type=forking
PIDFile=/run/fwd.pid
ExecStart=/opt/fwd/fwd
[Install]
WantedBy=multi-user.target

单元文件名为fwd.service。您将把这个单元文件放在/lib/systemd/system/目录中,这是systemd查找单元文件的标准目录之一。

一个单元文件由几个部分组成。下面是我在这些部分中设置的一些选项的描述。

[Unit]部分涵盖了服务的基本细节。Description选项提供了服务的简要描述。如果您要求systemd显示有关在机器上运行服务的详细信息,它将打印该描述,作为它显示给您的信息的一部分。

[Service]部分是配置服务最重要的部分。本节中的选项告诉systemd如何实际启动服务,以及服务启动时预期会发生什么。本节中最重要的选项是ExecStart选项,它指定了我们想要启动的赢博体育程序的路径。Type选项告诉systemd在启动赢博体育程序时期望什么。在这种情况下,由于赢博体育程序将分叉并创建一个子进程,该进程在赢博体育程序本身退出时在后台运行,因此我们需要告诉systemd不要担心赢博体育程序一启动就退出的事实。分叉赢博体育程序需要生成一个pid文件,该文件存储后台赢博体育程序的进程id。PIDFile选项告诉systemd在哪里可以找到该文件。当系统关闭或用户要求Systemd重新启动服务时,Systemd将使用该进程id关闭服务器赢博体育程序。

[Install]部分对于想要作为引导过程的一部分启动的服务是必需的。要在引导过程中为启动注册服务,必须启用该单元,并且必须在其单元文件中有一个[Install]节。WantedBy选项将此服务链接到systemd在引导过程中尝试启动的目标之一。多用户目标是systemd在引导时稍后启动的目标之一。

为了激活服务,我们构造一个单元文件,并将其放置在systemd查找单元文件的标准目录中。一旦我们创建了一个单元文件并将其放置在适当的位置,我们就可以要求systemd通过发出命令来启动它

Sudo systemctl start FWD

Systemctl是为systemd提供命令接口的终端赢博体育程序。

如果我们希望赢博体育程序在计算机启动时自动启动,我们必须告诉systemd启用它的单元。我们通过命令来完成

Sudo systemctl启用FWD

关于systemctl赢博体育程序和您可以使用它做的事情的更多信息可以在本文中在线获得。您可以在本文中了解有关单元文件中可用选项的更多信息。

成为一个精灵

大多数服务器赢博体育程序在系统上作为守护进程运行,这些守护进程是在后台长时间设计的进程。Michael Kerrisk的《The Linux Programming Interface》一书概述了大多数守护进程用来正确设置自己的过程。我将这些步骤总结如下。

要成为守护进程,程序通常在启动时执行以下步骤:

  1. 执行一个fork (),之后父进程退出,子进程继续。(因此,守护进程成为初始化过程。)这样做有两个原因:
    1. 假设守护进程是从命令行启动的,那么shell会注意到父进程的终止,然后显示另一个shell提示,让子进程继续在后台运行。
    2. 子进程保证不是进程组领导,因为它从父进程组ID继承了自己的进程组ID,并获得了自己的唯一进程ID,该进程ID与继承的进程组ID不同。为了能够成功执行下一步,这是必需的。
  2. 子进程调用setsid ()开始一个新的会话,并把自己从与控制终端的任何关联中解放出来。如果守护进程此后从未打开任何终端设备,那么我们就不需要担心守护进程重新获取控制终端。如果守护进程以后可能打开终端设备,那么我们必须采取措施确保该设备不会成为控制终端。为此,赢博体育程序执行第二次操作fork ()setsid ()调用,并且再次具有父退出和(孙子)子继续。这确保了子进程不是会话领导者,因此,根据System V获取控制终端的约定(Linux遵循),进程永远不能重新获取控制终端。
  3. 在执行最后的fork之后,子进程将把子进程的进程id保存在一个已知位置的文件中。这使得关闭孙子进程变得更容易。
  4. 通过调用清除进程umaskumask ()确保守护进程在创建文件和目录时具有所请求的权限。
  5. 通过调用更改进程的当前工作目录作用是(),通常到根目录(/)。这是必要的,因为守护进程通常运行到系统关闭;如果守护进程的当前工作目录位于包含/的文件系统之外的文件系统上,则无法卸载该文件系统。或者,守护进程可以将其工作目录更改为它执行任务的位置或其配置文件中定义的位置,只要我们知道包含此目录的文件系统永远不需要卸载即可。例如,cron将自己置于/var/spool/cron
  6. 关闭守护进程从其父进程继承的赢博体育打开的文件描述符。(守护进程可能需要将某些继承的文件描述符保持打开状态,因此此步骤是可选的,或者可以更改。)这样做的原因有很多。由于守护进程失去了它的控制终端并在后台运行,如果文件描述符0、1和2指向终端,那么守护进程保持打开这些描述符是没有意义的。此外,我们不能卸载长时间运行的守护进程使文件处于打开状态的任何文件系统。而且,像往常一样,我们应该关闭未使用的打开文件描述符,因为文件描述符是有限的资源。
  7. 关闭文件描述符0、1和2之后,一个守护进程通常会打开/ dev / null并使用dup2 ()(或类似的),使赢博体育这些描述符都指向这个设备。这样做有两个原因:
    1. 它确保如果守护进程调用对这些描述符执行I/O的库函数,这些函数不会意外失败。
    2. 它防止了守护进程以后使用描述符1或2打开文件的可能性,这些文件随后被库函数写入(并因此被破坏),库函数期望将这些描述符视为标准输出和标准错误。