原文见:
该系列以前的文章:
OpenSolaris新特性解析之一: open
solaris之前身今世
OpenSolaris新特性解析之二:ZFS
前段
时间比较忙,很久没有上chinaunix, 今天准备一次性把SMF这部分写完,要不然我感觉这个系列可能会中途而废了。
SMF的全称是service management facilit,
可以翻译成为是服务管理框架,是solaris新一代的进行服务管理的东东,目前在opensolaris里面SMF和传统的INIT机制还是并存的。虽
然大部分的服务已经转化成为了SMF的模式,但是INIT的机制依然得到了保留,并且还有很少部分的服务是采用INIT的形式的,SUN采用这样的策略是
考虑到了部分的
软件厂商,因为这些软件厂商
开发的
应用程序如
果是有部分注册成了服务的话,那么以前肯定是注册成了INIT的那种形式,为了让这部分程序在opensolaris和solaris10上面还可以运
行,所以INIT的方式依然得到了保留,不过在将来,opensolaris上的服务都会转到SMF上去,INIT会彻底停止使用。
先简单说下用法,
#su 转化成超级
用户
#svcs 可以看到
系统里面正在运行的服务,最后一列表明了服务的名字,例如svc:/system/fmd:default
#svcs -a 列出系统里面所有的服务,包括没有启动的
#svcs -x 查看服务的错误日志
#svcadm disable service-name 停止service-name这个服务,并在下次开机时也不运行它
#svcadm enable service-name 启动service-name这个服务,并在下次开机时也运行它
#svcadm restart service-name 重启service-name这个服务
大家如果熟悉REDHAT的话,很快就已经发现了SMF的用法和REDHAT下面的服务管理的用法几乎完全一样,不过他们只是形似,内部机制却相差很远,REDHAT目前所使用的还是传统的INIT的机制,下面是我个人认为的它们之间的区别。
区别1:我们知道在REDHAT/etc下面有rc1.d, rc2.d ....等等这样类似的目录,其他使用INIT机制的系统也会有这样的目录,比如几乎所有的LINUX,
AIX等,
这些目录下面放置了相关运行级别的服务列表,比如当系统进入运行级别3的时候,/etc/rc3.d下面的那些脚本都会被执行。这些服务都是编号的,名字
一般为S1service1,
S2service2等,1和2这样的数字决定了服务启动的顺序,数字小的先执行,大的后执行。好,问题来了,我们知道现在硬件都是多CPU,多核的,没
有依赖关系的服务应该充分利用这些硬件资源并行启动。但是在INIT的这种模型下,服务的启动只能是按照数字编号顺序启动,就算某两个服务之间并没有依赖
的关系。在SMF的模型下面改进了这一点,只要两个服务之间是没有依赖关系的,SMF将尽量安排它们平行启动。
区别2: 在INIT下,服务如果出错是不能自动重启的,也就是说INIT下面的服务如果要自动启动只有在开机的时候可以。这样也会带来问题的,比如我们的程序在下面注册了个服务,是专门接受
数据的,这个时候半夜三更的这个服务出错了,停止服务了,而用户的数据是不能丢失的,必须要持续接收,同志们只有半夜起来去趟机房或者是进行远程连接重起这个服务了。而SMF系统会自动的重起失败的服务。
区别3:对于那些出错而不能恢复的服务,处理方式不同。对于不能恢复的服务错误,在LINUX下面一般来说是需要重起整个
操作系统的,
如果单独杀掉这个出错的服务,系统不知道会有什么样的后果,因为服务之间是有依赖关系的。比较安全的方式是重起整个系统。在SMF下面,SMF存储了所有
服务之间的依赖关系,它知道杀掉这个出错的服务会不会有其他的关键服务受到影响,如果没有,系统就会杀掉这个出错而不能恢复的服务。对于一些运行关键任
务,不能停机的主机,这个特性是比较关键的。
图1是SMF的框架,repository.db存放了所有服务的属性的值,比如
电源管理服务的timeout时间之类的,当服务启动的时候需要加载这些值。svc.configd这个后台进程用于维护这个属性
数据库,
所有的对这个数据库的读或者写的操作都要经过这个进程,这样的设计保证了这个数据库的完整性。svc.startd这个后台进程在开机的时候使用,它将读
出需要启动的每一个服务的属性的值,然后用这些值去启动这些服务。SMF tools是SMF的一些维护工具如svcadm。
下面我将说明如果加入一个SMF服务,把以前的INIT的服务转换成SMF服务的方式也是一样的。
比如我们以前的服务是个
应用程序,分为A和B两个部分,其中B依赖于A。我们需要先创建这两个服务的属性配置
文件。
在SMF下面所有的属性配置文件都是放在/var/svc/manifest下面的,大家可以看到下面有几个分类目
录:application device milestone network platform site system。我们的服务是
应用程序,所以我们先到application目录下面创建个目录ourapplication,在这个目录下我们再创建服务A的属性配置文件,内容如
下,格式是xml类型的
SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> #必须要包含的文件,就好像C语言里面的头文件,里面有预定义
name='application/ourapplication/A' #定义服务的名字
type='service'
version='1'>
name='multi-user-server'
grouping='optional_all'
type='service'
restart_on='none'>
#这个服务属于哪个milestone
type='method'
name='start'
exec='/lib/svc/method/ourapplication/A %m' #启动这个服务需要启动的应用程序或脚本的路径
timeout_seconds='60'>
type='method'
name='restart'
exec='/lib/svc/method/ourapplication/A %m' #restart这个服务需要restart的应用程序或脚本的路径
timeout_seconds='60'>
type='method'
name='stop'
exec='/lib/svc/method/ourapplication/A %m' #stop这个服务需要stop的应用程序脚本的路径
timeout_seconds='60' >
#定义这个服务的类型
上面以#打头的部分是我的注释,大家自己写的时候需要把这些东东去掉。
其中需要注意的是 /lib/svc/method/ourapplication/A 这个路径,我们看到start,stop,
restart都是使用的这个脚本,熟悉INIT的朋友应该明白了,这个脚本就是在INIT里面的那个对应的脚本,我们这里只是把相应的参数如
start,restart,stop等传给它。
第二步,我们需要创建/lib/svc/method/ourapplication/A 这个脚本,它的写法和init中rcx.d下面脚本的写法一样,如果是把INIT下面的服务移植到SMF下面,我们的工作就是直接的拷贝。
第三步,我们需要把这个服务的属性文件导入到属性数据库中
# svccfg
svc:> validate /var/svc/manifest/application/ourapplication/a.xml
svc:> import /var/svc/manifest/application/ourapplication/a.xml
svc:> quit
第四步,激活
# svcadm enable svc:/application/ourapplication/a
这样就OK了,将B加入到SMF中的办法是一样的,唯一的区别是因为B依赖于A,所以在B的属性配置文件里面需要改动下面的东东
name='ourapplication-server'
grouping='optional_all'
type='service'
restart_on='none'>
在A里面是
name='multi-user-server'
grouping='optional_all'
type='service'
restart_on='none'>
大家对比一下就明白了。其他的步骤是完全一样的。
写道这里SMF这部分就基本上介绍完了。其他的更加具体的用法可以见附件servicemgmthowto。最后写一个列子是如果动态改变SMF服务中的属性的
#svccfg
svc:> select system/power #选择电源管理这个服务
svc:>listprop #让系统打印这个服务的属性的值
svc:>setprop stop/timeout_seconds=70 #修改timout这个属性的值为70
svc:>quit #直接推出
大家可以再用这个工具看看那个属性,可以看到已经改变了,并且这个服务会用这个新的值运行
[
本帖最后由 niupigege 于 2008-9-22 17:12 编辑 ]
(25.49 KB)
|
阅读(692) | 评论(0) | 转发(0) |