V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
bmpidev2019
V2EX  ›  分享创造

用 Elixir 重写 WebRTC 语音聊天室,自带集群扩容

  •  3
     
  •   bmpidev2019 ·
    madawei2699 · 2022-10-17 23:35:47 +08:00 · 4501 次点击
    这是一个创建于 550 天前的主题,其中的信息可能已经有所发展或是发生改变。

    之前写过一个帖子在这里: https://v2ex.com/t/828646

    Repo: https://github.com/madawei2699/free4chat

    最近花了一周时间重写了 http://free4.chat ,加入了文字聊天功能(花费 1 天时间)。新的技术栈:

    • 后端:Elixir + Phoenix
    • 前端:Nexitjs + Tailwindcss + RxJS

    后端用 Elixir/Erlang 的好处是自带集群功能,目前两台服务器组建集群,客户端随机负载均衡策略选择某个服务器做接入,同一房间的用户可以分布在不同节点的服务器,相比之前 Go 语言的版本,有了极大的 Scale 能力。Elixir/Erlang 还有极其强大的可观测能力,可以在运行时 remote 到 VM 中查看 process 的状态。

    前端用 NextJS 和 Tailwindcss 的好处在于大量的组件可以拿来即用,Tailwindcss 相比之前一些 UI 库好用到爆,可以让我这种前端小白在短时间糊出来还不错的页面,强烈推荐! RxJS 做组件间的通信工具,感觉比 Redux 要简单多了,Redux 是有点复杂。

    DevOps 的话,后端部署是用 GitHub Actions 将 Docker 容器远程部署在 AWS EC2 上。前端是部署在 @Cloudflare Pages ,后端 API 服务器没有用 Nginx ,通过 iptables 将 80/443 端口流量转发至容器监听的端口,HTTPS/TLS 是由 @Cloudflare 自动配置的。

    监控的话就用 Elixir hoenix 的 LiveDashboard 了。

    29 条回复    2022-11-30 16:49:36 +08:00
    Aloento
        1
    Aloento  
       2022-10-17 23:47:24 +08:00
    这前端太好看了吧
    DeWjjj
        2
    DeWjjj  
       2022-10-18 08:26:51 +08:00
    学习了,非常有用。
    aeli
        3
    aeli  
       2022-10-18 09:30:22 +08:00
    为什么会想用 ELixir 重写,而不是继续改进 Golang 版本?
    bmpidev2019
        4
    bmpidev2019  
    OP
       2022-10-18 09:33:08 +08:00 via iPhone   ❤️ 1
    @aeli 不喜欢 go 的语法,开发效率没有 elixir 高,更重要的是因为 turn 单体的约束,很难搞集群,但在 erlang/otp 的加持下,集群是个自带的功能。当然 go 的库更多一些,elixir 可能需要自己封装一些库,不过也不是啥难事
    maggch97
        5
    maggch97  
       2022-10-18 10:41:22 +08:00 via Android
    @bmpidev2019 turn 和 kraken 是分开的吧,只需要在 kraken 的 turn 接口多配置几个 coturn 返回就行了
    bmpidev2019
        6
    bmpidev2019  
    OP
       2022-10-18 11:14:23 +08:00 via iPhone
    @maggch97 这也算个方法,但不是我期望的 scale ,这种方法也解决不了同一个房间用户分布在多个节点上的问题,但这些问题在 elixir 版本中都已经解决了,相比 go 有着更少的内存使用(默认 80MB 的内存开销),erlang 的基于 process 的内存回收效率也比 go 的 gc 要高效(之前 go 版本用户几十人时可能会达到几百 MB 的开销,用户降低时内存并没有随之回收,导致我有时候不得不重启服务器,服务器 1G 内存)。还有就是 go 的 debug 比较复杂,这和 webrtc 本身协议众多也有关系,但 elixir 我直接 remote 到 vm 上去看 process 的信息,看状态,发消息,这种 debug 太方便了。
    cgpiao
        7
    cgpiao  
       2022-10-19 11:23:45 +08:00 via iPhone
    erlang otp 的 scale 能力是相当的令人印象深刻。
    elixir 优点和缺点都在于 erlang ,可以不用自己创造基磐,但你不会用 erlang 的话 elixir 也很难玩转。学习相当需要时间和锻炼。
    shawndev
        8
    shawndev  
       2022-10-19 11:51:28 +08:00
    好看
    bmpidev2019
        9
    bmpidev2019  
    OP
       2022-10-19 15:50:10 +08:00 via iPhone
    @cgpiao 门槛还是有的,但 elixir 可以直接调用 erlang-otp 的库,一般不需要造轮子,顶多封装下。
    zealinux
        10
    zealinux  
       2022-10-20 19:53:02 +08:00
    @bmpidev2019

    你说的“Elixir/Erlang 的好处是 [自带集群功能] ”,这个是什么意思?

    有关键字吗?我去搜一下什么原理。
    chancat
        11
    chancat  
       2022-10-20 21:28:57 +08:00 via Android
    额。。这个项目,有哪些场景会用到吗?
    bmpidev2019
        12
    bmpidev2019  
    OP
       2022-10-20 22:24:04 +08:00 via iPhone
    @zealinux 直接看 erlang 的介绍就知道了
    moose123
        13
    moose123  
       2022-10-21 10:33:52 +08:00
    这个界面是 elixir 的 phoenix 自带的,这方面开箱即用确实爽,elixir 擅长的还是 message 方面的应用,不过我们也拿来做其他的,如多人 h5 页游,很多东西也是开箱即用,之前也想过用 golang 做,看了下要处理太多 ws 的东西,还是用 phonex 搞吧,这样只关心业务,不用担心 scale ,并发等问题....
    bmpidev2019
        14
    bmpidev2019  
    OP
       2022-10-21 14:22:21 +08:00 via iPhone
    @moose123 如果一个应用最终要关系 scale 和容错的问题,那用 elixir 搞肯定是一个好的选择,如果用其他语言,scale 用 k8s 之类方案可以搞,但总是带来一定复杂度,甚至在细粒度的控制方面是不如 elixir/erlang-otp 的。还有如果要做实时通信类的应用,elixir 也不错,phoenix 自带 websocket 。公司项目技术栈有很多考量,但个人项目用 elixir 搞是很爽的。
    moose123
        15
    moose123  
       2022-10-21 21:13:22 +08:00   ❤️ 1
    @bmpidev2019 elixir+phoenix 适合一人一公司的技术栈,提供一些开箱即用的东西,可以快速把东西搞出来,我拿来搞 crm,cms,电商这些....
    bmpidev2019
        16
    bmpidev2019  
    OP
       2022-10-22 07:29:03 +08:00 via iPhone
    @moose123 相当于实时通信 Web ( real-time )的 Python+Django 组合,迅速出活,实时交互。所以 free4.chat 这个项目我设计了三大 feature:Real-time Communicating ,基于语音的实时聊天; Real-time Collaborating:基于白板的实时协作; Real-time Contesting:与其他人实时比赛,玩一些基于语音的游戏,比如可以通过语音与他人练习口语。这一切的底层都是实时与自动扩容,这些都得益于 Elixir/Erlang-otp 的支持,让开发效率变得无比快捷,服务器资源要求也很低。
    xieren58
        17
    xieren58  
       2022-10-22 12:10:44 +08:00
    rust 走起.
    bmpidev2019
        18
    bmpidev2019  
    OP
       2022-10-22 15:04:22 +08:00 via iPhone
    @xieren58 用 rust 搞明年也上线不了😂
    moose123
        19
    moose123  
       2022-10-23 11:51:17 +08:00
    @bmpidev2019 选用 elixir 其实就是快速出东西,phoenix+ecto 都很方便,再加上 erlang 的稳定性,在创业前中期完全够用了,唯一的问题就是人员跟不上,基本上需要自己培养。
    bmpidev2019
        20
    bmpidev2019  
    OP
       2022-10-23 12:55:50 +08:00 via iPhone
    @moose123 小众语言招聘难是个绊脚石,只能招学习能力好的培养了,好在入门也很快,起码比 rust 快多了😂另外工作机会少也导致大家不愿意投资这个技术,作为 side project 倒很好,出活快。
    moose123
        21
    moose123  
       2022-10-24 14:26:05 +08:00
    @bmpidev2019 Elixir 更适合创业者、小团队,如果想学习一门语言养家糊口的,自然会选择 java 这些了,就是因为有更多的选择才好玩,现在微服务这么流行,某些服务用 Elixir ,某些服务用 java 也没啥问题。
    bmpidev2019
        22
    bmpidev2019  
    OP
       2022-10-24 21:18:23 +08:00 via iPhone
    @moose123 团队用完 elixir 就回不去了😄
    moose123
        23
    moose123  
       2022-10-27 15:37:35 +08:00
    @bmpidev2019 你们集群有多少个节点啊?
    bmpidev2019
        24
    bmpidev2019  
    OP
       2022-10-27 16:04:56 +08:00 via iPhone
    @moose123 我现在就 2 个
    maggch97
        25
    maggch97  
       2022-11-26 12:44:42 +08:00   ❤️ 1
    @bmpidev2019 挖个坟,我当时很怀疑比较更接近底层的 Golang 怎么会有更差的内存占用。直到我最近也部署了 kraken 的服务,遇到了一样的内存占用问题。

    我看了一下代码。这不是 Golang 的问题,而是 kraken 本身实现问题。它的所有房间信息以及所有用户连接的资源并没有被正确释放,所有断开的连接仅仅被标记了一个 delete 的 id 。

    issue: https://github.com/MixinNetwork/kraken/issues/32
    bmpidev2019
        26
    bmpidev2019  
    OP
       2022-11-26 14:33:08 +08:00 via iPhone
    @maggch97 应该不是 golang 的问题,是 sfu 实现的问题,pion 本身应该也 OK ,不过调试真困难是真的😅
    maggch97
        27
    maggch97  
       2022-11-29 23:00:51 +08:00
    @bmpidev2019 更新一下,使用修复后的代码,36 个活跃用户服务器占用 66M ,内存泄漏的问题也没有了。
    bmpidev2019
        28
    bmpidev2019  
    OP
       2022-11-30 16:01:25 +08:00 via iPhone
    @maggch97 这个开销才正常一些👍但你怎么统计实时用户的?
    maggch97
        29
    maggch97  
       2022-11-30 16:49:36 +08:00 via Android
    @bmpidev2019 rpc 里面有一个 info method 的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   911 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:09 · PVG 06:09 · LAX 15:09 · JFK 18:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.