文章目录
1. linux中的service是什么?
service其实事守护进程(daemon process),有如下2个特点:
- 开机自启动
- 运行在后台
1.1 linux中的进程
进程终止的原因:
- 正常返回
- 收到信号,异常退出
常见信号:
查看命令: kill -l
SIGTERM: 15, 允许进程执行完毕后退出,可被进程忽略,kill命令发出的默认信号
SIGINT: 2, ctrl+c会发出该信号,效果类似SIGTERM
SIGKILL: 9, 进程立刻退出,不能被忽略
进程对信号的处理方式:
1) 进程退出
2) 忽略信号,继续执行
3) 调用信号处理函数
1.2 进程异常退出如何排查程序错误?
1) 查看日志,调试时输出日志非常重要,方便排查错误
2) gdb调试coredump文件
3) 思考程序运行时的环境,运行方式的可能影响,改变运行方式看能否复现错误
4) 看源码
coredump文件如何产生和调试?
linux默认不允许coredump,可能需要使用root权限更改下core文件的大小限制
a) ulimit -c 查看core文件容量限制,若为0,改为 unlimited: ulimit -c unlimited
b) 指定core文件的输出路径和文件名的格式:
echo “path/file” > /proc/sys/kernel/core_pattern
file可使用core-%e-%u-%g-%h-%p-%s-%t
%e: 程序文件名
%u: 用户名
%g: 用户组
%h: 主机名
%p: 进程ID
%s: 导致本次core dump的信号
%t: core dump的时间(离1970.01.01:00:00:00的秒数)
c) gdb -g 二进制文件 core文件,注意二进制文件编译时一定要加上-g调试模式
什么情况下会产生core文件?
1) 内存访问越界(数组,如字符串数组)
2) 多线程程序使用了线程不安全的函数
3) 多线程程序共享数据未加锁,访问冲突
4) 非法指针(如对空指针操作,指针未初始化访问了非法地址)
5) 堆栈溢出
1.3 代码中的退出
- 进程
exit(num)是进程直接向产生他的角色(如一般父进程或init进程)发信号,退出程序;
return是语言层面的退出,实际上会调用exit,不管return什么在操作系统看起来都是
正常退出 - 线程
一个线程调用exit或return都会影响另一个线程,导致全部退出
pthread_exit仅仅使得当前线程退出
1.4 nohup 和 后台任务(jobs)是咋回事?
示例命令: nohup ./foo > log.txt 2>&1 &
拆解:
1) nohup: 表示忽略SIGHUP信号,继续当前进程
SIGHUP信号什么时候发出?
当前进程所在的控制终端死亡时(如ssh远程登录后退出登录)
使用 nohup 的效果:
a) 若不使用输出重定向则把日志输出到nohup.out文件中
b) 退出登录,与远程shell断开连接,进程仍继续执行直到结束
-
2>&1: 表示把标准错误重定向到标准输出,&表示对标准输出的引用,整体效果是
把标准输出和标准错误重定向到log.txt中 -
&: 表示把当前进程放到后台执行,如果没有重定向则log仍然会输出到屏幕
±---- 4 行: 如果不想输出到屏幕也不想输出到文件则重定向到 /dev/null
1.5 进程运行后如何监控?
top, ps, systemd的log或程序自己输出的log
1.6 linux如何自定义守护进程?
旧方式: service命令
新方式: systemd的命令
1.6.1 linux的开机启动过程
使用init进程的service命令:
bios自检 -> 操作系统接管 -> 读取/boot目录下的内核文件 ->
运行init进程 -> 读取/etc/inittab获取运行级别 -> 运行启动守护进程的
脚本 -> 用户登录 -> login shell
init进程后,用户登录前的两步是启动守护进程的流程
运行级别:
分为0-6,每次系统启动只能选定一种运行级别,不同的运行级别可设置不同的守护
进程集合,可以设置默认的运行级别
运行级别3: 完全的多用户状态(有NFS),登录后进入控制台命令行模式
运行级别5: X11控制台,登录后进入图形GUI模式
设置操作系统默认的运行级别: 更改 /etc/inittab文件
设置守护进程可被执行的运行级别: 在/etc/init.d中建立配置文件
注册守护进程到对应级别的守护进程集合中: insserv工具
用户登录可选3种方式,与运行级别相关:
1) 图形界面
2) 命令行登录,tty1-tty6都可用,ctrl+alt+f1(…, f6)切换,ctrl+alt+f7退出
3) ssh登录
service启动方式的缺点:
1) 串行启动,耗时长
2) 启动脚本复杂,脚本需要处理启动遇到的各种情况(如启动失败,重启方式,服务的
依赖等)
1.6.2 新一代的systemd
- 并行启动
- 考虑了启动时的各种情况,简单配置即可
详细使用教程:
- 将准备以守护进程运行的可执行文件放在/usr/local/sbin目录下
- 进入/lib/systemd/system编写 **.service配置文件
- sudo systemctl enable ** 设置开机启动
如果想立即运行,则将3)替换为
a) 重新加载修改后的配置文件
sudo systemctl daemon-reload
b) 启动服务
sudo systemctl start ** 或者
sudo systemctl restart **
为什么放在/usr/sbin目录下:
1) /bin, /usr/bin, /sbin, /usr/sbin均在PATH环境变量中,意味着开机时系统
能搜索到
2) /bin 放置系统的必备执行文件,如cat, cp, ls, mount等
/usr/bin 放置应用程序的必备执行文件,如g++, diff, gzip
/sbin放置系统管理的必备程序,如fdisk
/usr/sbin放置网络管理的必备程序,如httpd, samba, tcpdump
/是系统核心的程序
/usr是系统级别次核心的程序,类似C:/Windows
/usr/local是用户编译的程序, 类似C:/Program Files/
/opt是用户编译的不那么重要的程序,类似 D:/Software 当不需要时,直接rm -rf
都没问题,当磁盘容量不够时,也可将/opt挂载到其他磁盘使用
参见阮一峰的博客:
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-commands.html
http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
配置文件位置:
配置文件: /lib/systemd/system
指向配置文件的符号链接: /etc/systemd/system
配置文件编写:
[Unit]
[Service] 设置待执行程序的路径,进程启动,杀死,重启的方式等
[Install] 设置类似service机制提供的运行级别
常见命令:
systemctl status **.service
(Loaded): 是否开机启动以及配置文件的位置
(Active): 是否正在运行
sudo systemctl start **.service
sudo systemctl stop **.service
sudo systemctl restart **.service
sudo systemctl kill **.service
sudo systemctl reload **.service
sudo systemctl daemon-reload
systemctl list-dependencies
systemctl list-unit-files --type=service
(enabled): 已经设置开机启动
(disabled): 未设置开机启动
(static): 配置文件无[Install]部分,只能作为其他配置文件的依赖
(masked): 被禁止建立启动连接
systemctl cat **.service
systemctl list-dependencies **.target // 查看一个target包含的所有unit
systemctl get-default // 查看启动时的默认target
sudo systemctl enable ** // 设置开机启动(自动创建到配置文件的符号链接)
sudo journalctl -u **.service // 查看某个service的日志(只要打印输出就是日志)
1.6 linux发行版
ubuntu, debain同源,使用apt管理程序包
redhat, centos同源,使用yum管理程序包