svc.periodicd - 服务管理工具定期重启程序
/lib/svc/bin/svc.periodicd
svc:/system/svc/periodic-restarter:default
svc.periodicd 是服务管理工具 (Service Management Facility, SMF) 的重启程序,用于处理那些不是作为长时间运行的守护进程实现,而是作为需要定期运行但运行时间较短的进程实现的服务。此类服务称为定期服务。
svc.periodicd 会在启动期间作为 system/svc/periodic-restarter 服务的一部分自动调用,并在发生任何故障时自动重新启动。请勿直接调用 svc.periodicd。
有关所有重启程序通用的配置和行为的信息,请参见 smf_restarter(7)。
svcs 命令可以报告由 svc.periodicd 管理的服务的附加状态。有关更多信息,请参见 svcs(1) 手册页。
定期服务仅支持 svc.startd(8) 中所述的方法之一。定期服务仅支持 start 方法。定期重启程序不支持 stop 和 refresh 方法,如果定义了这两种方法,则会将其忽略。
svc.periodicd 会将服务的重要重启程序操作以及方法标准输出和标准错误文件描述符记录到 /var/svc/log/service:instance.log 中。
定性地说,定期服务(由 svc.periodicd 管理)与其他服务的不同之处在于:表示此类服务的进程并不持久存在于服务的整个联机过程中。相反,定期服务所包含的进程相对比较短暂,而且是定期执行的。例如,某一定期服务可能用于每 30 秒检查一次远程资源的状态,或每周下载一次软件更新。svc.periodicd 会通过对委托实例定期运行 start 方法来实现这种行为。
开发或配置定期服务时,可以使用一组通用属性来影响 svc.periodicd 对该服务的处理方式。除了 svc.startd(8) 已知的通用属性外,svc.periodicd 还可识别以下一组属性,其中的每个属性均可存在于名为 'periodic' 的属性组中:
一个时间值,用于指定在服务 start 方法的两次调用之间需要等待多长时间。此属性必需。
一个时间值,用于指定在达到期限后,start 方法实际运行之前的随机延迟。延迟范围为 0 秒至此属性的值。此为可选属性,如果未定义,则采用 0。
一个时间值,用于指定服务在达到“联机”状态后,调用该服务的 start 方法之前需要等待的持续时间。此为可选属性,如果未定义,则采用 0。总延迟时间为 periodic/delay 与 periodic/jitter 之和。
一个布尔值,用于指示在系统停机期间定期重启程序是否应保持对实例的调度。如果值为 false,实例将通过引导来调度,就像其首次达到联机状态一样。如果值为 true,定期重启程序将根据实例的当前 periodic_restarter/next_run 属性值对该实例执行 start 方法。如果该值是过去的时间,则将下一次执行预定在发生停机之前、所建立期限的下一个倍数之时。
一个布尔值,用于指示定期重启程序是否应在引导过程中调用服务的 start 方法,以补偿由于系统停机而错过的执行。为实现这种效果,还需要将 periodic/persistent 属性设置为 true。后续执行将按调度计划进行。
预定服务的行为与定期服务非常相似。主要区别在于:预定服务在特定时间运行,而不是定期运行。例如,可以使用预定服务在每个星期日的 18:00 点备份特定目录。
开发或配置预定服务时,可以使用一组通用属性来影响 svc.periodicd 对该服务的处理方式。除了 svc.startd(8) 已知的通用属性外,svc.periodicd 还可识别以下一组属性,其中的每个属性均可存在于名为 'schedule' 的属性组中:
该值和频率值共同定义服务的 start 方法应采用的运行频率。可能值包括 'year'、'month'、'week'、'day'、'hour' 和 'minute'。确保服务的 start 方法针对每个调度的期间仅运行一次。也就是说,按 'day' 预定服务将每天仅执行一次其 start 方法。
此值定义必须经过多少个间隔才能运行服务的 start 方法。也就是说,如果间隔按周计且频率为 3,则 start 方法每 3 周执行一次。合法值为任意正整数。此为可选属性,如果未定义,则采用 1。
此值指定应使用哪个时区来派生服务 start 方法的执行时间。此为可选值,如果省略,则被视为系统时区。否则,有效值为时区名称。
一个数值,用于指定调度应基于哪个公历年。仅在创建频率不为 1 的预定服务时,此属性才有用;它将创建一个参考点,从该点开始计算调度的其余部分。
一个数值,用于指定基于年份(采用 ISO 周日期标准)预定在哪周(采用 ISO 8901 标准)运行服务。合法值为 1 到 53。可以使用负数从年末开始倒数。
一个数值,用于指定预定在哪个月运行服务。合法值为 1 到 12,或者月份的全名或三字母缩写。所有名称都必须使用 C 语言环境指定。可以使用负数从年末开始倒数。
一个数值,用于指定预定在给定工作日第几次出现时运行服务。合法值为 1 到 5。可以使用负数从月末开始倒数。
一个数值,用于指定预定在一周(采用 ISO 6801 标准)中的哪一天运行服务。合法值为 1 到 7,或者星期几的全名或三字母缩写。所有名称都必须使用 C 语言环境指定。可以使用负数从周末开始倒数。
一个数值,用于指定预定在月份中的哪一天运行服务。合法值为 1 到 31。如果某个月的天数少于此属性的值,则该服务的 start 方法将在该月的最后一天运行。可以使用负数从月末开始倒数。此属性不能与 day 属性一起使用。
一个数值,用于指定预定在一天中的哪一小时运行服务。合法值为 0 到 23。可以使用负数从一天的结尾开始倒数(-1 至 -24)。如果给定小时在某特定日期出现多次,则服务的 start 方法将仅在第一次出现该时间之际运行。如果该小时在某特定日期并未出现,则服务的 start 方法将在下一小时运行。
一个数值,用于指定预定在该小时中的哪一分钟运行服务。合法值为 0 到 59。可以使用负数从该小时的结尾开始倒数(-1 至 -60)。
一个布尔值,用于指示定期重启程序是否应在引导过程中调用服务的 start 方法,以补偿由于系统停机而错过的执行。
在此属性组中,只有 'interval' 是必填属性。除了 recovery 以外,所有其他属性都用于对调度施加额外的约束。只有时间长度短于间隔值的属性才能参与约束。如果 'interval' 的值为 'week',则允许通过将 'scheduled/day' 的值向下定义为 'minute' 来约束该调度。约束必须从 'interval' 值的向下一个层次开始,并且必须连续,但无需定义所有可能的约束。实际上,建议服务开发人员尽可能少地定义约束。这样,服务便可预定为在给定日期的某特定小时运行,但具体在该小时的哪一分钟运行服务的 start 方法留给 svc.periodicd 来决定。
对于 start 方法的初始调用,未定义约束会获取随机值。对于后续调用,svc.periodicd 会提供一定程度的一致性,以确保将服务 start 方法的各个执行充分隔离开来。具体来讲,系统将仅为服务的第一次执行随机生成第一个不受约束的时间单位,然后便会一直沿用此单位直至服务被禁用。以 'year' 为间隔且没有其他约束的服务将始终在一年的同一月份中运行,但不一定在该月份的同一天运行。同样,按 'week' 调度且具有 'day' 约束的服务将始终在该日期的同一小时运行,但不一定在该小时的同一分钟运行。
如果 'frequency' 的值大于 1,则还必须将所有约束指定为等于或高于 'interval' 值。此上下文中定义的约束将用于确定从其开始计算调度其余部分的参考点。对于间隔等于 'year' 且频率为 '2' 的服务,可以指定 'year = 2002' 或 'year = 1936' 的约束,以确保服务的 start 方法在偶数年执行。请注意,这些约束只是一些参考点,并不代表开始或结束日期。可以使用任何年份内任何日期中的任何时间,只要所选值能够准确反映应在何时运行服务的 start 方法即可。
svc.periodicd 管理的服务可能会显示为 smf(7) 中描述的任一状态。此重启程序未修改状态定义。
svc.periodicd 遵循 svc.startd(8) 的“服务失败”部分中列出的故障情况,但有两处修改。SMF_EXIT_TEMP_TRANSIENT 退出代码将与 SMF_EXIT_ERR_OTHER 的处理方式相同。此外,如果方法运行时执行时间超过配置的期限,但短于配置的方法超时,svc.periodicd(8) 将不会再次尝试调用该方法,而是等待该方法退出并将在此期限的后续倍数之时调用方法。
某实例第一次失败时,该实例将被置于“降级”状态。连续失败三次后,实例将立即进入维护状态。如果在第三次失败之前调用成功,实例将移回到联机状态。
以下是一个简单定期服务的清单。调用 'svcadm enable example/periodic_service:default' 后,svc.periodicd 将等待 15 至 20 秒,然后再运行 start 方法。第一次调用 start 方法后,该方法将每 30 到 35 秒运行一次。
<?xml version='1.0'?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> . <service_bundle type='manifest' name='SUNWsvc:test'> . <service name='example/periodic_service' type='service' version='1'> . . <instance name='default' enabled='false'> . <periodic_method period='30' delay='15' jitter='5' exec='/usr/bin/periodic_service_method' timeout_seconds='0'> <method_context> <method_credential user='root' group='root' /> </method_context> </periodic_method> . </instance> . </service> . </service_bundle>示例 2 创建调度的服务
以下是一个简单预定服务的清单。svc.periodicd 将在每月第一天的凌晨 2:00 到凌晨 3:00 之间执行此服务的 start 方法。
<?xml version='1.0'?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> <service_bundle type='manifest' name='SUNWsvc:test'> <service name='example/scheduled_service' type='service' version='1'> <instance name='default' enabled='true'> <scheduled_method interval='month' day='1' hour='2' exec='/usr/bin/scheduled_service_method' timeout_seconds='0'> <method_context> <method_credential user='root' group='root' /> </method_context> </scheduled_method> </instance> </service> </service_bundle>示例 3 创建具有频率的预定服务
以下是一个频率大于一的预定服务的清单。每当年份可被五整除时,svc.periodicd 便会在美国感恩节那天执行此服务的 start 方法。
<?xml version='1.0'?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> <service_bundle type='manifest' name='SUNWsvc:test'> <service name='example/scheduled_service' type='service' version='1'> <instance name='default' enabled='true'> <scheduled_method interval='year' frequency='5' year='1900' month='nov' weekday_of_month='4' day='Thu' exec='/usr/bin/scheduled_service_method' timeout_seconds='0'> <method_context> <method_credential user='root' group='root' /> </method_context> </scheduled_method> </instance> </service> </service_bundle>示例 4 创建多周服务
以下是预定服务的清单。svc.periodicd 将以 2027 年的第 15 周为参考点,每三周于星期二晚上 10:30 执行一次该服务的 start 方法。
<?xml version='1.0'?> <!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'> <service_bundle type='manifest' name='SUNWsvc:test'> <service name='example/scheduled_service' type='service' version='1'> <instance name='default' enabled='true'> <scheduled_method interval='week' frequency='3' year='2027' week_of_year='15' day='2' hour='22' minute='30' exec='/usr/bin/scheduled_service_method' timeout_seconds='0'> <method_context> <method_credential user='root' group='root' /> </method_context> </scheduled_method> </instance> </service> </service_bundle>
有关下列属性的说明,请参见 attributes(7):
|
svcs(1)、service_bundle(5)、smf(7)、smf_method(7)、svc.startd(8)