背景:

在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有四种:

  1. Launch Daemon:在开机时加载(Load)。
  2. Launch Agent:在使用者登录时加载。
  3. XPC Service:好像是10.7才有的。
  4. 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在开机时会做这些事:

  1. 加载(load)存放在这些目录下的plist:(/System/Library/LaunchDaemons,/Library/LaunchDaemons)
  2. 注册那些plist里面设定的sockets(port)和file descriptors
  3. 执行(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/legacy/library/documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html

https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/launchctl.1.html

https://developer.apple.com/library/content/technotes/tn2083/_index.html

Mac服务管理-Launchd(转)的更多相关文章

  1. linux的服务管理(centos6和Centos7)和网络管理(网卡配置),计划服务cron

    服务和网络 管理 init  ifcfg ens33 1.服务: Linux系统中提供的功能,统称为服务,如:at服务.cron服务.web服务.FTP服务.sshd服务等. 服务是由已经在运行的进程 ...

  2. 第11章 Linux服务管理

    1. 服务分类 (1)Linux的服务 ①Linux中绝大多数的服务都是独立的,直接运行于内存中.当用户访问时,该服务直接响应用户,其好处是服务访问响应速度快.但不利之处是系统中服务越多,消耗的资源越 ...

  3. CentOS 7 (RHEL 7)服务管理命令的变化

    CentOS 7 (RHEL 7)带来了新的服务管理命令,为了保持兼容原有的命令仍可以使用,以下是新旧命令的对照. 启动.停止.重启.重载.检查服务:6: service httpd start|st ...

  4. PC管理端与评委云打分配合步骤及疑难问题汇编,即如何使用PC管理端的云服务管理功能

    一.前期环境及数据准备 A.PC管理端主要流程 1.进入菜单 编辑/选项/服务器 界面,如下图所示,采用我官方所提供的云服务,不采用自己假设的AppWeb服务. 切记:AppWeb服务和云服务只能二选 ...

  5. Ubuntu 和 Redhat / Fedora 服务管理命令对比表(附Fedora16新的服务管理工具systemctl )

    以 apache/httpd 服务作为例子 任务 Red Hat / Fedora Ubuntu Ubuntu (with sysv-rc-conf or sysvconfig) 立即启动/停止某服务 ...

  6. Centos6.5 设置Tomcat8 service服务实现自启动和服务管理

    Centos6.5 设置Tomcat8 service服务实现自启动和服务管理 将tomcat设置成像apache,nginx一样. 用serviec xxxx start/stop/restart ...

  7. linux 学习 12 服务管理

      第十二讲 Linux服务管理 12.1 Linux服务管理-服务分类 ——Linux服务 ----RPM包默认安装的服务 ————独立的服务 ————基于xinetd服务 ----源码包安装的服务 ...

  8. [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 ...

  9. Powershell实例小结(服务管理)

    有关服务管理的具体实例脚本如下: #$lists="1.1.1.1","2.2.2.2" #远程ip列表 foreach ($list in $lists){ ...

随机推荐

  1. centos环境下登录mysql报 ERROR 1045 (28000)怎么解决

    centos环境下登录mysql报 ERROR 1045 (28000)怎么解决 新入手一台虚拟机,Centos7系列的操作系统,安装mysql后,执行连接出现了Mysql ERROR 1045 (2 ...

  2. Javascript 知识遗漏点梳理。

    先说一下我之前学习Javascript的学习经历,然后就是最近几天学到以前没有注意的知识遗漏点. 1.之前的学习经历和方法: 最开始是看了Javascript DOM编程与艺术这本书,把慕课网上的&l ...

  3. UVa 1151 Buy or Build (最小生成树+二进制法暴力求解)

    题意:给定n个点,你的任务是让它们都连通.你可以新建一些边,费用等于两点距离的平方(当然越小越好),另外还有几种“套餐”,可以购买,你购买的话,那么有些边就可以连接起来, 每个“套餐”,也是要花费的, ...

  4. swoole实现websocket推送

    环境配置:      swoole 1.9.3.centos6.5(虚拟机).PHP7.01   思路:      ①通过server中的collections取出fd      ②写一个admin. ...

  5. EventBus事件总线框架(发布者/订阅者模式,观察者模式)

    一. android应用内消息传递的方式: 1. handler方式-----------------不同线程间传递消息. 2. Interface接口回调方式-------任意两个对象. 3. In ...

  6. Spring全局异常处理

    最近学习Spring时,认识到Spring异常处理的强大.之前处理工程异常,代码中最常见的就是try-catch-finally,有时一个try,多个catch,覆盖了核心业务逻辑: 1 try{ 2 ...

  7. textarea 高度自动

    <textarea id="suggest" type="text" name="suggest" class="form- ...

  8. MvvmLight框架使用入门(二)

    上一篇我们简单对MvvmLight做了介绍.罗列了三个DLL中,各个命名空间下主要类的定义及大致作用.因为只是范范的概论,对于从未接触过MvvmLight的萌新来说,根本就是在晃点他们.不过万事开头难 ...

  9. iOS错误 - too many open files (error = 24)

    碰到这个错误是在用 UIImageView 显示图片的时候.UIImage 用的是 imageNamed 方法.错误原因是打开了太多的文件.应该是太多文件的打开导致了 UIImage 的 cache ...

  10. Exp5 MSF基础应用 20164323段钊阳

    网络对抗技术 20164323 Exp5 MSF基础应用 靶机 ip:192.168.1.229 kali ip:192.168.1.216 exploit选取 主动攻击:ms17_010_psexe ...