squbs-3.运行时的生命周期和API

原文地址:Runtime Lifecycle & API

生命周期是一个真正需要关注的基础。应用程序很少接触或感知到系统的生命周期。系统组件、管理员控制台、应用组建、actors会经过很长一段时间的初始化,并且为了traffic了解系统生命周期,系统必须在可用前完全初始化。后面包括诸如控制器(controller)、缓存加载器(cache loaders)、设备初始化器等等。

squbs运行时暴露以下生命周期状态:

  • Starting - squbs启动时的状态

  • Initializing - Unicomplex已启动. Services启动中. Cubes启动中. 等待初始化报告.

  • Active - 准备工作和执行服务调用

  • Failed - Cube可能没有启动

  • Stopping - Unicomplex收到GracefulStop消息 停止cube, actor, 和未绑定的service.

  • Stopped - 运行中的squbs已停止. Unicomplex终止. ActorSystem终止.

生命周期钩子(Hooks)

大多数的actor不关心他们什么时候启动或者停止。然而,他们可能为同一类actor,在他们达到接收一般trafiic状态前需要初始化。同样的,一些actor同样关心在关闭前被通知到,以允许在发送他们毒药丸(poison pill)之前适当的清理。生命周期的钩子存在就是为了这个原因。

你可以通过发送ObtainLifecycleEvents(状态: LifecycleState*)Unicomplex()将你actor注册到生命周期事件中。一旦系统的状态改变,你的actor将会接收到生命周期状态。

你同样可以通过向Unicomplex()发送SystemState来获得当前的系统状态。你将会获得以上其中一种状态的回复。所有的系统状态对象继承自org.squbs.unicomplex.LifecycleState , 并且所有都属于 org.squbs.unicomplex 包,见下列表:

  • case object Starting extends LifecycleState
  • case object Initializing extends LifecycleState
  • case object Active extends LifecycleState
  • case object Failed extends LifecycleState
  • case object Stopping extends LifecycleState
  • case object Stopped extends LifecycleState

启动钩子(Hooks)

一个actor希望参与初始化时必须指出,于是在squbs的元数据 META-INF/squbs-meta.conf如下:

cube-name = org.squbs.bottlecube
cube-version = "0.0.2"
squbs-actors = [
  {
    class-name = org.squbs.bottlecube.LyricsDispatcher
    name = lyrics
    with-router = false  # Optional, defaults to false
    init-required = true # 告知squbs我们需要在发送所有已经启动前等待该actor
  }

任何设置init-required为true的actor需要发送一个已完成(报告)消息至cube管理者,即这些well known actor的父actor。这个报告是Try[Option[String]]类型,允许actor报告初始化成功和失败(可能携带异常)。一旦所有的cube成功的初始化完成,运行中的squbs转变至Active 状态。这同样表示每个设置init-required为true的actor提交了初始化成功的报告。如果任何cube报告一个初始化失败的报告,运行中的squbs会以一个Failed状态取而代之。

关闭钩子(Hooks)

停止Actors

特性org.squbs.lifecycle.GracefulStopHelper让用户在他们自己的代码中实现优雅的关闭actor。你可以按如下的方式在你的actor中混合(mix)这个特性(trait):

scala
class MyActor extends Actor with GracefulStopHelper {
    ...
}

这个特性提供了一些帮助方法来支持在squbs框架中优雅的关闭actor

StopTimeout

scala
  /**
   * 优雅的关闭actor的超时时间
   * Override it for customized timeout and it will be registered to the reaper
   * Default to 5 seconds
   * @return Duration
   */
  def stopTimeout: FiniteDuration =
    FiniteDuration(config.getMilliseconds("default-stop-timeout"), TimeUnit.MILLISECONDS)

你可以复写这个方法来指出优雅的关闭actor所需要执行的大概时间。一旦actor启动,它将通过 StopTimeout(stopTimeout) 消息将stopTimeout发送至它们的父节点。如果你关心它,你可以在父actor中处理这条信息。

如果你混合(mix)这个特性在你的actor代码中,你应该在你的receive 方法中接收GracefulStop消息,因为只有在这种情况下你可以勾住你的代码来执行一个优雅的停止(你无法向PoisonPill添加自定义行为)。管理者将仅仅传播 GracefulStop 消息至他们那些混合了GracefulStopHelper特性的子节点。子节点的实现应该在他们的receive块中处理这个消息。

我们还提供了以下两个默认策略:

  /**
   * Default gracefully stop behavior for leaf level actors
   * (Actors only receive the msg as input and send out a result)
   * towards the `GracefulStop` message
   *
   * Simply stop itself
   */
  protected final def defaultLeafActorStop: Unit = {
    log.debug(s"Stopping self")
    context stop self
  }
  /**
   * Default gracefully stop behavior for middle level actors
   * (Actors rely on the results of other actors to finish their tasks)
   * towards the `GracefulStop` message
   *
   * Simply propagate the `GracefulStop` message to all actors
   * that should be stop ahead of this actor
   *
   * If some actors failed to respond to the `GracefulStop` message,
   * It will send `PoisonPill` again
   *
   * After all the actors get terminated it stops itself
   */
  protected final def defaultMidActorStop(dependencies: Iterable[ActorRef],
                                          timeout: FiniteDuration = stopTimeout / 2): Unit = {

    def stopDependencies(msg: Any) = {
      Future.sequence(dependencies.map(gracefulStop(_, timeout, msg)))
    }

    stopDependencies(GracefulStop).onComplete({
      // all dependencies has been terminated successfully
      // stop self
      case Success(result) => log.debug(s"All dependencies was stopped. Stopping self")
        if (context != null) context stop self

      // some dependencies are not terminated in the timeout
      // send them PoisonPill again
      case Failure(e) => log.warning(s"Graceful stop failed with $e in $timeout")
        stopDependencies(PoisonPill).onComplete(_ => {
          // don't care at this time
          if (context != null) context stop self
        })
    })
  }

停止Squbs插件

通过复写org.squbs.lifecycle.ExtensionLifecycle中的shutdown()方法,你可以添加在扩展关闭中添加个性化的行为。需要指出的是这个方法在所有安装好的扩展中将在actor系统停止后执行。如果任何扩展在关闭的时候抛出了异常,JVM会以-1退出。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容