iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >技术分享 | wrapper 和 dble 之间的那些事
  • 870
分享到

技术分享 | wrapper 和 dble 之间的那些事

技术分享|wrapperdble之间的那些事 2016-05-31 12:05:44 870人浏览 绘本
摘要

作者:鲍凤其 背景 在即将发布的 dble 2.19.09.0 版本中,我们将升级 dble 中 jsW 的版本,将 JSW 版本从 3.2.3 版本升级到 3.5.41 版本。升级的原因在于我们在使用过程中发现了几个比较严重的 bug

作者:鲍凤其

背景

在即将发布的 dble 2.19.09.0 版本中,我们将升级 dble 中 jsW 的版本,将 JSW 版本从 3.2.3 版本升级到 3.5.41 版本。升级的原因在于我们在使用过程中发现了几个比较严重的 bug,这几个 bug 会导致 dble 的守护进程异常退出和 hang 死。hang 死的案例可参考 issue:https://GitHub.com/actiontech/dble/issues/1402。看到这里的同学,有些同学可能对 JSW 可能还不太了解,我这里先简单介绍一下。

JSW 介绍

JSW 是 Java Service Wrapper 的缩写,也就是 dble 中通常所说的 wrapper。JSW 可用于将 Java 程序包装成一个后台服务运行。除此以外,JSW 还可以在你的 Java 程序宕掉以后,自动把服务拉起。相当于提供了一个守护进程的功能。它的一个主要目标就是,单点服务做到尽可能高可靠,宕掉后第一时间帮你把它拉起来!这样,能够最大化降低运维成本。

JSW 除了 Window 和 linux 还支持其他平台,社区中经常听到有同学问 dble 有 windows 版本此类的问题。在这里我想说可以有,但是 dble 官方只提供了 Linux 版,Windows 版本就需要各位同学自己动手编译打包了。Java Service Wrapper 分为社区版和企业版,企业版的功能更加强大,但是要收费。目前一般使用的都是社区版,免费并且开源

JSW 如何守护 dble

概述

要了解上面的 bug,我们需要先了解一下 JSW 的整体流程。下面我们先从整体来看一下 dble 和 JSW 守护进程的关系,如下图:

dble 在启动后,如果通过系统命令查看后台进程,会发现其实后台运行了两个进程。

  • 其中之一是 JSW 守护进程,下面直接叫做守护进程。它会守护我们的 dble 程序,挂掉后立马拉起。守护进程会开启一个 ServerSocket 端口,通过这个端口守护进程可以对 wrapper 下发指令,比如 ping,重启 dble 等等。
  • 另一个就是 Java 程序的进程了。JSW 会在 dble 程序之外包装一层 wrapper,这个 wrapper 的主要作用有两个:一是监听端口,处理守护进程发送来的指令;二是在合适的时机加载 dble。
  • 这两个进程是父子进程的关系,守护线程是父进程,Java 程序是其子进程。在上面的图中,其实漏掉了其中最重要的部分,那就是守护进程对 JVM 状态的处理和变更,这个会在下面详细介绍。

守护进程启动过程

守护进程的启动大致我大致分为两个阶段:1. 初始化阶段,2. 状态和事件处理阶段。

初始化阶段

  1. 守护进程内部会初始化 Java 程序状态的变量,比如记录当前 Java 程序是停止,正在启动还是运行等。初始时状态即为停止状态即下文中的 down。
  2. 注册信号事件处理函数,其中特别需要注意的是注册了 SIGCHLD 这个信号的处理函数。这个信号是当子进程退出时,它会向父进程发送 SIGCHLD 信号。
  3. 开启一个 ServerSocket 监听端口用于 wrapper 和守护进程通信。

状态和事件处理阶段

在此阶段,守护进程不停的轮询监听端口是否有事件达到,根据 Java 程序的状态执行不同的操作,以此反复。下面详细描述下过程,可对照下面的图来看。

  • 在守护进程启动之初,内部 Java 程序的状态为 down,若是初次启动,此时守护进程会直接将状态置为 lauch。
  • 在 lauch 状态下,守护进程调用 Linux fork 系统调用创建一个 Java 的子进程后将状态置为 lauching。
  • 在 lauching 状态下,守护进程会一直等待 Java 程序启动成功的事件达到,若在超时时间内没有等到,则会将子进程杀死并重启。一旦等到启动成功事件,状态就会被守护进程置为 lauched。
  • 在 lauched 状态下,守护进程对 wrapper 下发 start 命令,让 wrapper 加载 dble 的启动类并运行。命令被下发之后,状态被置为 starting,守护进程等待 dble 启动完成。与启动 Java 程序一样,这里也有个超时时间。
  • 一旦dble加载成功,状态即变为 started,此时 dble 在正常的运行状态。

  • 在运行状态期间,守护线程会定期向 wrapper 发送 ping 包,若 wrapper 按时返回 ping 的 response 包,则守护进程则认为它正常。

异常处理

在这里我们假设 JVM 由于某种原因 hang 了一段时间。我们来看下守护进程是如何处理的。一旦 JVM hang 住了,则守护进程的 ping 命令不能及时返回,此时守护进程将状态置为 killing 并准备杀死 Java 程序。守护进程调用系统调用 kill 向子进程发送 SIGKILL 信号,发送信号之后,守护进程会等待 0.5s 以确保这期间子进程被回收和状态的正确性。

问题分析

到这里我们已经介绍完 JWS 的启动流程和当 Java 程序异常时的处理。现在我们来看下之前我们遇到的问题:

  1. issue:Https://github.com/actiontech/dble/issues/1402

在最后的异常处理那节,从 killing 到 down 状态的转换过程中,主线程内会打印 log 来提示用户。打印日志前需要获取日志,但是此时主线程接收到 SIGCHLD 信号并回调了该信号的处理函数,在处理函数中也需要打印日志,此时也去获取日志锁,但是此锁是不可重入锁,因此发生死锁,导致守护进程主线程 hang 死。在 JWS 新的版本中,打印日志的操作会放在单独的线程中处理来解决这个问题。

  1. 守护进程异常退出

这个问题是一系列问题的总成,但是根本原因是相同的,还是在于 SIGCHLD 信号。在最后一个异常处理那个图中 SIGCHLD 信号的返回我画了两个。正常情况下是在守护进程等待 Java 子进程被回收的过程中收到该信号。但是如果 Java 子进程资源回收超过 0.5s 时,守护进程已经往下执行准备重启 Java 程序了,此时再回调到 SIGCHLD 信号处理函数,会导致状态异常而退出。新版本在这方面做出了一些改善。

总结

上面我对 dble 中使用的 JWS 从启动流程和错误处理两个方面做了简单的介绍,在最后对平常工作中遇到的 bug 进行了探究,希望对你们有帮助。

您可能感兴趣的文档:

--结束END--

本文标题: 技术分享 | wrapper 和 dble 之间的那些事

本文链接: https://www.lsjlt.com/news/2935.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么显示表的字段
    如何显示 oracle 表的字段 在 Oracle 数据库中,可以使用 DESC 命令显示表的字段。 语法: DESC table_name 参数: table_name:要显示字段的表...
    99+
    2024-05-14
    oracle
  • oracle怎么看所有的表
    在 oracle 数据库中查看所有表的步骤:连接到数据库运行查询:select table_name from user_tables; 如何使用 Oracle 查看所有表 ...
    99+
    2024-05-14
    oracle
  • oracle怎么显示行数
    如何使用 oracle 显示行数 在 Oracle 数据库中,有两种主要方法可以显示行数: 1. 使用 COUNT 函数 SELECT COUNT(*) FROM table_n...
    99+
    2024-05-14
    oracle
  • oracle怎么显示百分比
    oracle中显示百分比的方法有:使用百分号“%”;使用to_char()函数;使用format()函数(oracle 18c及更高版本);创建自定义函数。 Oracle 显...
    99+
    2024-05-14
    oracle
  • oracle怎么删除列
    oracle 中删除列的方法有两种:1)使用 alter table table_name drop column column_name 语句;2)使用 drop colum...
    99+
    2024-05-14
    oracle
  • sql怎么查看表的索引
    通过查询系统表,可以获取表的索引信息,包括索引名称、是否唯一、索引类型、索引列和行数。常用系统表有:mysql 的 information_schema.statistics、postg...
    99+
    2024-05-14
    mysql oracle
  • sql怎么查看索引
    您可以使用 sql 通过以下方法查看索引:show indexes 语句:显示表中定义的索引列表及其信息。explain 语句:显示查询计划,其中包含用于执行查询的索引。informat...
    99+
    2024-05-14
  • sql怎么查看存储过程
    如何查看 sql 存储过程的源代码:使用 show create procedure 语句直接获取创建脚本。查询 information_schema.routines 表的 routi...
    99+
    2024-05-14
  • sql怎么查看视图表
    要查看视图表,可以使用以下步骤:使用 select 语句获取视图中的数据。使用 desc 语句查看视图的架构。使用 explain 语句分析视图的执行计划。使用 dbms 提供...
    99+
    2024-05-14
    oracle python
  • sql怎么查看创建的视图
    可以通过sql查询查看已创建的视图,具体步骤包括:连接到数据库并执行查询select * from information_schema.views;查询结果将显示视图的名称、...
    99+
    2024-05-14
    mysql
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作