linux 如何实现java守护进程编程开发
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 如何实现java守护进程编程开发相关的知识,希望对你有一定的参考价值。
linux如何实现 java 守护进程编程开发
可以通过GuardServer实现,具体代码如下;
1 public class GuardServer2 private String servername;
3
4 public GuardServer(String servername)
5 this.servername = servername;
6
7
8 public void startServer(String cmd) throws Exception
9 System.out.println("Start Server : " + cmd);
10 //将命令分开
11 // String[] cmds = cmd.split(" ");
12 // ProcessBuilder builder = new ProcessBuilder(cmds);
13
14 //
15 ProcessBuilder builder=new ProcessBuilder(new String[]"/bin/sh","-c",cmd);
16 //将服务器程序的输出定位到/dev/tty
17 builder.redirectOutput(new File("/dev/tty"));
18 builder.redirectError(new File("/dev/tty"));
19 builder.start(); // throws IOException
20 Thread.sleep(10000);
21
22
23 /**
24 * 检测服务是否存在
25 *
26 * @return 返回配置的java程序的pid
27 * @return pid >0 返回的是 pid <=0 代表指定java程序未运行
28 * **/
29 public int checkServer() throws Exception
30 int pid = -1;
31 Process process = null;
32 BufferedReader reader = null;
33 process = Runtime.getRuntime().exec("jps -l");
34 reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
35 String line;
36 while ((line = reader.readLine()) != null)
37 String[] strings = line.split("\\\\s1,");
38 if (strings.length < 2)
39 continue;
40 if (strings[1].contains(servername))
41 pid = Integer.parseInt(strings[0]);
42 break;
43
44
45 reader.close();
46 process.destroy();
47 return pid;
48
49 参考技术A 程序的运行就是一个进程。
你还想怎么样?
把可以运行的程序打包成jar包,然后在对应的用户下面 执行 jave -jar yourApplicationName.jar 即可追问
这是个web项目,,需求是:解析一个文件,获得文件的版本号,所以这个java解析类,必须获得root权限才能解析,在windows下正常使用但是在linux下,报错:么有权限,这个java解析类要监视着8080端口,只要client有要解析的文件,这java解析类就得解析获得版本号,返回给client端,现在报错这个解析类报错,没有root权限;所以得获得root权限
追答容器装好了没?你用的是哪个容器?
追问tomcat啊。。linux debian系统。。。
追答加入你的tomcat用户为tomusr,有没有在root权限下,执行过
chown -R tomusr tomcatDir
chmod -R 777 tomcatDir
我不太懂 linux,但是tomcat绝对不能有 root权限,会引发安全性问题。
追答所以才叫你用chown,把权限交给tomusr用户
追问没用过啊。。chown 是把什么权限交给tomcat用户啊
追答所有操作权限
追问所有权限那不就是root权限吗???我对linux不太了解
追答别傻了,那个用户可以完全得到root的权限的,至少用su的时候,非root用户要输密码。那个chown,是把root原来对tomcat的操作权限,给了tomusr
参考技术B linux权限问题需要在root权限下运行即可使该进程拥有root权限追问tomcat 出于安全性,不可能 赋给他root权限的,
追答我看你在别人那里的追问了,你说在windows下正常使用,那你在windows使用的应该也是administrator权限,跟linux中的root是对等的
追问就是从request 获得文件,现在解析,没有权限,没有root权限,解析不了,我总不能给tomcat root权限把,所以用独立解析类解析文件,返回版本号,就是让这个解析jar包获得root权限,成为守护进程,后台运行。监听着;只要有文件上传这个解析jar包就解析这个文件,返回版本号。
追答那我建议你做插口式项目,解析JAR包作为独立类拥有独立运行的可能,在原WEB项目上预留解析jar包的接口,需要解析时调用web项目外解析包,在进行反馈,这样可以在外部解决权限问题,不然的话你只能为你的程序填写配置文本对某一程序流进行授权。
追问插口项目?没听过啊。是webservices借口吗?
追答外部调用
参考技术C 这是什么问题啊?什么守护进程?不就是个死循环吗?追问其实就是 使这个java程序成为进程,获得root权限,
追答在root权限下运行,程序自然就有root权限
追问这是个web项目,,需求是:解析一个文件,获得文件的版本号,所以这个java解析类,必须获得root权限才能解析,在windows下正常使用但是在linux下,报错:么有权限,这个java解析类要监视着8080端口,只要client有要解析的文件,这java解析类就得解析获得版本号,返回给client端,现在报错这个解析类报错,没有root权限;所以得获得root权限
追答这个问题有些蹊跷,既然是web项目,为什么要监视8080端口?而不是从request中获得client发过来的文件?如果要监视端口号,就必须用独立的程序才可以,并且需要在root权限下启动
追问你说的对,就是从request 获得文件,现在解析,没有权限,没有root权限,解析不了,我总不能给tomcat root权限把,所以用独立解析类解析文件,返回版本号,就是让这个解析jar包获得root权限,成为守护进程,后台运行。监听着;只要有文件上传这个解析jar包就解析这个文件,返回版本号。
追答你解决问题的方向错了,要是从request获得文件就,就在web程序里解析,出现解析出错没有权限,是因为你的解析算法有问题,访问了超出权限的资源,如果这些资源必须用root权限,那么这个项目就是失败的,否则只要把这些资源的权限分配给tomcat启动的用户就可以了。
追问忘了告诉你这个
自己
写的java类调用apktools.JAR
那就是apktool.jar里调用了其他资源,你最好了解一下都用了哪些资源,看看能不能把这些资源的权限给tomcat的启动用户
追问可以用root 用户 执行nohup java 那个类,设成后台进程,吗?
追答没有懂你的意思,什么nohup?
追问linux 的nohup 命令啊 、、、以root用户启动我写好的jar,作为后台进程啊。还有个问题就是java里面有进程吗?我只知道java里的thread线程,运行写好的jar,就是起了个进程呗。。呵呵,对嘛
追答你的解决方案很有问题,怎么又用什么独立的进程了?如果这么用怎么截取request?又怎么返回client?
追问抛开request 不考虑,就是单纯的 解析文件,我不能确定什么时候jar包会解析文件,所以我只能把这个jar,运行,起个进程在后台运行。只要客户端要解析文件,jar包就得解析并把版本号返回client来,这个用到了socket。 我是这么个思路,就是这个jar包要一直运行着,并且有root权限。麻烦你了。。
追答这种思路不好,可以这样做,
1.webapp 将请求存到数据库中,然后等待
2.独立运行程序扫描数据库,有数据就解析,解析结果存储到数据库
3.weapp将解析结果返回
[Python网络编程]浅析守护进程后台任务的设计与实现
在做基于B/S应用中。常常有须要后台执行任务的需求,最简单比方发送邮件。在一些如防火墙,WAF等项目中,前台仅仅是为了展示内容与各种參数配置。后台守护进程才是重头戏。所以在防火墙配置页面中可能会常常看到调用cgi。但真正做事的一般并非cgi,比方说执行关机命令,他们的逻辑例如以下:
(ps:上图所说的前台界面包括通常web开发中的后端,不然也没有socket一说)
为什么要这么设计
怎样实现
class MgrService(win32serviceutil.ServiceFramework): """ Usage: ‘python topmgr.py install|remove|start|stop|restart‘ """ #服务名 _svc_name_ = "Mgr" #服务显示名称 _svc_display_name_ = "Daemon Mgr" #服务描写叙述 _svc_description_ = "Daemon Mgr" def __init__(self, args): win32serviceutil.ServiceFramework.__init__(self, args) self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) def SvcDoRun(self): self.ReportServiceStatus(win32service.SERVICE_START_PENDING) INFO("mgr startting...") self.ReportServiceStatus(win32service.SERVICE_RUNNING) self.start() # 等待服务被停止 INFO("mgr waitting...") win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE) INFO("mgr end") def SvcStop(self): self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) INFO("mgr stopping...") self.stop() INFO("mgr stopped") # 设置事件 win32event.SetEvent(self.hWaitStop) self.ReportServiceStatus(win32service.SERVICE_STOPPED) def start(self): pass def stop(self): pass非常easy。这样就实现了windows中的服务,也就是说脱离终端。执行于后台。
INFO等函数仅仅是简单的记录作用。可直接忽略。
class Engine(MgrService): rbufsize = -1 wbufsize = 0 def start(self): INFO(‘wait connection‘) self.server = StreamServer((HOST, PORT), self.msg_handle) self.server.serve_forever() def msg_handle(self,socket,address): try: rfile = socket.makefile(‘rb‘, self.rbufsize) wfile = socket.makefile(‘wb‘, self.wbufsize) headers = Message(rfile).dict INFO(‘get a connection from:%s,headers:%s‘ % (str(address), headers)) if ‘module‘ in headers and headers[‘module‘] in MODULES: MODULES[headers[‘module‘]].handle(wfile, headers) except Exception: ERROR(‘msg_handle exception,please check‘) def stop(self): if hasattr(self, server): self.server.stop()当有新连接到来,由msg_handle处理,首先读取发送来的消息。消息格式使用了最简单的http的格式,即(键名:键值)的格式,你要问我为什么採用这个格式,哈哈,格式简单,python有现成的库解析。
上面代码的那个MODULES是个全局变量,当你加入一个模块的时候须要注冊到MODULES中,我提供了module_register方法。
MODULES = { # module: handle module class } def module_register(module_name, handle_class): if module_name in MODULES: WARN(‘duplicate module_name:‘ + module_name) else: MODULES[module_name] = handle_class
class Module(object): SECRE_KEY = "YI-LUO-KEHAN" MODULE_NAME = "BASE_MODULE" PREFIX = "do_" # method prefix def __init__(self, wfile, headers): self.wfile = wfile self.headers = headers def __getattr__(self, name): try: return self.headers[name] except Exception: ERROR("%s has no attr:%s,please check" %(self.MODULE_NAME, name)) @classmethod def handle(cls, wfile, headers): module_obj = cls(wfile, headers) module_obj.schedule_default() def verify(self): if hmac.new(self.SECRE_KEY, self.MODULE_NAME).hexdigest() == self.signature: return True else: WARN("client verify failed,signature:%s" % str(self.signature)) def schedule_default(self): err_code = 0 if self.verify() and self.action: func_name = self.PREFIX + self.action try: getattr(self, func_name)() except AttributeError: err_code = 1 ERROR("%s has no method:%s" %(self.MODULE_NAME, func_name)) except Exception: err_code = 2 ERROR("module:%s,method:%s,exception" % (self.MODULE_NAME, func_name)) else: err_code = 3 if err_code: self.send_error({‘err_code‘:err_code}) def send_success(self, msg=‘‘): data = {‘success‘:True,‘msg‘:msg} self.wfile.write(json.dumps(data)) def send_error(self, msg=‘‘): data = {‘success‘:False,‘msg‘:msg} self.wfile.write(json.dumps(data))
在基类模块中我们提供了默认的处理流程,即依据消息中action,调用do_action方法。并提供了一个简单但非常有效的认证方法,通过消息的signature字段,可能有些简陋。但没关系,你能够定义自己的认证方法。
TASK = {} # task_id: pid class ScanModule(Module): MODULE_NAME = "SCAN_MODULE" def do_start(self): self.send_success(‘start ok‘) DEBUG(‘------------task start------------‘) task_ids = [int(task_id) for task_id in self.task_ids.split(‘,‘) if int(task_id) not in TASK] for task_id in task_ids: try: cmd = ‘python scan.py -t %s‘ % task_id DEBUG(cmd) self.sub = Popen(cmd, shell=True, cwd=CWD) pid = int(self.sub.pid) TASK[task_id] = pid INFO(‘%s start a new task,task_id:%s,pid:%s‘ %(self.MODULE_NAME, task_id, pid)) except Exception: ERROR(‘%s start a new task,task_id:%s failed‘ % (self.MODULE_NAME, task_id)) def do_stop(self): self.send_success(‘stop ok‘) DEBUG(‘------------task stop------------‘) task_ids = [int(task_id) for task_id in self.task_ids.split(‘,‘) if int(task_id) in TASK] for task_id in task_ids: pid = TASK.pop(task_id) try: INFO(‘%s stop a new task,task_id:%s,pid:%s‘ %(self.MODULE_NAME, task_id, pid)) call([‘taskkill‘, ‘/F‘, ‘/T‘, ‘/PID‘, str(pid)]) except Exception: ERROR(‘%s taskkill a task failed,task_id:%s,pid:%s‘ %(self.MODULE_NAME, task_id, pid)) module_register(ScanModule.MODULE_NAME, ScanModule)
所以说as soon as possible
#!/usr/bin/env python #-*-encoding:UTF-8-*- import hmac import gevent from gevent import monkey monkey.patch_socket() addr = (‘localhost‘, 6667) def send_request(module_name,request_headers): SECRE_KEY = "YI-LUO-KEHAN" socket = gevent.socket.socket() socket.connect(addr) request_headers[‘module‘] = module_name request_headers[‘signature‘] = hmac.new(SECRE_KEY, module_name).hexdigest() h = ["%s:%s" %(k, v) for k,v in request_headers.iteritems()] h.append(‘\n‘) request = ‘\n‘.join(h) socket.send(request) print socket.recv(8192) socket.close() if __name__ =="__main__": import sys if sys.argv[1] == ‘start‘: send_request(‘SCAN_MODULE‘,{‘action‘:‘start‘,‘task_ids‘:‘1‘}) else: send_request(‘SCAN_MODULE‘,{‘action‘:‘stop‘,‘task_ids‘:‘1‘})
!
!
以上是关于linux 如何实现java守护进程编程开发的主要内容,如果未能解决你的问题,请参考以下文章