Process 长生不老药:找出进程终止的原因

Process 长生不老药:找出进程终止的原因,process,elixir,signals,amqp,gen-server,Process,Elixir,Signals,Amqp,Gen Server,在性能测试期间,我的应用程序因以下日志而死亡: 17:17:28.187 [info] SIGTERM received - shutting down 17:17:28.187 [info] SIGTERM received - shutting down 17:17:28.188 [error] GenServer #PID<0.3707.0> terminating ** (stop) 'stopping because dependent process <0.3

在性能测试期间,我的应用程序因以下日志而死亡:

17:17:28.187 [info]  SIGTERM received - shutting down

17:17:28.187 [info] SIGTERM received - shutting down

17:17:28.188 [error] GenServer #PID<0.3707.0> terminating
** (stop) 'stopping because dependent process <0.3703.0> died: shutdown'
Last message: {:EXIT, #PID<0.3703.0>, :shutdown}
17:17:28.189 [error] gen_server <0.3707.0> terminated with reason: "stopping because dependent process <0.3703.0> died: shutdown"
17:17:28.190 [error] CRASH REPORT Process <0.3707.0> with 0 neighbours exited with reason: "stopping because dependent process <0.3703.0> died: shutdown" in gen_server:handle_common_reply/8 line 751
17:17:28.190 [error] Supervisor {<0.3705.0>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.3706.0>, {amqp_params_network,<<"publicmq-npperfcom1">>,<<"publicmq-npperfcom1">>,<<"/publicmq-npperfcom1">>,...}) at <0.3707.0> exit with reason "stopping because dependent process <0.3703.0> died: shutdown" in context child_terminated
17:17:28.190 [error] Supervisor {<0.3705.0>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.3706.0>, {amqp_params_network,<<"publicmq-npperfcom1">>,<<"publicmq-npperfcom1">>,<<"/publicmq-npperfcom1">>,...}) at <0.3707.0> exit with reason reached_max_restart_intensity in context shutdown
问题:

  • AmqpTransport没有捕获出口。为什么?
  • 在错误日志中,我看到了pids。我可以在那里看到命名进程吗
  • 那个里会发生什么事情使这个过程死亡?我如何进一步调查细节

  • 连接
    amqp
    应用程序的主管作为(
    Connection.open/2
    只需委托)在引擎盖下内部监督启动

    将一个进程链接到两个进程捕获出口是很棘手的,而且通常不是幂等的,这就是to
    进程的原因。监视/1
    底层连接并全速重新启动监视进程


    我记得Andrea Leopardi在相关主题上发表了一些评论,但对我来说总是非常有效。

    嗨,很抱歉在这里发表评论@Aleksei,但你能给我一些线索吗?
    defmodule MyApp.Events.AmqpTransport do
    
      require Logger
      use GenServer
      use AMQP
    
      @restart_delay 2000 # 2 seconds
    
      defmodule State do
        @moduledoc false
        @type t :: %__MODULE__{
          exchange: String.t,
          channel: AMQP.Channel.t,
          routing_key: String.t,
          emitter_id: String.t,
          np_tracking_id: String.t
        }
        defstruct [:exchange, :channel, :routing_key, :emitter_id, :np_tracking_id]
      end
    
      def start_link(_) do
        GenServer.start_link(__MODULE__, [], name: __MODULE__)
      end
    
      def init(_opts) do
        Process.flag(:trap_exit, true)
        send(self(), :connect)
        {:ok, nil}
      end
    
      def handle_info(:connect, _state) do
        username = get_conf(:username)
        password = get_conf(:password)
        host = get_conf(:host)
        port = get_conf(:port)
        vhost = String.replace(get_conf(:vhost), "/", "%2f")
        amqp_url = "amqp://#{username}:#{password}@#{host}:#{port}/#{vhost}"
        Logger.info("amqp transport connecting to #{amqp_url}")
        case Connection.open(amqp_url) do
          {:ok, conn} ->
            Process.link(conn.pid)
            {:ok, chan} = Channel.open(conn)
            :ok = AMQP.Exchange.declare(chan, get_conf(:exchange), :topic, durable: true)
            state = %State{
              exchange: get_conf(:exchange),
              channel: chan,
              routing_key: get_conf(:routing_key),
              emitter_id: Application.fetch_env!(:coups_events, :emitter_id),
              np_tracking_id: Application.fetch_env!(:coups_events, :np_tracking_id),
            }
            {:noreply, state}
          {:error, err} ->
            Logger.error("amqp transport failed\n Err: #{inspect(err)}\n Retrying to connect ...")
            Process.send_after(self(), :connect, @restart_delay)
            {:noreply, nil}
        end
      end
    
      def handle_info({:EXIT, pid, reason}, _state) do
        Logger.error("amqp transport failed with #{inspect(reason)}")
        Process.unlink(pid)
        Process.send_after(self(), :connect, @restart_delay)
        {:noreply, nil}
      end
    
      def handle_cast({:emit, event}, state) do
        # event publishing
        {:noreply, state}
      end
    
      defp get_conf(key) do
        conf = Application.get_env(:events, :amqp)
        conf[key]
      end
    end