Mac服务管理-Launchd(转)
背景:
在Mac下没有像Linux那样有很多的关于init方面的工具,从init的发展历史https://en.wikipedia.org/wiki/Init上可以知道,Mac使用的是Launchd作为init管理工具,对应的命令工具为launchctl。
如果在Linux下创建一个自启动服务可以使用Upstart、Systemd、Sysvinit,其中最简单和最古老的方式应该是Sysvinit,毕竟其支持Shell脚本,非常方便。而在Mac下,与Linux的做法不太一样,采用Launchd进行管理,其设置服务采用了plist文件进行对服务来描述,并通过配置好后放在/System/Library/LaunchDaemons或者/Library/LaunchDaemons,最后通过launchctl命令行使其生效,期间也可以直接通过launchctl来对服务进行操作,比如启动、停止等。
详细的plist编写规范及介绍,参考:https://en.wikipedia.org/wiki/Launchd
以下是关于Launchd的详细解释:
Launchd是什么?
Mac OS X从10.4开始,采用Launchd来管理整个作业系统的Services及Processes 。传统的UNIX会使用/etc/rc.*或其他的机制来管理开机时要启动的Startup Services,而现在的Mac OS X使用launchd来管理,它的Startup Service叫做Launch Daemon和Launch Agents 。而视为Service的程序,就该是Background Process,不应该提供GUI,也不应该跳到(Console的)Foreground 。当然有些例外,例如听快速键之后跳出视窗的程序。
Launchd管理的Background Process有四种:
- Launch Daemon:在开机时加载(Load)。
- Launch Agent:在使用者登录时加载。
- XPC Service:好像是10.7才有的。
- Login Items:在User登录时执行。有两种方法可以用程序新增项目到Login Item:(Shared File List:会出现在Account偏好设定的Login Item清单。Service Management Framework:这个就不会出现在Login Item清单。)
(以下把重点放在Launch Daemon/Agent 。至于XPC和Login Item先不做解释。)
Launch Daemon & Launch Agent
Launch Daemon和Launch Agent是同一种东西在不同Scopes的异名。Launch Daemon是System-Wide(系统级别)的Service,称为Daemon,Launch Agent是Per-User(用户级别)的Service ,称为Agent,前者在开机时会加载(Load),后者在使用者登录时(才)会加载。
如果你打开Activity Monitor,并切换到Hierarchy View,你会发现有个Launchd会在最上层,跟它同层的只有kernel_task,它下面有很多Child Processes的User都是root,其中还有一个Launchd,启动的User是你自己,它底下的Child Processes的User也几乎都是你自己。当这些Processes是由Launchd加载Launchd Property List File来执行的时候,前者由root执行的称为Launch Daemons,后者由使用者执行的称为Launch Agents 。
Launchd Property List File就是你会在LaunchDaemon或LaunchAgents目录中看到的*.plist档案(以下统称plist档)。它是XML格式。
launchd Service Process Lifecycle
由Launchd所管理的Services(Launch Daemon、Launch Agent)是要先由Launchd加载(load)以后才会执行(run),但加载之后并不一定马上执行。在苹果的官方文件说明了kernel加载完成后会发生的事,用来说明Launch Daemons、Launch Agents及其Processes的生命周期。
开机时,会先加载OS Kernel,加载完成后就执行Launchd,用来加载System-Wide Services(Daemons)。这个System-Wide Launchd在开机时会做这些事:
- 加载(load)存放在这些目录下的plist:(/System/Library/LaunchDaemons,/Library/LaunchDaemons)
- 注册那些plist里面设定的sockets(port)和file descriptors
- 执行(run)KeepAlive = true的Daemons,当然RunAtLoad = true的也会启动。
Run好后,Loginwindow就出现了,提示使用者登录。有设定自动登录的话,就会跳过这关。
在使用者登录以后,会执行属于该使用者的Launchd,负责处理Launch Agent,做的事跟上面加载Launch Daemon很像,差别在于它从以下的目录加载plist:
- /System/Library/LaunchAgents
- /Library/LaunchAgents
- ~/Library/LaunchAgents
由使用者执行的任何程序也都是Launchd来执行的,所以Launchd也是该使用者的所有Processes之母。
在使用者登出、关机或重新开机时,会触发Termination Event。接受登出、关机、重新开机使用者指令的Process是Loginwindow。它会先向使用者确认,一但确认,就会对每个由该使用者的Launchd所启动的Processes送出Termination Signal,如果是Cocoa则送出Cocoa API的Event,其他的就送出SIGTERM要他们自我了断,45秒之后,除了Cocoa的应用程式可以丢出某个Error来取消这整个Termination Process,其他还没结束的都会被kill掉。
这就是为什么Loginwindow这个Process会一直存在,它要负责把该使用者执行起来的Processes统统清掉。而Per-User Services都关掉以后,就回到Loginwindow,或是执行关机、重新开机的流程,后两者就是照着差不多的流程去关掉所有System-Wide Services。
Launchd-Compatible Daemon Programming Guide
以下是该文件中提及关于配合Launchd开发Daemon时应注意的事,提到关于plist的key就请参考man 5 launchd.plist。以下的Daemon指的是Launch Daemon所要运行的Process,所以Launch Agent也一并适用。
Listen to SIGTERM
如上文所提及的,由于Loginwindow这个Process在要关掉你的Daemon时会先送SIGTERM,要你自我了断,等太久没关掉才会SIGKILL。如果你的程式需要在结束之前做什么事,一定要听SIGTERM这个Signal。
On-Demand Daemon
Launch Daemon/Agent默认不会让某个Process一直执行,当它的设定没有KeepAlive = true时,它会根据被执行的Process的CPU Usage和Requests(如TCP/IP Service)来决定要不要送出SIGTERM叫他自尽。
当该Service需要被使用时,而相对应的Program没有跑成Process时,会自动把该Service给跑起来。例如某个TCP/IP Service听某个Port,当这个Port有封包进来时,Launchd会把相对应的Service给启动,这种行为叫做on-demand 。
当然,也有non-on-demand daemon,其实也就是keep-alive daemon,这也是传统意义上的Daemon ,比如一直躲在墙角默默执行,直到有人找他,他才跳出来回一下话,回完了以后又继续躲在墙角。只要把KeepAlive这个key设成true,它就会在plist被Launchd加载(load)时执行(run)起来。要是那个Process死掉,Launchd会知道,马上再把它开起来。所以如果你试着去Activity Monitor砍掉这种Daemon,它就马上会复活。
No fork or exec
传统的System Programming会教你用exec、fork等等的POSIX API来做Daemon,但配合Launchd时,由于Daemon的生命周期是由Launchd来控制的,除非强制要求Kepp-Alive,否则要生要死是Launchd决定,更何况Keep-Alive还要考虑Daemon Process在结束以后自动重新执行,所以在配合Launchd写Daemon时,苹果建议你不要用传统的fork和exec*。当然,plist文件中的ProgramArguments就是exec*系列subroutine的参数。
当一个Process跑起来10秒内就死掉,Launchd会判定为Crash,然后试着重新执行。要是你用传统的fork-exec style,就可能会造成无限循环。
No setuid / setgid / chroot / chdir etc
为了安全性的考虑,苹果强烈建议你不要自己调用setupd、setgid、chroot、chdir等等System Subroutines,而是透过plist文件的设定值来让Launchd帮你完成,参考UserName、GroupName、RootDirectory、WorkingDirectory的keys 。
No pipe redirection hell for fd 0, 1 or 2
在写Log或输出信息时可以设定StandardOutPath、StandardErrorPath,只管输出到stdout或stderr就好了。而StandardInPath也可以让你的Process一执行就从stdin指定path的内容。也就是说,Launchd帮你把fd = 0, 1, 2的东西都传了一遍。
其他应用
定时任务
Launch Daemon/Agent的设置项可以指定该Service的执行周期及执行时间,也就是说,它可以替代传统的at、periodic和cron。这些设定值的key请参考StartInterval和StartCalendarInterval。
搭配LaunchOnlyOnce的话可以模拟at,但如果要用Launchd只临时做一件事,还不如直接at方便。
监视文件或目录异动
Launch Daemon/Agent可以监视某个path的异动,设定在WatchPaths这个key。这里所说的path可以是Directory或是某个特定的文件,只要该path有异动,就会执行你的Job。
也可以用来清Queue,只要Directory里面有东西,就会执行Job直到空为止,可以用来做Mail Server或Notification。设定在QueueDirectories这个key。
参考:
https://en.wikipedia.org/wiki/Init
https://en.wikipedia.org/wiki/Launchd
https://stackoverflow.com/questions/15735320/osx-s-etc-init-d-equivalent
https://nathangrigg.com/2012/07/schedule-jobs-using-launchd#launchctl
https://blog.yorkxin.org/2011/08/04/osx-launch-daemon-agent(以上内容转自此篇博客,由于繁体翻译成简体,有些地方可能语义存在问题)
https://developer.apple.com/library/content/technotes/tn2083/_index.html
Mac服务管理-Launchd(转)的更多相关文章
- linux的服务管理(centos6和Centos7)和网络管理(网卡配置),计划服务cron
服务和网络 管理 init ifcfg ens33 1.服务: Linux系统中提供的功能,统称为服务,如:at服务.cron服务.web服务.FTP服务.sshd服务等. 服务是由已经在运行的进程 ...
- 第11章 Linux服务管理
1. 服务分类 (1)Linux的服务 ①Linux中绝大多数的服务都是独立的,直接运行于内存中.当用户访问时,该服务直接响应用户,其好处是服务访问响应速度快.但不利之处是系统中服务越多,消耗的资源越 ...
- CentOS 7 (RHEL 7)服务管理命令的变化
CentOS 7 (RHEL 7)带来了新的服务管理命令,为了保持兼容原有的命令仍可以使用,以下是新旧命令的对照. 启动.停止.重启.重载.检查服务:6: service httpd start|st ...
- PC管理端与评委云打分配合步骤及疑难问题汇编,即如何使用PC管理端的云服务管理功能
一.前期环境及数据准备 A.PC管理端主要流程 1.进入菜单 编辑/选项/服务器 界面,如下图所示,采用我官方所提供的云服务,不采用自己假设的AppWeb服务. 切记:AppWeb服务和云服务只能二选 ...
- Ubuntu 和 Redhat / Fedora 服务管理命令对比表(附Fedora16新的服务管理工具systemctl )
以 apache/httpd 服务作为例子 任务 Red Hat / Fedora Ubuntu Ubuntu (with sysv-rc-conf or sysvconfig) 立即启动/停止某服务 ...
- Centos6.5 设置Tomcat8 service服务实现自启动和服务管理
Centos6.5 设置Tomcat8 service服务实现自启动和服务管理 将tomcat设置成像apache,nginx一样. 用serviec xxxx start/stop/restart ...
- linux 学习 12 服务管理
第十二讲 Linux服务管理 12.1 Linux服务管理-服务分类 ——Linux服务 ----RPM包默认安装的服务 ————独立的服务 ————基于xinetd服务 ----源码包安装的服务 ...
- [MySQL Reference Manual] 5 MySQL 服务管理
5. MySQL 服务管理 5. MySQL 服务管理 5.1 The Mysql Server 5.2 Mysql 服务日志 5.2.1 选择General query log和slow query ...
- Powershell实例小结(服务管理)
有关服务管理的具体实例脚本如下: #$lists="1.1.1.1","2.2.2.2" #远程ip列表 foreach ($list in $lists){ ...
随机推荐
- centos环境下登录mysql报 ERROR 1045 (28000)怎么解决
centos环境下登录mysql报 ERROR 1045 (28000)怎么解决 新入手一台虚拟机,Centos7系列的操作系统,安装mysql后,执行连接出现了Mysql ERROR 1045 (2 ...
- Javascript 知识遗漏点梳理。
先说一下我之前学习Javascript的学习经历,然后就是最近几天学到以前没有注意的知识遗漏点. 1.之前的学习经历和方法: 最开始是看了Javascript DOM编程与艺术这本书,把慕课网上的&l ...
- UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)
题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...
- swoole实现websocket推送
环境配置: swoole 1.9.3.centos6.5(虚拟机).PHP7.01 思路: ①通过server中的collections取出fd ②写一个admin. ...
- EventBus事件总线框架(发布者/订阅者模式,观察者模式)
一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...
- Spring全局异常处理
最近学习Spring时,认识到Spring异常处理的强大.之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑: 1 try{ 2 ...
- textarea 高度自动
<textarea id="suggest" type="text" name="suggest" class="form- ...
- MvvmLight框架使用入门(二)
上一篇我们简单对MvvmLight做了介绍.罗列了三个DLL中,各个命名空间下主要类的定义及大致作用.因为只是范范的概论,对于从未接触过MvvmLight的萌新来说,根本就是在晃点他们.不过万事开头难 ...
- iOS错误 - too many open files (error = 24)
碰到这个错误是在用 UIImageView 显示图片的时候.UIImage 用的是 imageNamed 方法.错误原因是打开了太多的文件.应该是太多文件的打开导致了 UIImage 的 cache ...
- Exp5 MSF基础应用 20164323段钊阳
网络对抗技术 20164323 Exp5 MSF基础应用 靶机 ip:192.168.1.229 kali ip:192.168.1.216 exploit选取 主动攻击:ms17_010_psexe ...