运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

简介:

运维经验分享作为一个专题,目前共7篇文章

  1. 运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本

  2. 运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化

  3. 运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)

  4. 运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

  5. 运维经验分享(五)-- 改进的java进程管理的服务控制脚本

  6. 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)

  7. 运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化

====================================分割线======================================

ChatterServer 之所以有如此多版和遇到这么多问题,跟java进程还有很大的关系,此次面临的问题和分析思路总结如下,欢迎各位补充。

停止java进程可能面临的问题:

  1. 以kill pid的方式停止java进程,java进程在等待java进程内部结束,因此没有立即结束,从而导致原java程序监听的端口可能没有释放,原java进程的pid也可能依然存在

  2. 在原java进程没有立即结束的情况下,再重新启动这个java进程就会产生错误,这些错误包括无法重新监听端口,甚至是直接启动失败

  3. 启动java进程可能面临的问题:

  4. 用java命令启动java进程,java进程返回结果为成功,但实际不成功(需要注意确认“用java命令启动java进程”返回的执行结果是java自身返回的,还是人工编写的程序返回的)

上面描述的一些进一步解释、术语和例子:

  1. java进程是指由人工编写的一些java程序,其中不能保证程序里面的异常全部捕获并处理,例如如果无法监听端口返回正确的错误返回值并退出

  2. 以kill pid的方式:kill `cat $PIDFILE`

  3. 用java命令启动java进程:java -jar somename.jar $ARGS

原有的启动java进程的流程

  1. 启动进程有两种情况,第一次启动(首次启动),停止进程后再次启动(重新启动),因此可以考虑将这两种情况综合在一起考虑,即不区分之前是否启动过或停止过,把这些情况都考虑进去

  2. 判断当前系统中的特定目录下是否存在pid文件或者锁

  3. 判断当前系统中是否已经存在java进程,判断的依据是从系统中检测java进程pid是否存在,如ps,而不是根据pid文件或者锁判断

  4. 判断当前系统中是否已经监听端口号,因为端口号可能由别的程序(如果pid不存在,则该端口号不会由它自己占用)占用

  5. 启动java进程(大部分程序都会保证此处能启动成功,可参考/etc/init.d/functions,行270,1-8),如果返回结果为成功,则输出成功并创建pid文件和锁,如果不成功,则输出不成功,不再尝试再次启动

原有的停止java进程的流程

  1. 如果找到pid,先发送TERM信号,暂停100000微秒(usleep 100000),如果人工预先知道需要继续延迟,则延迟自定义秒数,如果没有杀死(即依然能检测到系统中存在此pid)则再发送KILL信号,再次暂停100000微秒

  2. 再次检测到系统中是否存在此pid,如果不存在则输出成功并移除pid文件和锁,如果存在则输出不成功

  3. 如果找不到pid,则输出程序没有在运行

根据以上问题重新设计启动java进程的流程(主要问题所在)

  1. 启动进程有两种情况,第一次启动(首次启动),停止进程后再次启动(重新启动),因此可以考虑将这两种情况综合在一起考虑,即不区分之前是否启动过或停止过,把这些情况都考虑进去

  2. 判断当前系统中的特定目录下是否存在pid文件(原有设计中没有锁,故此处不使用锁)

  3. 判断当前系统中是否已经存在java进程,判断的依据是从系统中检测java进程pid是否存在,如test -d /proc/$pid,ps,而不是根据pid文件或者锁判断

  4. 判断当前系统中是否已经监听端口号,因为端口号可能由别的程序(如果pid不存在,则该端口号不会由它自己占用)占用

  5. 启动java进程(大部分程序都会保证此处能启动成功,可参考/etc/init.d/functions,行270,1-8),如果返回结果为成功,从系统中检测java进程pid是否存在,如果pid存在则输出成功并创建pid文件(原有设计中没有锁,故此处不使用锁),如果pid不存在,则再次启动java进程,移除“如果不成功,则输出不成功,不再尝试再次启动”。

根据以上问题重新设计停止java进程的流程

  1. 针对java进程没有杀死的可能性,现做出如此修改,如果找到pid,先发送TERM信号,暂停100000微秒(usleep 100000),已经预先知道需要继续延迟,延迟5秒,如果没有杀死(即依然能检测到系统中存在此pid)则再发送KILL信号,再次暂停100000微秒

  2. 再次检测到系统中是否存在此pid,如果不存在则输出成功并移除pid文件(原有设计中没有锁,故此处不使用锁),如果pid依然存在则再尝试kill -9(The signals SIGKILL and SIGSTOP cannot be caught, blocked, or ignored.当前假设认为-9比kill更加强制)

  3. 如果找不到pid,则输出程序没有在运行

--end--

====================================分割线======================================

运维经验分享作为一个专题,目前共7篇文章

  1. 运维经验分享(一)-- Linux Shell之ChatterServer服务控制脚本

  2. 运维经验分享(二)-- Linux Shell之ChatterServer服务控制脚本二次优化

  3. 运维经验分享(三)-- 解决Ubuntu下crontab不能正确执行Shell脚本的问题(一)

  4. 运维经验分享(四)--关于 java进程管理的服务控制脚本编程思路分析

  5. 运维经验分享(五)-- 改进的java进程管理的服务控制脚本

  6. 运维经验分享(六)-- 深究crontab不能正确执行Shell脚本的问题(二)

  7. 运维经验分享(七)-- Linux Shell之ChatterServer服务控制脚本第三次优化




本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1677155,如需转载请自行联系原作者


相关文章
|
24天前
|
人工智能 运维 Linux
AI驱动的操作系统服务体验:大模型时代的运维革新
AI驱动的操作系统服务体验:大模型时代的运维革新
32 5
|
2月前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
2月前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
79 12
|
2月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
209 2
|
2月前
|
运维 监控 Ubuntu
【运维】如何在Ubuntu中设置一个内存守护进程来确保内存不会溢出
通过设置内存守护进程,可以有效监控和管理系统内存使用情况,防止内存溢出带来的系统崩溃和服务中断。本文介绍了如何在Ubuntu中编写和配置内存守护脚本,并将其设置为systemd服务。通过这种方式,可以在内存使用超过设定阈值时自动采取措施,确保系统稳定运行。
103 4
|
2月前
|
Java 对象存储 开发者
如何找出Java进程占用CPU高的元凶
本文记录了一次Java进程CPU占用率过高的问题和排查思路。
|
2月前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
2月前
|
运维 监控 Cloud Native
云原生之运维监控实践:使用 taosKeeper 与 TDinsight 实现对 时序数据库TDengine 服务的监测告警
在数字化转型的过程中,监控与告警功能的优化对保障系统的稳定运行至关重要。本篇文章是“2024,我想和 TDengine 谈谈”征文活动的三等奖作品之一,详细介绍了如何利用 TDengine、taosKeeper 和 TDinsight 实现对 TDengine 服务的状态监控与告警功能。作者通过容器化安装 TDengine 和 Grafana,演示了如何配置 Grafana 数据源、导入 TDinsight 仪表板、以及如何设置告警规则和通知策略。欢迎大家阅读。
63 0
|
2月前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
71 3
|
18天前
|
监控 运维
HTTPS 证书自动化运维:https证书管理系统- 自动化监控
本文介绍如何设置和查看域名或证书监控。步骤1:根据证书状态选择新增域名或证书监控,线上部署推荐域名监控,未部署选择证书监控。步骤2:查询监控记录详情。步骤3:在详情页查看每日定时检测结果或手动测试。
HTTPS 证书自动化运维:https证书管理系统- 自动化监控