【这是一猿小讲的第 48 篇原创分享】

各位坐稳扶好,我们要开车了。不过在开车之前,我们还是例行回顾一下上期分享的要点。

上期我们抛了一个砖:“如何实现 Java 应用进程的状态监控,如果被监控的进程 down 掉,是否有机制能启动起来?”并结合 Resin 应用服务器背后启动的进程,更详细的阐述了一下问题。

我们依然不考虑自己怎么去实现,而是先看看 Resin 这款技术轮子,是不是按照我们的猜想设计的呢?是不是可以模仿一二?

好了,熟读唐诗三百首,不会作诗也会吟,抱着疑问,我们再深入一次 Resin 的源码,如果不感兴趣,或者脑仁疼,那建议跳到下篇直接撸码实战。

1.

我们从 ResinBoot 的 main 函数开始,一步一步来看看怎么实现,目标是提取里面的关键核心思想,细枝末节莫纠结。

ResinBoot 的 main 函数是 Resin 应用服务器入口,大概流程如下:

创建 ResinBoot 实例 boot;

然后根据传入的 args 参数获取对应的 XxCommand 对象;

接着调用 ResinBoot 的 start 函数,完成服务的启动;

最后退出 ResinBoot 的进程。

那接下来不妨再深入看看创建 ResinBoot 对象时,构造方法中都干了啥?

发现 ResinBoot 创建对象时,构造方法中创建了 WatchdogArgs 对象,WatchdogArgs 里面到底又做了什么呢?

发现 WatchdogArgs 静态代码块中提前预制了一堆命令执行的对象实例,其中就包括 StartCommand,再回头看看它的构造方法,会发现会进行解析咱们 main 函数传入的 args 入参,然后根据入参获取对应的命令执行对象。

其中格式化命令行入参的方法 parseCommandLine 会匹配一堆预制的参数,实在匹配不到就从静态的 _commandMap 中去匹配对应的命令执行对象,当然咱们传入的参数是 start,所以会匹配成功  StartCommand。

那么我们再回头看看 ResinBoot 的 main 函数,发现又调用了 ResinBoot 的 start 方法。

那我们也一起看看 ResinBoot 的 start 方法做了些什么操作?发现方法中获取对应的 command,然后调用 command.doCommand() 方法。

我们知道此时的 command 为 StartCommand,那 StartCommand 中的 doCommand() 到底做了什么事情呢?会发现 doCommand 方法中调用了 WatchdogClient 的 startWatchdog 的方法。

那我们看看 startWatchdog 方法中又做了哪些事情?重点要来了,重点要来了,重点要来了。发现调用了 launchManager 方法,那 launchManager 又是干什么的呢?

仔细深入会发现,launchManager 方法主要用 ProcessBuilder 来实现启动 WatchdogManager 的进程。

并且第 539 行有一句日志输出,和咱们在控制台输入 ./resin.sh start 命令启动 Resin 服务时的日志不谋而合。

至此,ResinBoot 通过 ProcessBuilder.start() 成功触发启动 WatchdogManager 进程,也就是咱们猜测的大总管进程,哪丫鬟进程是否也存在呢?丫鬟进程又是怎么启动的呢?

2.

此时我们跟随源码设计的脚步,继续向下刨一刨 WatchdogManager,发现 WatchdogManager 程序入口 main 函数中,根据传入参数构建了 WatchdogManager 对象,并通过参数获取对应的 XxCommand(似曾相识的感觉),然后通过 XxCommand 调用 doWatchdogStart 函数完成服务的启动。

再深入去跟踪,发现 doWatchdogStart 方法中会调用 WatchdogManager 的 startServer 方法。

那 startServer 方法中又干了什么事情呢?很显然是通过配置找到要启动的子服务,然后调用重载的 startServer 方法。

接着就开始调用 WatchdogChild 的 start 方法,方法干了什么事情呢?

WatchdogChild 的 start 方法中创建了 WatchdogChildTask 任务对象,并调用 start 方法完成任务启动。

其中 WatchdogChildTask 的 start 方法很简单,就是起了一个线程开始跑任务。

重点再一次来临,会发现线程体中创建了一个 WatchdogChildProcess 对象实例,接着调用对象的 run 方法。此处就是保证了 Resin 应用为什么一直杀不死的原因,有个循环调度,一旦子进程有问题,立即再次进行创建子进程。

我们看看 run 方法的实现,会发现创建了一个 socket 用于通讯;然后把端口传入 createProcess 方法构建 Resin 进程对象。

接着会发现 WatchdogProcess 的创建进程的方法 createProcess 中定义要启动的类为 com.caucho.server.resin.Resin;然后封装一系列的参数;紧接着用 ProcessBuilder 完成 Resin 进程的启动。

然后 connectToChild 方法主要用于等待子进程的连接。这不就是大总管开辟的实时通讯的端口么!

至此,我们知道 WatchdogManager 会创建 WatchdogTask 任务,用于创建WatchdogChildProcess 对象,此对象会触发启动 Resin 进程,并提供 socket 通讯服务。

3.

那 Resin 进程又干了啥?我们依然从 main 函数开始看起。一目了然根据传入参数创建 Resin 实例,然后重点关注一下 waitForExit,这个是不是和咱们猜测的丫鬟进程与大总管进程通讯不上就退出,是不是这么回事呢?

然后深入 Resin 的 waitForExit 方法发现通过 pingSocket 参数构建 ResinWaitForExitService,用于启动 ResinActor(这个 Actor 模型前期的分享咱们提过一嘴),然后调用 waitForExit 方法。

到这大概也就到了最后,根据蓝色框中的日志输出约莫也就是那么回事儿。

...... 此处省略一万图(不刨了,点到为止)......

至此,丫鬟进程 Resin 也启动完毕了,并且与父进程建立了实时通讯。源码看了七七八八,细枝末节没细谈,主要是能明白梗概,梳理个大致脉略,能大致清晰 Resin 服务启动时启动了 ResinBoot 进程、WatchdogManager 进程、Resin 进程,当进程启动完成后 ResinBoot 进程就正常退出了,所以当我们用 jps 命令看时,就发现只有 WatchdogManager、Resin 两个进程啦,其中用到的核心技术为 ProcessBuilder、Socket 通讯。

好了,能坚持看到这儿的,那绝对都是铁粉,希望我不是一人在饮酒醉,独醉不如众醉,独乐乐不如众乐乐,希望这期的分享能帮你打通任督二脉,以后如果真用到时,不妨以本文作为参考,说不定会有点价值。

下期我们将站在 Resin 的肩膀上进行实战,请各位期待。

推荐阅读:

如何让Java应用成为杀不死的小强?(中篇)相关推荐

  1. ida so 不root_十字符病毒,杀不死的小强,一次云服务器沦陷实录

    一.现象 接到客户的电话,说自己的云服务器被提供商禁止访问了,原因是监测到网络流量暴满,服务器不停的向外发包,在确认客户没有业务量突增的情况下,初步判断可能服务器遭受了流量攻&击(DDOS), ...

  2. linux感染十字符病毒,十字符病毒,杀不死的小强,一次云服务器沦陷实录

    一.现象 接到客户的电话,说自己的云服务器被提供商禁止访问了,原因是监测到网络流量暴满,服务器不停的向外发包,在确认客户没有业务量突增的情况下,初步判断可能服务器遭受了流量攻&击(DDOS), ...

  3. 一次杀不死的进程记录

    1. 发现问题: 服务器今天发现遭受木马攻击,疑似挖矿程序植入,cpu一路飙升至99%,导致其他程序异常卡顿. 机智的我上来一个top命令让程序现出原形,结果发现一个dvjj的进程耗尽了资源. 2. ...

  4. app之 杀不死的进程

    有些需求要求app进程杀不死 我觉的扯再多都是没用的  不如 给你们看看~~~人家是如何实现的 demo是可以用的 我已经测试成功了 感觉很厉害哦~~好佩服的哦~~~哦哦哦~~~    常驻进程 An ...

  5. Android_常驻进程(杀不死的进程)

    Android常驻进程,就是要让进程在内存中永远存在,让进程保活,不被杀死.可能这时都会喷,这不是流氓软件吗?刚接触android的时候,我也是认为这是很流氓的做法,可是慢慢发现很多场景(应用),要为 ...

  6. Android中创建杀不死的APP进程(5.0以下)

    所谓的杀不死指的时进程被杀掉后,会自动重启. 即便时在设置里面强行停止后,也能够自动重启. 那么如何自动重启呢?目前想到的有3种方式: 1.使用AlarmManager来定时发intent启动 2.N ...

  7. java多线程解决应用挂死的问题

    java多线程解决应用挂死的问题 参考文章: (1)java多线程解决应用挂死的问题 (2)https://www.cnblogs.com/hushaojun/p/4323808.html (3)ht ...

  8. 杀不死的人狼——我读《人月神话》(四)

    <<==上一节 ===== 四.没有银弹,或人狼杀不死 ===== 人狼这个动物很奇怪,皮肉坚实还是自疗系的,所以要么砍它不动,要么杀它不死.这种动物如同习得(传说中的)金钟罩功夫,刀枪不 ...

  9. 杀不死你的,终将使你更强大

    从4月份到10月底,开发的新功能顺利上线了,运行平稳.这期间除了忙,就是巨忙.除了8月初休假一周回了趟老家,其他时间每天从早拼到晚,周末时间也搭进去不少.但是总归结果是挺好的. 接下来新的任务挑战性更 ...

最新文章

  1. Seleunim 获取文本和标签属性的方法
  2. 手机浏览器推荐_推荐一款手机上最好用的浏览器
  3. lisp医院化验系统_医院智能导视系统
  4. python中列表和集合的区别_python中列表和集合有什么区别
  5. MSSQL日期格式转换函数(使用CONVERT)
  6. halcon学习之基于灰度的特征提取
  7. 太原理工大学计算机课程设计报告,太原理工大学matlab课程设计报告
  8. 读书笔记《TAOCP》 V1 S1.1
  9. c++ int转char*
  10. An Analysis of Scale Invariance in Object Detection – SNIP
  11. 《设计模式》(精华集)
  12. 001、【C语言编程题目】猴子吃桃问题
  13. SSH:The authenticity of host xxx can‘t be established.
  14. python html生成图片_Python将html文件转为图片
  15. ansys em 19 reg_ansysedt.exe错误3221227010 reg_siwave.exe错误:3221227010
  16. linux下 批量替换文件内容
  17. 公众号开发(1) —— natapp 内网穿透
  18. 企业员工活动打卡收集照片、收集视频的小程序
  19. Android图形显示系统(一)
  20. java tcp多人聊天室

热门文章

  1. sap生产工单报工_SAP中单张工单报工完成还能入库吗
  2. 中国中心城市和都市圈发展指数发布:成都天津位次紧跟北上深广,合肥提升最明显,大连下跌幅度较大...
  3. 【图像处理】——Python+opencv实现图像的hu不变矩特征提取(含原理、推导过程、应用、代码等)
  4. 智能手机发布会上云,是“迫不得已”还是“刻不容缓”?
  5. 在线文本转语音工具大全
  6. PHP开发实战权威指南-读书总结
  7. ROS机器人实践---小乌龟画圆
  8. 什么是end-to-end神经网络?
  9. 设备驱动程序安装的重要文件
  10. 鲅鱼圈什么地方有计算机培训学校,2017年营口市鲅鱼圈区中等职业技术专业学校计算机应用(160人)...