zoukankan      html  css  js  c++  java
  • erlang 健壮性

      erlang 提供了简单易用的并发编程模型,基本不需要再考虑多线程并发问题。但实际应用中并不是那么的完美,很多地方需要注意,就算标准库也有不少问题。很多在多线程编程中很多很容易解决的事情,在erlang中是那么的蛋疼和无奈。erlang专注于自己擅长领域,本身十分健壮,强大的shell,分布式特性,让我们更专注于业务实现;但因缺乏文档、足够的经验资料,初入时很容易用出各种问题。

      1.进程message_queue_len

       很多问题归根结底都处在message_queue_len 太长,每个进程都带着一个buffer 无限的queue,嗯,来着不拒。

       queue 因为各种各样原因消费不过来,经典的gen_server port 调用receive_match 问题, 越来越长,越长越慢,OOM...

       进程数高,数十万百万级别时更容易出问题

       列举解决方案:

       - 日志组件

        errror_logger 很坑,使用lager 关闭crash_log, sync_on none, file_backend 只能用于测试环境,使用自定义scribe_backend 将日志通过网络收集到中心日志服务器。

       - dns 解析

        一次erlang 节点CPU严重波动排查

      - gen_server

        改用rabbitmq-server 提供的gen_server2

      

      2. 热点进程

        不像多线程模型,一个执行流内路径都由一个线程完成,而是分布到多个进程,而一个进程最多使用一个核心。

        一个进程活儿干不过来,那就使用多个进程一组来完成,要做分发(这个很蛋疼啊)。能用ets 就用ets,不行只能分组了。

        -   进程优先级调高

          process_flag(priority, high)

        -   discard

          process_info(self(), message_queue_len) 控制流量,必要的时候discard 部分

        -  合包

          消息传递是有成本的,receive {'gen_cast', Msg} 多次合包处理也是提高并发好办法

        - supervisor

         此进程也容易造成热点,必要proc_lib:spawn 方式,有些场景去掉supervisor 节省内存同时去除热点

       3. 公平调度

        erlang 是公平调度的,尤其在高进程数节点内,热点进程设置高优先级是必须的,线上使用依赖库很多都有此改动。

        否则会出现,CPU 很低,但是业务处理不过来,很多call timeout 问题

        - 避免使用rpc:call

           erlang 虚机crash 提到,使用自己的gen_call 实现,OTP rpc 使用rex 单进程提供服务,进程优先级无法调整,请求量稍微一高就莫名的timeout。

        - swt low

         erlang 内部统计reductions 对于bif不准确,可能会存在cpu 很低,但业务依然timeout,提高调度器唤醒敏感度

      4. 流控

       因为消息队列原因,来着不拒,虚拟crash 大多因为 OOM,所以流控非常有必要

       - message_queue_len 

        过长时,discard 策略,或server busy 应答

      -  memory

        erlang:memory(total)/ SysMem(参考rabbit_memory_monitor) > 70% 后开始拒绝请求

        为啥是70%呢?erlang:memory(total) 为实际使用内存,不保留无法使用的碎片,70% 很保守,必要应考试60%以下

       

      5. 系统日志

       一旦出现OOM,crash_dump 是无法生成的,shell也基本进入无望,所以必要的系统日志提供事后分析

         erlang 没有提供进程队列阀值通知机制,那么只能是定时轮了

        根据进程数量: registered() < release_handler_1:get_supervised_procs() < processes()  选取不同频率定时check,配合报警。

  • 相关阅读:
    使用signalr不使用连接服务器和前台的js的方法
    signalR client属性中的大致方法
    创建一个简单的signalr项目
    设计模式之工厂模式
    VS2012下没有ADO.NET实体数据模型
    迷你极客主机Station M1 开箱体验
    制作Station M1主机的Armbian启动卡
    StationP1的Ubuntu上安装gedit
    Station OS播放网络共享文件夹的媒体资源
    体验StationOS的推荐应用功能
  • 原文地址:https://www.cnblogs.com/lulu/p/4188255.html
Copyright © 2011-2022 走看看