Linux 系统服务的配置

上篇文章 我们留了个坑, 最后提到了 init.d, systemd 这两个概念,在理解这两个概念前,我们先来了解另一个概念,那就是 Linux 上的 service。

如果硬要给 service 下个定义,还真有些不可描述。以笔者个人理解, Linux 上的 service 通常就是一个可以跑在后台的程序。具体来说,我们执行 ll /etc/init.d
这个目录下的可执行脚本都会对应一个程序。 然后这个程序我们可以通过 service xxxd startservice xxxd stop 去启动或是终止。

通常我们管理 service 有两种方式,而这两种方式就分别涉及到 init.d 和 systemd 了:

  • 一是通过 /etc/init.d 内的可执行脚本,对应的技术是 System V init,涉及到的命令通常是 service xxxc ...update-rc.d xxxc ...
  • 二是通过 /lib/systemd/system(debian) 或 /usr/lib/systemd/system/(redhat) 的配置文件,对应的技术是 systemd,涉及到的常用命令是 systemctl

上述的方式一是老方式,而方式二是最近几年发展起来的新方式。笔者开发和生产环境一直是使用 Ubuntu,所以,这里以 Ubuntu 为例进行说明。

在 Ubuntu14.04 及以前,我们只能使用 System V init,因为这时还没有引入 systemd,而在 Ubuntu15.04 后,引入了 systemd,所以在这之后的系统,推荐使用 systemd

接下来,我们以 mongodb 为例,分别以两种方式走下创建 service 的流程

Ubuntu14.04 创建 mongod service

mongodb 官方提供了二进制文件下载,在这里
下面我先说下我自己的部署标准

  1. 该软件整体安装在 /opt 目录下
  2. 相关的可执行文件如 mongomongod 全局可用
  3. 配置到系统服务,可开机启动

了解了以上思路,我们正式开始部署流程,注意以下所有操作都是在 root 账户下,后面不再赘述。

1. 先解压从官网下载的二进制文件包,在 /opt 目录下解压后,解压后文件目录如下

# tree /opt
/opt
└── mongodb-linux-x86_64-3.6.4
    ├── bin
    │   ├── bsondump
    │   ├── install_compass
    │   ├── mongo
    │   ├── mongod
    │   ├── mongodump
    │   ├── mongoexport
    │   ├── mongofiles
    │   ├── mongoimport
    │   ├── mongoperf
    │   ├── mongoreplay
    │   ├── mongorestore
    │   ├── mongos
    │   ├── mongostat
    │   └── mongotop
    ├── GNU-AGPL-3.0
    ├── MPL-2
    ├── README
    └── THIRD-PARTY-NOTICES

2. 创建相关文件及文件夹

# 进入到 mongodb 安装目录
cd /opt/mongodb-linux-x86_64-3.6.4

# 创建将来存放 mongo 数据的文件夹
mkdir data 

# 创建日志文件夹
mkdir logs

# 创建并编写配置文件, 并给到 755 的权限
vim mongod.conf

# 创建并编写 init.mongod, 用于将来注册进 init.d
vim init.mongod
chmod 755 init.mongod

配置文件 mongod.conf 内容如下

# mongod.conf
# Where to store the data.
dbpath = /opt/mongodb/data
storageEngine = wiredTiger
directoryperdb = true

# where to log
logpath = /opt/mongodb/logs/mongodb.log
logappend=true
logRotate = reopen

port = 27017

# daemon
fork = true

# Enable journaling, http://www.mongodb.org/display/DOCS/Journaling
journal=true

# Turn on/off security.  Off is currently the default
noauth = true
# auth = true
# keyFile = /srv/mongodb/conf/rs.key

# crawler repl
# replSet=rs_crawler

pidfilepath = /opt/mongodb/mongod.pid

init.mongod 内容如下

#! /bin/sh

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/opt/mongodb/bin/mongod
DAEMON_ARGS="-f /opt/mongodb/mongod.conf"
NAME=mongod
DESC=mongodb

RUNDIR=/opt/mongodb
PIDFILE=$RUNDIR/mongod.pid

test -x $DAEMON || exit 0

if [ -r /etc/default/$NAME ]
then
    . /etc/default/$NAME
fi

. /lib/lsb/init-functions

set -e

if [ "$(id -u)" != "0" ]
then
    log_failure_msg "Must be run as root."
    exit 1
fi

case "$1" in
  start)
    echo -n "Starting $DESC: "
    mkdir -p $RUNDIR
    touch $PIDFILE
    chown mongodb:mongodb $RUNDIR $PIDFILE
    chmod 755 $RUNDIR

    if [ -n "$ULIMIT" ]
    then
        ulimit -n $ULIMIT || true
    fi

    if start-stop-daemon --start --quiet --oknodo --umask 007 --pidfile $PIDFILE --chuid mongodb:mongodb --exec $DAEMON -- $DAEMON_ARGS
    then
        echo "$NAME."
    else
        echo "failed"
    fi
    ;;
  stop)
    echo -n "Stopping $DESC: "

    if start-stop-daemon --stop --retry forever/TERM/1 --quiet --oknodo --pidfile $PIDFILE --exec $DAEMON
    then
        echo "$NAME."
    else
        echo "failed"
    fi
    rm -f $PIDFILE
    sleep 1
    ;;

  restart|force-reload)
    ${0} stop
    ${0} start
    ;;

  status)
    status_of_proc -p ${PIDFILE} ${DAEMON} ${NAME}
    ;;

  *)
    echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
    exit 1
    ;;
esac

exit 0

3. 接下来为了解耦或是方便,我们可以创建一些软链接

ln -s /opt/mongodb-linux-x86_64-3.6.4 /opt/mongodb
ln -s /opt/mongodb-linux-x86_64-3.6.4/bin/mongod /usr/local/bin/mongod
ln -s /opt/mongodb-linux-x86_64-3.6.4/bin/mongo /usr/local/bin/mongo

# /opt/mongodb-linux-x86_64-3.6.4/bin 下的其它命令是否创建软链,根据自己需求

我们注意到,mongodb 的所有相关文件都在自己的目录内,如果外部引用的话,都是通过软链接的方式,这类似于设计模式中的桥接或是代理。

4. 注册到系统服务

# 创建 mongodb 的用户,通常这种系统服务,出于安全考虑,我们不会直接以 root 用户运行
# 我们首先创建一个 mongodb 用户,将来用这个用户运行 mongodb
# 下面的命令创建了 mongodb user,同时创建了 mongodb group,指定该用户无法登录系统,同时创建了家目录,此处家目录其实可以不创建,因为我们的部署流程中没用到 mongodb 的家目录
useradd mongodb --home-dir /var/lib/mongodb --shell /usr/sbin/nologin --create-home --user-group

# 将 mongodb 的安装目录 全部交给 mongodb 用户
chown -R mongodb:mongodb /opt/mongodb /opt/mongodb-linux-x86_64-3.6.4

# 将 init.mongod 文件软链到 /etc/init.d/mongod, 注册成系统服务
ln -s /opt/mongodb/init.mongod /etc/init.d/mongod
# 下面的命令是为了将 mongod 软链到不同的 runlevel,以便于开机启动 mongod,其执行结果如下
# runlevel 不理解的话,可以简单参考 http://www.mikewootc.com/wiki/linux/usage/ubuntu_service_usage.html
# 这篇文章有个大概的介绍,能给您从一个点对这些概念初步了解,如果想要详细了解,再详查
update-rc.d -f mongod defaults

    update-rc.d: warning: /etc/init.d/mongod missing LSB information
    update-rc.d: see <http://wiki.debian.org/LSBInitScripts>
     Adding system startup for /etc/init.d/mongod ...
       /etc/rc0.d/K20mongod -> ../init.d/mongod
       /etc/rc1.d/K20mongod -> ../init.d/mongod
       /etc/rc6.d/K20mongod -> ../init.d/mongod
       /etc/rc2.d/S20mongod -> ../init.d/mongod
       /etc/rc3.d/S20mongod -> ../init.d/mongod
       /etc/rc4.d/S20mongod -> ../init.d/mongod
       /etc/rc5.d/S20mongod -> ../init.d/mongod

5. 启动关闭 mongod

# 以下命令启动 mongod, 会输出下面的结果
service mongod start

    Starting mongodb: about to fork child process, waiting until server is ready for connections.
    forked process: 1479
    child process started successfully, parent exiting
    mongod.
    
# 查看 mongod 状态    
service mongod status
    * mongod is running  # 启动时的状态
    * mongod is not running  # 关闭时的状态

# 关闭 mongod
service mongod stop

Ubuntu18.04 创建 mongod service

在 Ubuntu18.04 上面,也可以通过与 Ubuntu14.04 流程一样,创建 service。但是,当我们创建完成后,通过 service mongod start 启动服务时,会报如下错误

Failed to start mongod.service: Unit mongod.service not found.

这是什么意思呢?

因为在 Ubuntu18.04 中,系统已经主要通过 systemd 来管理服务,所以,如果只是在 /etc/init.d 中注册了服务,还不够,需要根据我的 上篇文章,
/lib/systemd/system 中注册 mongod.sevice 配置文件。当这个也配置好后,就可以通过 service mongod start 启动服务了,此时输出如下:

● mongod.service - mongodb server
   Loaded: loaded (/opt/mongodb/mongod.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-10-16 19:26:53 CST; 10s ago
 Main PID: 25089 (mongod)
    Tasks: 23 (limit: 478)
   CGroup: /system.slice/mongod.service
           └─25089 /opt/mongodb/bin/mongod -f /opt/mongodb/mongod.conf

Oct 16 19:26:53 iZ8vb9wvg14ypn9rjj3sdpZ systemd[1]: Started mongodb server.

此时的输出结果与执行 systemctl status mongod.service 结果一样,而并不是我们在 init.mongod 脚本中写的输出的内容,所以我怀疑,在 Ubuntu18.04 中,service 命令底层是不是还是调用了 systemctl 命令。另外,我们发现这个输出比 Ubuntu14.04 上面的好看一些。然后这也解答了我 上篇文章 的疑惑,即我们在 apt install ... 的时候,不仅把服务注册到了 systemd,还注册到了 init.d, 所以我们在管理服务时,既可以通过 service mongod ..., 也可以通过 systemctl ... mongod 来控制。

但是为了方便起见,我们在较新版本的系统上,自行配置服务时,笔者建议采用 systemd 配置。

那么既然 systemd 可以实现以上需求,为什么新版本系统还不丢弃 init.d 呢?

笔者看来,首先 systemd 的功能并不能完全覆盖 init.d,比如 init.d 里面的服务,可以配置 runlevel,但是 systemd 中貌似并没有这种功能,虽然绝大多数场景用不到 runlevel 的特性。另外一点是,init.d 中的脚本,我们可以随意自定义命令,而 systemd 中只有些固定的 start/stop 等命令。

当然,软件行业一个新技术要代替老技术,真的阻力太大,我们有时候甚至不知道这个阻力到底是好是坏。我们经常看到,一个新技术,远远优于一个老技术,但是就是没法完全取代老技术,最后的结果往往是新技术不得不费了吃奶的劲儿以一个丑陋的方式去兼容老技术。

最后,如果您想要更多的了解 systemd,你可以参考 鸟哥的文档,本文只是给您展示了一个基本的东西,如果读者朋友希望有更全面的更深入的理解,还是建议读一些成体系的文档。

至此,Linux 上面服务的配置,就基本说完了。希望对于想要入门 Linux 系统服务的您来说有所帮助,也期待您留言讨论。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容