Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Erlang в FunBox

Erlang в FunBox

Опыт использования Erlang в компании FunBox

D83b63db79b42978fe35e120550ca180?s=128

Anton Kaliaev

April 24, 2016
Tweet

Transcript

  1. Erlang в FunBox Антон Каляев

  2. Предупреждение • презентация содержит смехуечки • есть некая вероятность, что

    вы не узнаете ничего нового • прослушав этот доклад, вы не научитесь писать на Erlang
  3. О чем пойдет речь? • проблемах, с которыми столкнулись при

    написании приложений, и как мы их решили • какие инструменты используем • как деплоим • как дебажим • личные впечатления от Erlang • Elixir
  4. FunBox • основана в: 2006 г. • сфера деятельности: телеком

    • клиенты: операторы сотовой связи • Erlang разработчиков: ~ 20 • Erlang репозиториев: 39 • Elixir репозиториев: 5
  5. lager

  6. lager app file

  7. lager app file Если синхронный режим включен → таймауты →

    падение приложения exit({timeout, …
  8. lager app file Если синхронный режим выключен → рост потребления

    памяти и OutOfMemoryError в конце https://groups.google.com/forum/#!topic/erlang-russian/ 8xEeffAV8sc (http://bit.ly/hl-logging)
  9. https://github.com/funbox/chokecherry chokecherry _shaper app chokecherry _writer lager file

  10. https://github.com/funbox/chokecherry [ {chokecherry, [ {shaper, [ {timeout, 1000}, {log_queue_capacity, 10000}

    ]} ]} ].
  11. Вывод если что-то может пойти не так, оно обязательно пойдет

    https://ru.wikipedia.org/wiki/Закон_Мерфи
  12. Источник: https://imgur.com/gallery/kWcbEED

  13. Источник: https://imgur.com/gallery/kWcbEED

  14. redis

  15. Latest commit 7218c80 on Aug 19, 2013 (3 years ago)

    https://github.com/basho-labs/hierdis
  16. - X не выглядит так, что его кто-то пилит, 25

    Jan последний PR - 25 Jan для эрланг библиотеки - можно сказать вчера коммитнули. актив девелопмент
  17. 1 LPUSH 100 LPUSH 
 via pipeline Avg time (msc)

    0,00000 175,00000 350,00000 525,00000 700,00000 eredis hierdis eredis ~ 16K ops
 hierdis ~ 28K ops
 redis-benchmark ~ 60K ops 100 соединений | n = 100_000
  18. • Нету read_timeout • Нету автоматического реконнекта https://github.com/basho-labs/hierdis

  19. https://github.com/funbox/hierdis • read_timeout • автоматический реконнект • тесты

  20. планируйте нагрузку https://en.wikipedia.org/wiki/Capacity_management Вывод

  21. Источник: http://joyreactor.com/

  22. Источник: http://joyreactor.com/

  23. пул воркеров

  24. Зачем? • CPU bound (кол-во процессов <= N ядер) •

    Соединения к внешним ресурсам (редис, postgresql) • не тратим время на открытие соединения • проще поддержка (одно место в коде) • проще анализ текущего состояния (кол-во соединений и т.п.) • разделяем задержку от сети
  25. В одну морду 0 t1 t2

  26. В одну морду 1 t1 t2

  27. t2 t1 Пул синяков 0 зачастую t1 намного больше t2

  28. t2 t1 Пул синяков 3 зачастую t1 намного больше t2

  29. • не переподнимает воркеры • нельзя зарепортить плохого воркера •

    минимальная статистика https://github.com/devinus/poolboy
  30. • если падает один воркер, падают все в рамках пула

    • нельзя зарепортить плохого воркера • нормальная статистика https://github.com/inaka/worker_pool http://www.erlang-factory.com/sfbay2015/anthony-molinaro How to Pick a Pool in Erlang without Drowning
  31. Напишем свой пул с блекджеком и шлюхами Вывод

  32. Инструменты • rebar3 • dialyzer • https://github.com/inaka/erlang_guidelines • lhttpc (https://github.com/ferd/lhttpc)

    • ej (https://github.com/seth/ej)
  33. в Erlang техника “а давайте выберем библиотеку с наибольшим количеством

    звездочек на Github не работает” Вывод
  34. Источник: http://popkey.co/m/v7N5-confused-the+lion+king-cartoon-disney

  35. Источник: http://popkey.co/m/v7N5-confused-the+lion+king-cartoon-disney

  36. Как деплоим • Собираем релиз посредством https://github.com/ erlware/relx • Доставляем

    с помощью Capistrano
  37. Как деплоим • нет необходимости ставить Erlang на сервере •

    разные приложения могут использовать разные версии Erlang • собирать релиз нужно на ОС == ОС сервера (из-за C расширений)
  38. - А почему capistrano, А не что- нибудь другое (ansible)

    ? - Потому что и так все работает
  39. важна унификация Вывод

  40. Как мониторим • логи • собственная система сбора метрик и

    состояния приложения и его сущностей (http://riemann.io/ + Kafka) • https://github.com/zaa/entop
  41. Как дебажим • http://erlang.org/doc/man/observer.html • http://erlang.org/doc/apps/observer/ crashdump_ug.html • https://ferd.github.io/recon/ •

    подключаемся к ноде и вперед (process_info(Pid), system_info(procs)) http://www.slideshare.net/motonarola/erlang-data-operation- caveats (http://bit.ly/1Wfhq9k)
  42. None
  43. None
  44. • одна из лучших реализаций акторов (если не лучшая) •

    OTP крут (никто пока не повторил нормально) • простой до жути синтаксис Личные впечатления
  45. handle_messages(Socket) -> receive {tcp,error,closed} -> done; {tcp,Socket,Data} -> gen_tcp:send(Socket,Data), echo:handle_messages(Socket);

    _Other -> unexpected end. http://ferd.ca/on-erlang-s-syntax.html On Erlang's Syntax
  46. • одна из лучших реализаций акторов (если не лучшая) •

    OTP крут (никто пока не повторил нормально) • простой до жути синтаксис • добротная документация и инструментарий (тот, что включен в стандартную поставку) Личные впечатления
  47. “эрланг не гуглят это бесполезно ) я поначалу пытался по

    привычке найти ответы на SO потом смирился и приучил себя читать доки”
  48. Личные впечатления • ошибки непонятные

  49. $> make make: *** [deps] Ошибка 1

  50. $> make make: *** [deps] Ошибка 1

  51. "всего через год упорных тренировок ты научишься по слову error

    различать не меньше 25 видов ошибки и додумывать трейс на ходу"
  52. Личные впечатления • ошибки непонятные • сложно писать тесты

  53. сложно писать тесты из-за • отсутствия DI в нашем коде

    • необходимости запускать зависимые компоненты • дополнительного coupling-а из-за spawn-ов с внешними обращениями.
  54. print_time() -> Time = erlang:system_time(seconds), io:format("~p", [Time]). DI в Erlang?

  55. -module(system). -export([time/0, print/1]). time() -> erlang:system_time(seconds). print(Str) -> io:format(Str). print_time(System)

    -> Time = System:time(), System:print(io_lib:format("~p", [Time])).
  56. DI в Erlang https://github.com/funbox/doppler

  57. print_time_test(_Config) -> PredefinedTime = 1459246205, System = doppler:start(undefined), doppler:def(System, time,

    fun(State) -> {PredefinedTime, State} end), doppler:def(System, print, fun(_State, Str) -> NewState = Str, {ok, NewState} end), print_time(System), PrintedTime = doppler:state(System), doppler:stop(System). "1459246205" = lists:flatten(PrintedTime).
  58. Личные впечатления • ошибки непонятные • сложно писать тесты •

    много лишнего кода в случае с OTP • не всегда есть готовые библиотеки → возможность написать свое
  59. Elixir • удобные макросы • синтаксический сахар • протоколы из

    Clojure • много возможностей → больше ответственность args = %{"req" => req, “resp” => nil} |> authorize |> decode_req |> validate_body
  60. Мы узнали, что • все что угодно может пойти не

    так, и надо “бороться” с этим (тесты, статические анализаторы, code review, game days) • нужно планировать нагрузку • важна унификация • важны метрики и мониторинг (логи никто не смотрит)
  61. Источник: https://www.flickr.com/photos/usnationalarchives/8675982016

  62. http://spawnedshelter.com/

  63. Вопросы? https://twitter.com/AntonKalyaev http://homeonrails.com/