Elixir의 WebSocket을 사용한 실시간 대시보드

원래 게시됨https://darnahsan.medium.com/real-time-dashboard-with-websocket-in-elixir-f4bad1a71ba7 2020년 4월 17일 게시됨

모바일 팀의 QA를 지원하기 위해 주말 동안 Elixir 프로젝트로 시작한 것입니다. UltronEx은 엘릭서를 포함하여 우리 스택에 많은 새로운 것을 도입한 놀이터로 성장했습니다. QA에 대한 추가 지원을 제공하기 위해 구축된 프로젝트의 초기 설계는 stream messages directly into Slack이었습니다. 통화 속도가 제한되는 Slack 쪽에서 곧 한계에 도달했습니다. 이로 인해 QA가 작업할 수 있도록 수천 개의 메시지가 Slack으로 전달되지 않았습니다. 우리는 프로젝트 이후로 10,000회 이상 비율이 제한된 수백 가지 이벤트 유형을 받고 있었습니다. 한 가지 방법은 재시도하는 것이었지만 스트림 시스템에서는 메시지를 다시 대기열에 넣기만 하면 실패하고 메시지가 지연되거나 순서가 어긋나면 값이 손실됩니다. 속도 제한이 얼마나 나쁜지는 아래 이미지에서 알 수 있습니다.



시스템을 모니터링하는 재미있는 방법으로 얼마나 많은 메시지가 처리되었는지, 얼마나 많은 첨부 파일이 다운로드되고 일치하는지 스캔되었는지, 서비스를 사용하여 얼마나 많은 메시지가 전송되었는지에 대한 통계를 유지하기 시작했습니다. 이 모든 것은 가치를 제공할 뿐만 아니라 강력한 기술로서 Elixir의 능력을 평가하기 위한 프로젝트로 시작되었음을 명심하십시오. 슬랙 봇과 함께 API와 이제 WebSocket을 사용하여 구축된 실시간 대시보드는 리소스 제한에서 변경된 사항이 없습니다. 여전히 클라우드의 1vCPU 2GB RAM 인스턴스에서 실행됩니다(애플리케이션 컨테이너 메모리 제한은 350MB로만 설정됨). 이 글을 쓰는 시점에서 Slack에서 130만 개 이상의 메시지를 읽고, 120만 개 이상의 첨부 파일을 다운로드하고 스캔했으며, 다른 서비스의 API 엔드포인트를 사용하여 약 100만 개의 메시지를 Slack으로 보냈습니다.

통계 카운터

대시보드는 성공, 위험, 경고 메시지를 표시하는 3개의 카테고리로 나뉩니다. 프런트엔드 작업을 한 지 오래되었습니다. 마지막으로 클라이언트 측 Bootstrap에서 CSS 및 JS로 작업했습니다. 그래서 나의 첫 번째 직감은 Bootstrap을 위해 Google에 대한 것이었고 놀랍게도 활발하고 잘 작동하며 jQuery를 계속 유지하고 있습니다. 약간의 부트스트랩 스타일로 대시보드가 ​​만족스러워 보였습니다.



대시보드의 성능은 부드럽고 안정적이었습니다. 내부적으로 우리는 단일 장치에서 눈에 띄는 지연 없이 최대 30명의 사용자에게 테스트했으며 응용 프로그램에는 평균 165MB만 사용되는 350MB의 메모리만 할당됩니다. 이는 메시지가 대시보드로 전송되는 단방향 커뮤니케이션입니다. Server-Sent Events가 사용 사례로 충분했을 것이라고 주장할 수 있지만 이것은 범위를 확장하는 프로젝트이므로 나중에 양방향으로 업그레이드하는 것은 노력할 가치가 없는 것 같습니다.

서버 측에서 메시지 푸시를 처리하는 코드는 Elixir 덕분에 간결하고 읽기 쉽습니다.


아산다르 / 울트로넥스


Elixir로 작성된 RTM Slack 봇





Github에서 개인 Gitlab 저장소의 amirror

OpenSource 이니셔티브에 따라 내 프로젝트를 고려하고 APM용 무료 계정을 설정한 AppSignal에 감사드립니다. 이것이 다른 사람들이 제품을 사용하는 데 도움이 되기를 바랍니다. Elixir 모니터링에 사용할 수 있는 가장 포괄적인 도구 중 하나입니다.


UltronEx - Elixir의 Ultron


첫 번째 작성 시도elixir 코드가 그다지 비약적이지 않을 수 있습니다. 이것은 제가 몇 년 전에 루비에서 했던 슬랙 봇을 다시 쓴 것입니다. Blog post 결과 elixirruby를 100% 능가하는 결과를 보여줍니다.
command(s)
      --> help #list the command list
      --> mute/talk #TODO implement later
      --> xkcd #shows a random xkcd comic
      --> xkcd <comic no> #shows xkcd comic no
      --> gif #shows random gif
      --> gif <category> #show a random gif from the category
      --> quote #shares a quote
      --> forward <term> #sets up msg forwarding for the


View on GitHub


defmodule Ultronex.Server.Websocket.SocketHandler do
  use Appsignal.Instrumentation.Decorators

  @behaviour :cowboy_websocket

  def init(request, _state) do
    state = %{registry_key: request.path}
    {:cowboy_websocket, request, state}
  end

  def websocket_init(state) do
    Registry.UltronexApp
    |> Registry.register(state.registry_key, {})

    {:ok, state}
  end

  @decorate transaction()
  def websocket_handle({:text, json}, state) do
    payload = Jason.decode!(json)
    message = payload["data"]["message"]
    websocket_send_msg(message, state)
    {:reply, {:text, message}, state}
  end

  @decorate transaction()
  def websocket_info(info, state) do
    {:reply, {:text, info}, state}
  end

  @decorate transaction()
  def websocket_send_msg(message, state) do
    Registry.UltronexApp
    |> Registry.dispatch(state.registry_key, fn entries ->
      for {pid, _} <- entries do
        if pid != self() do
          Process.send(pid, message, [])
        end
      end
    end)
  end
end

실시간 웹 앱은 현재 트렌드인 것으로 보이며 Phoenix Live 보기를 통해 차세대 혁명이 될 수 있습니다. Ruby on Rails가 웹 개발을 현대화한 후 Elixir와 Phoenix가 될 것입니다.

좋은 웹페이지 즐겨찾기