Elixir

https://elixirschool.com/cn/

小 Elixir 例子

并行处理 JSON 字符串输入,并且解析成可用的变量,计算每秒处理的速度并输出。

https://github.com/doubaokun/exsample

entop 监控 Elixir 应用状态

翻译 ?

Java、Erlang、Scala、php、javascript、C#、C、Python、Ruby 等一大堆各种风格的编程语言

学那么多编程语言是想做”翻译”吗?其实事情并不那么简单

不同语言背后是风格截然不同的类库群、技术堆栈、生态和工具链

不同的语言针对了不同类型的问题。某些语言解决某些问题的成本会比其他语言低非常多

回归本质,学习编程语言还是为了低成本高效的解决实际的业务问题

一些编程风格

近实时更新变更

最好不需要长时间编译才能执行、应用启动快

PHP 、Node.js

jave maven/gradle

C/C++

编译速度

很多前端工具,源码变更,不需要刷新页面自动反应在浏览器中

更进一步,生产环境热加载,更新代码不影响

PHP 默认就是这样,部署后刷新 APC 缓存就可以

正是无状态、短链接的 HTTP 应用的优势,虽然随之而来的是性能相对降低更多 TCP 的开销,但是把问题变得简单很多

elixir、Erlang 可以做到真正的任何情况下开着跑车换轮子

并发模型

支持并发执行

人更习惯顺序执行的思路,且大部分业务逻辑都是顺序执行的

但为降低延迟、提高性能,最好能在语言层面支持并发执行。一个操作开始还未返回结果,就可以开始另一个操作

这样调用远程 API 或者远程 RPC,耗时为最慢那一个操作的耗时。大部分流行语言都可以做到并发调用,但 PHP 难以做到

轻量级执行进程或者线程

某些业务逻辑会因为大量计算、网络、磁盘 IO 等占用一个执行进程或者线程

希望这个执行体能够尽量轻量级,很少的内存占用,很快的启动时间,很少的切换消耗,最好能在 IO 执行的时候自动让出计算资源

进程模型

曾经有的异步框架 CS 高居不下,甚至比业务逻辑的 CPU 使用更高

线程模型

相对于进程模型好了很多,比进程轻量很多,创建、切换也快很多

但也容易无法充分利用多核性能,IO 阻塞无法释放计算资源

每个 CPU 核心只能同时运行一个线程,多个线程之间需要切换调度(CS)

CPU 密集类型的计算,没有或者很少 IO 操作,最好启动 CPU 核心数量的线程

IO 操作多,如 磁盘或者网络,多余 CPU 核心数的线程有效,IO 操作的时候可以切换到其他线程执行 CPU 操作

Fork-join 轻量级进程模型

Fork-join 创建自己的进程池来执行小粒度的任务

相对于 Erlang 那种真正的抢占式调度的 VM 实现或者操作系统的抢占式调度,Fork-join 模型非常简单,也意味着相比之下效率相对低

Fork-join 针对计算密集操作设计,无法告诉 F/J 框架你因为 IO 等待而释放一会儿计算资源。所以,一般需要将异步 IO 操作放到另外的线程池,FJ 只处理纯计算

基于 Scala 的 Akka 即是这种模型。所以,假如处理不当, Akka 的 Actor 很容易阻塞执行线程,如果执行线程池的线程被耗光,整个应用将会僵死在那里。而 Erlang 则没有这个问题

Erlang 轻量级进程模型

VM 调度线程,将计算划分为非常小的执行单元。可以支持非常多的进程。IO 阻塞可以自动释放资源。真正的抢占式调度


elixir是用erlang写的语言,有意思的是它完全是“解释性”的。也就是说用erlang的语法重新封装了一个更好用的语法

有评价说是“小孩子的玩具”,试过后来发现——额,我们直接erlang吧。。。。

类型系统

静态类型可以避免很多失误;动态类型经常会出现不可预期的结果

动态类型让开发更加快速。强静态类型系统会执行很快,比如 Java,但是也可以在有必要的时候使用反射,比如很多 RPC 框架的实现 (也有更进一步的字节码修改技术)

每个语言的类型系统都有自己的特点

其他

  • 内置结构或者容器类

  • GC

除非 Erlang 无可媲美的轻量级线程级别的 GC

要么需要记住和理解复杂的 GC 调优参数、要么像 PHP 那样过一段时间将进程杀掉重来

  • 元编程和 DSL 扩展性

在语法级别的抽象和封装更能提高开发效率

  • 依赖和库管理系统

Node.js npm

  • 打包和发布

如 Java 打包成 Fat Jar,或 Golang编译成单一文件

  • 工具链

项目构建、编译、测试工具比较完善。 比如 Java、Scala 项目的 maven、sbt 。Erlang 项目可以用 rebar ,但是 Elixir 的 mix 友好的很多倍

另外一个好的 REPL 命令行工具非常重要,因为这可以方便的侵入应用进行调试,或者测试一条代码片段

比如 PHP 的 php -a, sbt, Clojure 的 lein, Erlang 的 erl, Elixir 的 iex 等等

  • 脚本执行

小任务可以立刻创建一个脚本执行,而不需要修改、编译部署现有运行的应用

比如,连接到集群,读取状态或者进行一次性的数据操作,然后断开

ref

PHP并发IO编程之路

http://blog.jobbole.com/98986/