在Linux上如何创建Java创建一个守护进程程服务

linux下利用daemon(jsvc)构建java守护进程:部署
1.安装jsvc
2.编写服务启动类
-------------------------------------
public class TestJsvc {
public static void main(String args[]) {
& System.out.println("execute main
method!");
& & public void init()
throws Exception {
& System.out.println("execute init
method!");
& & public void
init(String[] args) throws Exception {
& System.out.println("execute init(args)
method!");
& & public void start()
throws Exception {
& System.out.println("execute start
method!");
& & public void stop()
throws Exception {
& System.out.println("execute stop
method!");
& & public void destroy()
throws Exception {
& System.out.println("execute destroy
method!");
------------------------------------
main方法可以去掉,调用中不会使用,但是init(String[]
args),start(),stop(),destroy()方法不能少
1&程序中,最好把初始化的所有操作,例如读配置文件等等,都放在init中,放在start中貌似有时候会出错,具体原因不详
2&服务在启动时会先调用init(String[]
args)方法,然后调用start()方法,在服务停止是会首先调用stop()方法,然后调用destroy() 方法.
3.把这个类打包成TestJsvc.jar
放到/home/dijunzheng/test目录下(改成你自己的)
4.编写启动服务的脚本 myjsvc
-------------------------------
export RUN_HOME=/data/storageServer
export JAVA_HOME=/data/jdk1.6.0_26 &
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
#jsvc所在的目录 (找到你自己的jsvc目录)
DAEMON_HOME=/data/commons-daemon-1.0.7-native-src/unix
MYJSVC_USER=root
# for multi instances adapt those lines.
TMP_DIR=$RUN_HOME/tmp
PID_FILE=$RUN_HOME/sstest.aa
export DAEMON_HOME
export MYJSVC_USER
export TMP_DIR
export PID_FILE
CLASSPATH=$CLASSPATH:$RUN_HOME/test.jar
CLASSPATH=$CLASSPATH:$RUN_HOME/lib/commons-daemon-1.0.6.jar
export CLASSPATH
case "$1" in
& & start &
$DAEMON_HOME/jsvc \
& & & -user
$MYJSVC_USER \
& & & -home
$JAVA_HOME \
-Djava.io.tmpdir=$TMP_DIR \
& & & -wait
-pidfile $PID_FILE \
-outfile $RUN_HOME/log/myjsvc.out \
$CLASSPATH \
& & & exit
& & stop &
$DAEMON_HOME/jsvc \
& & & -stop
-pidfile $PID_FILE \
& & & exit
---------------------------------
5 启动停止
至此,守护进程已经可以启动,&
运行./test.sh &start 启动
&./test.sh stop停止启动
看是否成功,有三种方法:
1 &看它的日志文件,这里的日志文件为:tail -f
log/myjsvc.out&
2 &看它的进程号文件是否生成:这里为test.pid
3 &查看ps -ef|grep jsvc 是否存在
&(应该是两个进程,具体为什么我也不知道)
以上例子均在本机测试通过
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。扫一扫体验手机阅读
linux守护进程原理及创建详解
<span type="1" blog_id="400260" userid='
75篇文章,26W+人气,0粉丝
高并发架构之路
¥51.0073人订阅
新西兰资深网工运维之道
¥51.00390人订阅
前百度高级工程师的架构高可用实战
¥51.00228人订阅
<span type="1" blog_id="400260" userid='APP中一种在Java层实现的简单守护进程方式 - 简书
APP中一种在Java层实现的简单守护进程方式
CB08F567-698E-46DF-970B-D178FB3BE55B154112-fbbdee.gif
守护进程是一个黑色地带的产物,无论是通过native的方式在linux中fork进程达到,还是在java层通过两个service守护的方式,都是不太友好的做法,据很多人反应,总有一些实际的业务场景中,希望自己的应用保持live状态, 一种是在native中做:
linux中多进程;
unix domain套接字实现跨进程通信;
linux的信号处理;
exec函数族的用法;
把他们组合起来实现了一个双进程守护,几个实现双进程守护时的关键点:
父进程如何监视到子进程(监视进程)的死亡?很简单,在linux中,子进程被终止时,会向父进程发送SIG_CHLD信号,于是我们可以安装信号处理函数,并在此信号处理函数中重新启动创建监视进程;
子进程(监视进程)如何监视到父进程死亡?当父进程死亡以后,子进程就成为了孤儿进程由Init进程领养,于是我们可以在一个循环中读取子进程的父进程PID,当变为1就说明其父进程已经死亡,于是可以重启父进程。这里因为采用了循环,所以就引出了之前提到的耗电量的问题。
父子进程间的通信有一种办法是父子进程间建立通信通道,然后通过监视此通道来感知对方的存在,这样不会存在之前提到的耗电量的问题,在本文的实现中,为了简单,还是采用了轮询父进程PID的办法,但是还是留出了父子进程的通信通道,虽然暂时没有用到,但可备不时之需!
这种native方式,可参考链接:
今天介绍下用两个service守护的方式作一完整的小案例。仅作学习交流之用。两个进程互相监视对方,发现对方挂掉就立刻重启!(实际就是在onDisconnected时,start另一个service)
假设我们的APP中开启了两个Service,分别是A和B,那么:如果A守护B,则B挂掉的同时,A就应该把B唤醒起来,反之亦然,也就是说A和B应该是互相守护,无论谁被杀掉,对方就把它唤醒起来。既然提到了两个Service,那么这两个Service就不能让它们同处在一个进程中,否则就会被一次性双杀。显然不能在同一个进程中,在android中通常我们可以使用AIDL来实现IPC实现。
原理图(简单版):
226BBD66-B17C-4E9C-8849-AE8C6393BB37.png
MainActivity
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 启动两个守护服务
startService(new Intent(this, ServiceA.class));
startService(new Intent(this, ServiceB.class));
&service android:name=".ServiceA"&&/service&
&service android:name=".ServiceB" android:process="com.guardprocess.remote"&&/service&
interface IBridgeInterface {
String getName();
public class ServiceA extends Service {
private static final String TAG = ServiceA.class.getSimpleName();
private MyBinder mB
private PendingIntent mPendingI
private MyServiceConnection mServiceC
public void onCreate() {
super.onCreate();
if (mBinder == null) {
mBinder = new MyBinder();
mServiceConnection = new MyServiceConnection();
public int onStartCommand(Intent intent, int flags, int startId) {
this.bindService(new Intent(this, ServiceB.class), mServiceConnection, Context.BIND_IMPORTANT);
mPendingIntent = PendingIntent.getService(this, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(this);
builder.setTicker("守护服务A启动中")
.setContentText("我是来守护B不被杀的!")
.setContentTitle("守护服务A")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(mPendingIntent)
.setWhen(System.currentTimeMillis());
Notification notification = builder.build();
// 设置service为前台进程,避免手机休眠时系统自动杀掉该服务
startForeground(startId, notification);
return START_STICKY;
class MyServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName componentName, IBinder binder) {
Log.i(TAG, "ServiceA连接成功");
Toast.makeText(ServiceA.this, "ServiceA连接成功", Toast.LENGTH_LONG).show();
public void onServiceDisconnected(ComponentName componentName) {
// 连接出现了异常断开了,RemoteService被杀掉了
Toast.makeText(ServiceA.this, "ServiceA被干掉", Toast.LENGTH_LONG).show();
// 启动ServiceB
ServiceA.this.startService(new Intent(ServiceA.this, ServiceB.class));
ServiceA.this.bindService(new Intent(ServiceA.this, ServiceB.class),
mServiceConnection, Context.BIND_IMPORTANT);
class MyBinder extends IBridgeInterface.Stub {
public String getName() throws RemoteException {
return "ServiceA";
public IBinder onBind(Intent intent) {
public class ServiceB extends Service {
private static final String TAG = ServiceB.class.getSimpleName();
private MyBinder mB
private PendingIntent mPendingI
private MyServiceConnection mServiceC
public void onCreate() {
super.onCreate();
if (mBinder == null) {
mBinder = new MyBinder();
mServiceConnection = new MyServiceConnection();
public int onStartCommand(Intent intent, int flags, int startId) {
this.bindService(new Intent(this,ServiceA.class), mServiceConnection, Context.BIND_IMPORTANT);
mPendingIntent =PendingIntent.getService(this, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(this);
builder.setTicker("守护服务B启动中")
.setContentText("我是来守护A不被杀的!")
.setContentTitle("守护服务B")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(mPendingIntent)
.setWhen(System.currentTimeMillis());
Notification notification = builder.build();
//设置service为前台进程,避免手机休眠时系统自动杀掉该服务
startForeground(startId, notification);
return START_STICKY;
class MyServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName componentName, IBinder binder) {
Log.i(TAG, "ServiceB连接成功");
Toast.makeText(ServiceB.this, "ServiceB连接成功", Toast.LENGTH_LONG).show();
public void onServiceDisconnected(ComponentName componentName) {
// 连接出现了异常断开了,LocalCastielService被杀死了
Toast.makeText(ServiceB.this, "ServiceB被干掉", Toast.LENGTH_LONG).show();
// 启动ServiceA
ServiceB.this.startService(new Intent(ServiceB.this, ServiceA.class));
ServiceB.this.bindService(new Intent(ServiceB.this, ServiceA.class), mServiceConnection, Context.BIND_IMPORTANT);
class MyBinder extends IBridgeInterface.Stub {
public String getName() throws RemoteException {
return "ServiceB";
public IBinder onBind(Intent intent) {
最后:如果系统干掉这个服务,还是难逃此劫的。向ROM厂商提出加白名单方式,才是终极最万全方案。
以上完整代码下载链接:
这里记录着一个程序媛的成长历程
守护进程是一个黑色地带的产物,无论是通过native的方式在linux中fork进程达到,还是在java层通过两个service守护的方式,都是不太友好的做法,据很多人反应,总有一些实际的业务场景中,希望自己的应用保持live状态, 一种是在native中做: linux中...
守护进程是一个黑色地带的产物,无论是通过native的方式在Linux中fork进程达到,还是在Java层通过两个service守护的方式,都是不太友好的做法,据很多人反应,总有一些实际的业务场景中,希望自己的应用保持live状态, 一种是在native中做: linux中...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金相信有很多朋友...
用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? ... Android 获取 View 宽高的常用正确方式,避免为零 - 掘金 相信有很多...
Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式...
晚间,搭乘地铁,人潮涌涌,突然间,觉得我那迷人的玉臀被类似短棍的硬物不停地顶着,刚开始以为是人太多,谁的包包或提物,没太留意,继续跟脸对脸的女友谈笑着,可慢慢觉得不对,我有意避开那硬物,那硬物却形影不离,突然一下急刹车,惯性地向前方倾斜,明显感觉到一只手有力地在我的右臀捏了...
文/陶子 《无题》 城市孤独吗 还是灵魂只和自己的影子 翩翩起舞 寂静无声的夜 你的真实终于原形毕露 撕裂开那结痂的伤疤 再一次血流如注 看见心间那滴眼泪 仍晶莹如最初 你以为走过万水千山 已忘却雪地那片白月光 你以为看尽琼楼玉宇 再也梦不到心中那片桃花源 原来一切模糊又清...
怎么才能拉近与陌生人的关系?怎么才能有出小区就众人问好的感觉?怎么能迅速认识陌生人?怎么能和许久未见的朋友保持联系?怎么能一发朋友圈就收获无数个赞和评论? 好吧,告诉你答案,首先,你要有个娃,你要有个娃,你要有个娃。重要的事情说三遍。 怀孕四五个月的时候,租住在富人区。氛围...
我想,任何一个接受过教育的人应该都知道250+360=610,就算是没有接受过任何教育,在生活的烟熏火燎里也必然会知道就是这个答案。 可是我今天想说的,不是250+360=610,而是在生活里250+360也可以等于510。也许当你看到这篇文章题目的时候就产生了否定想法,确...【Linux学习杂谈】之守护进程以及简单创建 - Linux论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
【Linux学习杂谈】之守护进程以及简单创建
高级工程师
13:28:06  
首先我们需要了解一下什么叫做守护进程,以及我们为什么需要这样的进程。我们知道当我们写一个简单的程序的时候我们知道,这个程序比如说printf一些信息出来我们最终会在终端上面看到,但是当我们整个main函数执行完了,这个程序也就完成了。同样的当我们关闭一个终端的时候,伴随在终端运行的程序也就结束了。但是我们有时候会有这样的需求,比如说我们希望能有一个程序一直接收我们所发送的信息,并进行处理,但是如果想我们和终端进行绑定的话是肯定不行的,也就是我们需要一个进程,能够在后台一直运行,这个时候我们就引入了守护进程这个概念。那么相应的守护进程就能够实现一直在后台运行,不会出现我们关闭终端它就结束的情况。这种进程我们在服务器当中用的很多,我们需要对客户端提供服务,那么服务器的服务程序需要一直运行,能够在后台实时响应用户的请求,并给出回复。
插播一个知识点:ps查看进程。如果我们在中断输入ps的话我们查看到的是当前终端当中运行的进程。下面我们按下两个常用的ps参数命令。ps -ajx 偏向于显示各种有关的ID号,包括ppid、pid、pgid、sid,分别是父进程ID,进程ID,进程组ID,会话ID。ps -aux偏向于显示进程占用的资源,比如说我们的系统CPU使用率、内存使用率等等。
kill命令可以用来向进程发送指令。这里我们可以百度得到各种参数的用法我们在这里不一一进行列出了。使用方式:kill -信号编号 进程ID比如我们常用的关闭进程的命令:kill -9 进程ID
守护进程的英文为daemon,简写为d,当我们去查看系统该进程的时候后面如果是以d结尾的一般都是守护进程,这里说的是一般,并不包括所有以d结尾的进程都是守护进程,这里要根据实际情况进行判断。守护进程是一个长期运行的进程,和我们的控制台是脱离的,不依附于控制台运行的,普通程序是需要依附在控制台运行,如果控制台(终端)关闭的话,那么伴随终端的所有进程就会都被关闭了。
常见的守护进程:syslogd:这个进程是系统日志的守护进程,提供syslogcron:这个进程用来实现操作系统时间管理,可以看到这个进程虽然结尾不是d但是它也是一个守护进程
我们看下创建一个守护进程的方式:1.创建一个子进程,而后结束父进程2.用setpid为进程设置一个新的会话期session,目的是让进程脱离控制台3.用chdir将工作目录设置为’/’,切换到根目录4.用umask设置为0,保证进程对文件操作有一个最大权限5.关闭所有的文件描述符,可以通过sysconf获取开启了多少个文件6.将文件描述符0,1,2重定位到/dev/null
下面我们来实际代码测试一下:#include &stdio.h&
#include &unistd.h&
#include &stdlib.h&
#include &sys/types.h&
#include &sys/stat.h&
#include &fcntl.h&
void create_daemon(void);
int main(void){
& & & &
& & & & create_daemon();& & & &
& & & & while (1)
& & & & {
& & & & & & & & printf(&This is a dameon test.\n&);
& & & & & & & &
& & & & & & & & sleep(1);
& & & & }
& & & &
& & & & return 0;
}
// 在这里我们来创建一个守护进程
void create_daemon(void){
& & & & // 第一步:创建一个子进程,同时结束父进程
& & & & pid_t pid = 0;
& & & & pid = fork();
& & & & if(pid & 0){
& & & & & & & & perror(&fork:&);
& & & & & & & & exit(-1);
& & & & }
& & & & if(pid & 0){
& & & & & & & & exit(0);
& & & & }
& & & & // 到这里我们就完成了子进程创建,父进程结束的过程
& & & & // 第二步:设置一个新的会话期,脱离控制台
& & & & pid = setsid();
& & & & if(pid & 0){
& & & & & & & & perror(&setsid:&);
& & & & & & & & exit(-1);
& & & & }
& & & &
& & & & // 第三步:设置工作路径到根目录
& & & & chdir(&/&);
& & & &
& & & & // 第四步:设置文件的可操作的最高权限
& & & & umask(0);
& & & &
& & & & // 第五步:关闭当前的所有文件描述符
& & & & int cnt = sysconf(_SC_OPEN_MAX);
& & & & int i = 0;
& & & & for(i = 0;i & i++){
& & & & & & & & close(i);
& & & & }
& & & &
& & & & // 第六步:重定向0,1,2这三个文件描述符
& & & & // 这三个文件描述符分别是标准输出,标准输入和标准错误
& & & & open(&/dev/null&,O_RDWR);
& & & & open(&/dev/null&,O_RDWR);
& & & & open(&/dev/null&,O_RDWR);
& & & &
您的付出是论坛的动力,感谢您一直支持!.
19:46:29  
谢谢楼主的分享~
高级工程师
23:43:15  
谢谢楼主的分享~
林超文手把手教你学!
教你1000种电路设计思路
张飞硬件电路之PFC全集
参与免费送VIP+原创视频
运放、ADC、电磁兼容
Powered by
供应链服务
版权所有 (C) 深圳华强聚丰电子科技有限公司&nbsp>&nbsp
&nbsp>&nbsp
&nbsp>&nbsp
Linux入门:创建守护进程
摘要:&&&&守护进程(deamon),也称精灵进程,是一种运行在后台的一种特殊的进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。由于在Linux中,每个系统与用户进行交流的界面成为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端被称为这些进程的控制终端,当控制终端被关闭的时候,相应的进程都会自动关闭。但是守护进程却能突破这种限制,它脱离于终端并且在后台运行,并且它脱离终端的目的是为了避免进程在运行的过程
& & & &守护进程(deamon),也称精灵进程,是一种运行在后台的一种特殊的进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。由于在Linux中,每个系统与用户进行交流的界面成为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端被称为这些进程的控制终端,当控制终端被关闭的时候,相应的进程都会自动关闭。但是守护进程却能突破这种限制,它脱离于终端并且在后台运行,并且它脱离终端的目的是为了避免进程在运行的过程中的信息在任何终端中显示并且进程也不会被任何终端所产生的终端信息所打断。它从被执行的时候开始运转,直到整个系统关闭才退出(当然可以人为的杀死相应的守护进程)。如果想让某个进程不因为用户或中断或其他变化而影响,那么就必须把这个进程变成一个守护进程。
& & & &守护进程一般以‘d’结尾,查看当前守护进程:ps ajx | grep 'd$'
创建守护进程最重要的一步是调用setsid函数创建一个新的session,并成为session leader(pid_t setsid(void)),该函数调用成功时返回新创建的session的id(也就是当前进程的id),调用这个函数的进程不允许是当前进程组的组长进程,否则出错返回-1。要保证当前进程不是组长进程只需要先fork一下再让父进程退出(exit)即可。
进程组即是一个或多个进程的集合,每个进程组都有一个唯一的进程组id等于其组长进程的id,只要进程组中有一个进程存在,该进程组就存在,与组长进程是否存在无关;而每打开一个终端就会新建一个会话,关闭一个终端则会关闭一个会话,此期间所有进程都会属于这个会话。
成功调用该函数的结果是:
1.创建一个新的session,当前进程为session leader,当前进程的id为session的id。
2.创建一个新的进程组,当前进程成为进程组的leader,当前进程的id就是进程组的id。
3.如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有终端的额守护进程。所谓失去终端是指,原来的控制终端仍然是打开的,任然可以读写,但只是一个普通的文件而不是控制终端了。
创建守护进程:
1.调用uamsk将文件模式创建屏蔽字设置为0;
2.调用fork,父进程退出;
3.调用setsid创建一个新会话;
4.再次调用fork,让父进程退出;
5.将当前工作目录改为根目录(因为根目录下的文件不易被删除);
6.关闭不再需要的文件描述符;
7.忽略SIGCHLD信号。
第一次调用fork是必不可少的:
(1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使shell认为该命令已执行完毕,不用
挂在输入终端上
(2)为了调用setsid函数服务,保证子进程不是一个进程组的组长进程
第二次调用fork不是必须的,是为了防止误操作再打开一个会话终端,因为打开一个会话终端的前提条件是该进 & & & &程需为会话组长,再fork一次,sid就为父进程的id,所以也就无法打开新的会话终端。
程序代码:#include &stdio.h&#include &unistd.h&#include &stdlib.h&#include &signal.h&void mydaemon(){ umask(0); if(fork() & 0) exit(0); setsid(); if(fork() & 0) exit(0); chdir(&/&); close(0); close(1); close(2); signal(SIGCHLD, SIG_IGN);}int main(){ mydaemon(); while(1) { } return 0;}运行结果:也可以调用函数创建守护进程:int daemon(0, 0);
以上是的内容,更多
的内容,请您使用右上方搜索功能获取相关信息。
若你要投稿、删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内给你回复。
云服务器 ECS
可弹性伸缩、安全稳定、简单易用
&40.8元/月起
预测未发生的攻击
&24元/月起
邮箱低至5折
推荐购买再奖现金,最高25%
&200元/3月起
你可能还喜欢
你可能感兴趣
阿里云教程中心为您免费提供
Linux入门:创建守护进程相关信息,包括
的信息,所有Linux入门:创建守护进程相关内容均不代表阿里云的意见!投稿删除文章请联系邮箱:zixun-group@service.aliyun.com,工作人员会在五个工作日内答复
售前咨询热线
支持与服务
资源和社区
关注阿里云
International

我要回帖

更多关于 创建守护进程 的文章

 

随机推荐