什么是 daemon 与服务 (service)

Linux Daemon (守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些事件。它不需要用户输入就能运行并且提供某种服 务,不是对整个系统就是对某个用户程序提供服务。 Linux 系统的大多数服务器就是通过守护进程实现的。常见的守护进程包括系统日志进程 syslogd 、 web 服务器 httpd 、邮件服务器 sendmail 和数据库服务器 mysqld 等。
 
守护进程一般在系统启动时开始运行,除非强行终止,否则直到系统关机都保持运行。守护进程经常以超级用户( root )权限运行,因为它们要使用特殊的端口( 1-1024 )或访问某些特殊的资源。
 
一个守护进程的父进程是 init 进程,因为它真正的父进程在 fork 出子进程后就先于子进程 exit 退出了,所以它是一个由 init 继承的孤儿进程。守护进程是非交互式程序,没有控制终端,所以任何输出,无论是向标准输出设备 stdout 还是标准出错设备 stderr 的输出都需要特殊处理。
 
工作原理
Linux 守护进程的工作模式是服务器 / 客户机( Server/Client ),服务器在一个特定的端口上监听( Listen )等待客户连接,连接成功后服务器和客户端通过端口进行数据通信。守护进程的工作就是打开一个端口,并且监听( Listen )等待客户连接。如果客户端产生一个连接请求,守护进程就创建( Fork )一个子服务器响应这个连接,而主服务器继续监听其他的服务请求。
 
 

注:Linux下可以直接调用damon函数来实现daemon进程,没必要重新实现,理解其原理即可。

在Linux中专门提供了一个函数来完成这个daemon化的过程,这个函数的原型如下

int daemon ( int __nochdir, int __noclose) ;

如果__nochdir的值为0,则将切换工作目录为根目录;如果__noclose为0,则将标准输入,输出和标准错误都重定向到/dev /null。

经过这个函数调用后的程序将运行在后台,成为一个daemon程序,而linux下大多的服务都是以此方式运行的。

我们来看一个简单的例子。例如编写例子程序test.c

#include <unistd.h>
#include <stdio.h>
int do_sth(){
//Add what u want
return ;
}
int main(){
daemon(,);
while(){
do_sth();
sleep();
}
}

编译并运行

[ leconte@ localhost daemon] $ gcc -o test test.c
[ leconte@ localhost daemon] $ ./ test

程序进入了后台,通过ps查看进程情况,可以看到进程的父进程id为1,即init进程

root        0.0  0.0       ?        Ss   :   : ./test

所谓的父进程是1这个表示怀疑

用lsof查看test进程所打开的文件,可以看到文件描述符0,1,2都被重定向到/dev/null
重定向到/dev/null也表示怀疑

并且能够看到,进程的当前工作目录(cwd)为根目录/,daemon函数已经帮我们完成了daemon化的过程,接下来我们只需要关注于程序功能的实现了。

daemon 的主要分类

依据 daemon 的启动与管理方式可以将 daemon 分为可独立启动的 stand alone , 与透过一支 super daemon 来统一管理两大类:

  • stand_alone:此 daemon 可以自行单独启动服务

stand alone 是『独立的启动』的意思。这种类型的 daemon 可以自行启动而不必透过其他机制的管理;
daemon 启动并加载到内存后就一直占用内存与系统资源。最大的优点:因为是一直存在内存内持续的提供服务,
因此对于客户端的请求,stand alone 的 daemon 响应速度较快。常见的
stand alone daemon 有 WWW 的 daemon (httpd)、FTP 的 daemon (vsftpd) 等等。

  • super daemon: 由一支特殊的 daemon 来统一管理

这一种服务的启动方式则是藉由一个统一的 daemon 来负责唤起服务!这个特殊的 daemon 就被称为 super daemon 。
早期的 super daemon 是 inetd,后来被 xinetd 取代了。当没有客户端的请求时,各项服务都是未启动的状态,等到有来自客户端的请求时, super daemon
才唤醒相对应的服务。当客户端的请求结束后,被唤醒的这个服务也会关闭并释放系统资源。

这种机制的好处是: (1)由于 super daemon 负责唤醒各项服务,因此 super daemon
可以具有安全控管的机制,类似网络防火墙!
(2)由于服务在客户端的联机结束后就关闭,因此不会一直占用系统资源。但是
因为有客户端的联机才会唤醒该服务,而该服务加载到内存的时间需要考虑进去,因此服务的反应时间会比较慢一些!
常见的 super daemon 所管理的服务有 telnet !

如上所示,Super daemon 是常驻在内存中的, Program 1, 2, 3 则是启动某些服务的程序 (未被启动状态)。当有客户端的请求时, Super daemon 才会去触发相关的程序加载成为 daemon 而存在于内存中,此时,客户端的请求才会被 Super daemon 导向 Daemon 1 去完成服务!当客户端的请求结束时,Daemon 1 将会被移除,图中实线的联机就会中断!

    • super daemon 的处理模式有两种,分别是这样:

      • multi-threaded (多线程):
      • single-threaded (单线程):
    • 如上所示,左侧为多线程的运行方式, daemon 会触发多支程序来给不同 client提供的服务,所以不论你是第几个请求者, 都可以享用 daemon 的服务。至于右侧则是单线程的方式,仅会有一支 daemon 被唤醒,第一个用户完成服务之前, 后续请求的用户就得要等待,因此它们的联机是不会成功的。
      • daemon 工作形态的类型
      • signal-control
        这种 daemon 是透过讯号来管理的,只要有任何客户端的请求进来,它就会立即启动去处理!例如打印机的服务 (cupsd)。
      • interval-control
        这种 daemon 则主要是『每隔一段时间就主动的去运行某项工作』,所以,你要作的是在配置文件指定服务要进行的时间与工作,
        该服务在指定的时间才会去完成工作。atd 与 crond
        就属于这种类型的 daemon  (每分钟侦测一次配置文件)

      • daemon 的命名守则

      通常会在服务的名称之后会加上一个 d ,例如例行性命令的创建的 at, 与 cron 这两个服务,
      他的程序文件名会被取为 atd 与 crond,这个 d 代表的就是 daemon
      的意思。


      服务与端口的对应

      系统所有的功能都是某些程序所提供的,而程序则是透过触发程序而产生的。同样的,系统提供的网络服务当然也是这样的!

      当客户端联机过来我们的主机时,
      我们主机是透过埠号 (port number)区分不同的服务

      两个网址都是指向 ftp.isu.edu.tw 义守大学的 FTP 网站,但是浏览器上面显示的结果却是不一样的!这是因为我们指向不同的服务!一个是 http 这个 WWW 的服务,一个则是 ftp
      这个文件传输服务。


      图 1.2.1、 port 与 daemon 的对应,客户端连接协议不同,服务导向端口号亦不同

      事实上,为了统一整个因特网的端口号对应服务的功能,好让所有的主机都能够使用相同的机制来提供服务与要求服务,
      所以就有了『通讯协议』这玩意儿。也就是说,有些约定俗成的服务都放置在同一个埠号上面啦!举例来说,
      网址列上面的 http 会让浏览器向 WWW 服务器的 80 埠号进行联机的要求!而 WWW 服务器也会将 httpd 这个软件激活在 port 80,
      这样两者才能够达成联机的!

      系统上有提供服务跟端口对应的配置文件: /etc/services!

[root@www ~]# cat /etc/services
....(前面省略)....
ftp /tcp
ftp /udp fsp fspd
ssh /tcp # SSH Remote Login Protocol
ssh /udp # SSH Remote Login Protocol
....(中间省略)....
http /tcp www www-http # WorldWideWeb HTTP
http /udp www www-http # HyperText Transfer Protocol
....(底下省略)....
# <daemon name> <port/封包协议> <该服务的说明>

daemon 的启动脚本与启动方式

提供某个服务的 daemon 虽然只是一支程序而已,但是这支 daemon 的启动还是需要运行档、配置文件、运行环境等等, 举例来说,你可以查阅一下 httpd 这个程序 (man httpd) ,里面可谈到不少的选项与参数!此外,为了管理上面的方便, 所以通常 distribution 都会记录每一支 daemon 启动后所取得程序的 PID 在 /var/run/ 这个目录下! 在启动这些服务之前,你可能也要自行处理一下 daemon 能够顺利运行的环境是否正确等等。鸟哥这里要讲的是, 要启动一支 daemon 考虑的事情很多,并非单纯运行一支程序就够了。

为了解决上面谈到的问题,因此通常 distribution 会给我们一个简单的 shell script 来进行启动的功能。 该 script 可以进行环境的侦测、配置文件的分析、PID 文件的放置,以及相关重要交换文件案的锁住 (lock) 动作, 你只要运行该 script ,上述的动作就一口气连续的进行,最终就能够顺利且简单的启动这个 daemon!

那么这些 daemon 的启动脚本 (shell script) 放在哪里啊?还有, CentOS 5.x 通常将 daemon 相关的文件放在哪里? 以及某些重要的配置文件又是放置到哪里?基本上是放在这些地方:

  • /etc/init.d/* :启动脚本放置处
    系统上几乎所有的服务启动脚本都放置在这里!事实上这是公认的目录,我们的 CentOS 实际上放置在 /etc/rc.d/init.d/ 啦!
    不过还是有配置连:结档到 /etc/init.d/ 的!既然这是公认的目录,因此建议您记忆这个目录即可!
  • /etc/sysconfig/* :各服务的初始化环境配置文件
    几乎所有的服务都会将初始化的一些选项配置写入到这个目录下,举例来说,登录档的 syslog 这支 daemon
    的初始化配置就写入在 /etc/sysconfig/syslog 这里呢!而网络的配置则写在 /etc/sysconfig/network 这个文件中。
    所以,这个目录内的文件也是挺重要的;
  • /etc/xinetd.conf, /etc/xinetd.d/* :super daemon 配置文件
    super daemon 的主要配置文件 (其实是默认值) 为 /etc/xinetd.conf ,不过我们上面就谈到了, super daemon
    只是一个统一管理的机制,他所管理的其他 daemon 的配置则写在 /etc/xinetd.d/* 里头喔!
  • /etc/* :各服务各自的配置文件
  • /var/lib/* :各服务产生的数据库
    一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中。举例来说,数据库管理系统 MySQL 的数据库默认就是写入
    /var/lib/mysql/ 这个目录下啦!
  • /var/run/* :各服务的程序之 PID 记录处
    我们在第十七章谈到可以使用讯号 (signal) 来管理程序,
    既然 daemon 是程序,所以当然也可以利用 kill 或 killall 来管理啦!不过为了担心管理时影响到其他的程序,
    因此 daemon 通常会将自己的 PID 记录一份到 /var/run/ 当中!例如登录文件的 PID 就记录在
    /var/run/syslogd.pid 这个文件中。如此一来, /etc/init.d/syslog 就能够简单的管理自己的程序啰。

上面谈到的部分是配置文件,那么 stand alone 与 super daemon 所管理的服务启动方式怎么作呢?他是这样做的喔:

  • Stand alone 的 /etc/init.d/* 启动

刚刚谈到了几乎系统上面所有服务的启动脚本都在 /etc/init.d/ 底下,这里面的脚本会去侦测环境、搜寻配置文件、 加载 distribution 提供的函数功能、判断环境是否可以运行此 daemon 等等,等到一切都侦测完毕且确定可以运行后, 再以 shell script 的 case....esac 语法来启动、关闭、 观察此 daemon 喔!我们可以简单的以 /etc/init.d/syslog 这个登录档启动脚本来进行说明:

[root@www ~]# /etc/init.d/syslog
用法: /etc/init.d/syslog {start|stop|status|restart|condrestart}
# 什么参数都不加的时候,系统会告诉你可以用的参数有哪些,如上所示。 范例一:观察 syslog 这个 daemon 目前的状态
[root@www ~]# /etc/init.d/syslog status
syslogd (pid ) 正在运行...
klogd (pid ) 正在运行...
# 代表 syslog 管理两个 daemon ,这两个 daemon 正在运行中啦! 范例二:重新让 syslog 读取一次配置文件
[root@www ~]# /etc/init.d/syslog restart
正在关闭核心记录器: [ 确定 ]
正在关闭系统记录器: [ 确定 ]
正在启动系统记录器: [ 确定 ]
正在启动核心记录器: [ 确定 ]
[root@www ~]# /etc/init.d/syslog status
syslogd (pid ) 正在运行...
klogd (pid ) 正在运行...
# 因为重新启动过,所以 PID 与第一次观察的值就不一样了!这样了解乎?

鸟哥的Linux私房菜 第十八章、认识系统服务 (daemons)的更多相关文章

  1. 鸟哥的Linux私房菜——第十八章:磁盘配额quota

    视频链接:http://www.bilibili.com/video/av10892470/ 磁盘配额quota的意思是给用户进行使用磁盘额度的空间的划分,举个例子,你的百度网盘的使用空间,其他云盘的 ...

  2. 鸟哥的linux私房菜学习记录之认识系统服务(daemons)

  3. 鸟哥的linux私房菜——第十六章学习(程序管理与 SELinux 初探)

    第十六章.程序管理与 SE Linux 初探 在 Linux 系统当中:"触发任何一个事件时,系统都会将他定义成为一个程序,并且给予这个程序一个 ID ,称为 PID,同时依据启发这个程序的 ...

  4. 鸟哥的Linux私房菜——第十九章:例行命令的建立

    视频链接:http://www.bilibili.com/video/av11008859/ 1. 什么是例行性命令 (分为两种,一种是周期性的,一种是突发性的)1.1 Linux 工作排程的种类: ...

  5. 鸟哥的Linux私房菜——第十四章:Bash Shell

    视频链接:http://www.bilibili.com/video/av10094012/ 本章目录: 1. Bash shell1.1 什么是 shell ? (我们通过shell与Kernel核 ...

  6. 鸟哥的Linux私房菜——第十二章:档案的压缩与打包

    视频链接: 土豆:http://www.tudou.com/programs/view/GncwT0FJKsQ B站(推荐):http://www.bilibili.com/video/av98857 ...

  7. 鸟哥的linux私房菜——第十二章学习(Shell Scripts)

    第十二章  Shell Scripts 1.0).什么是shell scripts? script 是"脚本.剧本"的意思.整句话是说, shell script 是针对 shel ...

  8. 鸟哥的Linux私房菜——第十六章:学习Shell Scripts

    视频链接:http://www.bilibili.com/video/av10565321/ 1. 什么是 Shell Script       (shell写的脚本)1.1 干嘛学习 shell s ...

  9. 鸟哥的Linux私房菜——第十五章:正规表示法

    视频链接 B站:http://www.bilibili.com/video/av10364761/ 目录如下 1. 前言:2. 基础正规表示法:2.1 以 grep 撷取字符串 (grep -iv   ...

随机推荐

  1. javaScript中with的用法

    1 JavaScript中的with语句的作用是为逐级的对象访问提供命名空间式的速写方式, 也就是在指定的代码区域, 直接通过节点名称调用对象 初次接触到with用法,是这样一段代码: 1 2 3 4 ...

  2. Kivy中文显示

    Win7系统 下载 DroidSansFallback.ttf字体(android设备上自带了) 源代码第一行增加#-*- coding:utf-8 -*- 创建widget值定font_name s ...

  3. 2016030208 - sql50题练习题

    数据库建表脚本和使用的数据请参考:http://www.cnblogs.com/zhtzyh2012/p/5235826.html sql50题练习参看:http://blog.sina.com.cn ...

  4. .Net平台下的B/S开发框架

    一.前言 本文主要是对.Net平台下的几种B/S开发框架进行比较.只对比前端展现和界面业务逻辑的部分,对于后台的数据层.业务层.持久层等则不作讨论,因为这些部分是完全可以共用的.  主要从如下几个维度 ...

  5. 写一个TT模板自动生成spring.net下面的配置文件。

    这个是目标. 然后想着就怎么开始 1.

  6. 使用Runnable接口创建线程-3

    实现Runnable接口的类必须使用Thread类的实例才能创建线程.通过Runnable接口创建线程分为两步: 1. 将实现Runnable接口的类实例化. 2. 建立一个Thread对象,并将第一 ...

  7. 修改.htaccess实现子目录绑定示例分享

    <IfModule mod_rewrite.c>RewriteEngine On  RewriteBase /# 把 www.jb51.net改为你要绑定的域名.# 如果是域名:Rewri ...

  8. 240多个jQuery插件

    概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是—写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不 ...

  9. sharepoint 2013创建外部内容类型并创建外部列表

    步骤: 1.如何:基于 SQL Server 表创建外部内容类型 How to: Create an External Content Type Based on a SQL Server Table ...

  10. 天草(初级+中级+高级)VIP和黑鹰VIP破解教程(全部iso下载地址)

    以下就是我收集的教程地址,之前我收集到的都是一课一课下载的,虽然这样,我也下载完了天草的全部课程.这里分享的是在一起的iso文件,比起一课课下载爽多了.~~ 还有这些教程都是从零起点开始教的,不用担心 ...