erlang浅谈
优点:
1.面向并发,有成熟而且久经考验的框架可供使用,网络部分已经经过了良好封装
2.内存缓存解决方案进程字典,前者的读写速度是50NS-100Ns级别的
3.对二进制数据解析的语法是直观,简单,强大(游戏中有大量的二进制数据要处理
4.没有共享内存! 没有锁!(我们在代码中没有过显示使用锁)
缺点
1.从一种语言过渡到另一种语言,会有各种不爽:
2.控制逻辑简单只有if 和 case ,而且有if没有else,没有continue break goto
3.包括kernel库和standlib库在内,很多函数和变量的命名和传统语言不一样
一.
1. 结构: 应用--<>模块--<>函数--<>语句--<>子语句--<>表达式--<>子语句..
2. 函数式编程
a) 函数式编程,本身不存放状态,对它的影响只有输入参数,而它的影响就是输出函数。
b) 函数式编程,是分布式应用中,高并发,代码热替换的基石
c) Erlang应用就是由这些函数构成的,它的重要理念,everything is function,所有的函数都有返回值。(相当于默认最后一句就是return的值)
3. 变量
a) Erlang是面向函数式编程的,进程本身没有全局变量。
b) 在函数上下文中,可有局部变量,所有的局部变量都是readonly,及只能赋值一次
4. 尾递归优化
a) Erlang没有循环,如果要实现循环只能通过递归来实现。
b) Erlang对函数调回,如果该函数后面没有下文,则被优化,栈空间不会被占用
先看一个例子,对前面的一个总结
raw_read_loop(File, Acc) -> %%函数
case file:read(File, 10) of
{ok, Bytes} ->
raw_read_loop(File, [Acc | Bytes]); %%递归实现循环,尾递归优化
eof ->
file:close(File), %%表达式直接用逗号隔开
{ok, iolist_to_binary(Acc)}; %%子语句用分号隔开
{error, Reason} ->
file:close(File),
erlang:error(Reason)
end.
5. 模式匹配
a) 这个是横行于Erlang和区别其他语言的重要特性
b) 通过模式匹配把函数拆分成多个子句
convert_to_celsius({Name, {c, Temp}}) ->
{Name, {c, Temp}}; %%子句
convert_to_celsius({Name, {f, Temp}}) ->
{Name, {c, (Temp - 32) * 5 / 9}}.
调用convert_to_celsius("ABC", {f, 1234}}) . 根据(f),将匹配第二句
c) 分支判断
case catch onecached_storage:get_item(Storage, Key) of
{ok, {Flags, Data}} ->
...
none ->
ok;
Other ->
...
end.
d) 协议匹配
case Packet of
<<Len:16, PayLoad:Len/binary, 16#ef>> ->
{body, PayLoad};
_ ->
{error, invalid_packet}
end.
总结:
主要说他的限制把,Erlang不是GSL(通用语言),因此使用性和流行度上有天生的限制。流行度不够,所以发展也相对缓慢。其纯函数式编程,对那些复杂业务编程不太适合。
二.
1. Erlang系统特点
Erlang本身内置支持分布式应用里边的,高并发,分布式,代码热替换,容错性。
1.1. 高并发
a) 进程
i. Erlang的最小执行单元是进程,进程的最大特点是隔离性好,(有自己的独立内存空间,Crash不会影响其他工作单元)。
ii. Erlang的进程特点
1. 协程
a) 自己控制执行切换
b) 高效。由于不频繁切换系统上下文(页表等),效率比直接使用OS的高。
2. 成本极低
a) 一个Erlang进程,默认开销2K多一点(主要是栈和默认堆)
b) 对应的一个OS线程,一般栈空间都不少于512K
c) 由于是协程,进程切换直接成本极低
3. CPU亲和性
a) 协程,当然可以自己控制ERLANG进程绑定在特定的OS线程之上
b) 这个特性大大避免了锁开销
4. 零锁编程
a) 函数式编程本身理念就是无需锁的
b) 没有全局变量,进程本身状态也只有自己可以访问,因此找不到锁的用武之地
c) 不是绝对的,比如依赖外部异构资源,这个语言本身无法解决
b) Erlang的进程成本如此之低,因此我们可以以同步的方式来构建我们的异步系统。它的实现也是如此的,对耗时操作都会引起当前进程的trap.
1.2. 容错性
a) 内置的容错性
i. 基于进程的,隔离性好
ii. 支持异常捕获
iii. 进程直接可以建立关系
发生了Link关系的两个进程可以感知另外一个进程的结束,不处理默认就是一起exit了
iv. 进程和节点监控
有内置的监控机制去监控某个进程或者节点,可以感知他们down
b) 内置支持失败重启
以-heart Cmd 标志启动,当前节点crash可以自动重启。这样你无须自己去写监控脚本。
c) OTP的Supervisor模式
Supervisor可以把根据依赖关系,把进程搭建成树状结构,高层的节点或者叶节点被低层监控。
监控节点可以根据参数决定子节点的重启策略
- Restart: permanent | transient | temporary 永远重启|异常退出才重启|永远不重启
- 监控节点退出子进程的shutdown 策略
子进程的返回中控制:
- l 当前进程挂掉了重启间隔时间
- l 指定时间内重启最大频率
- RestarStrategy: l 重启时是重启自己 || 所有的进程 || 配置时排在当前进程之后
1.3. 分布式支持
1. 节点位置透明
根据节点名可以连到节点,无需指定具体的端口号
2. 自动连接
发生通讯的进程,如果处于两个节点上,这两个节点可以自动连接
3. 连接协议可配置
节点之间的连接协议是可以配置的,内置支持TCP和SSL,也可以开发自己的协议
4. 全联通
A连接了B,如果A在连接了C,这时B和C之间也可以互相感知了(nodes()和monitor都可以感知到)
5. 透明路由
进程之间的通讯不论是同一节点上,跨节点,或者跨机器,都可以以统一的Pid!Message的方式进行通讯。
因此,我们可以以统一的方式来构建我们的系统。
6. TakeOver
可以配置多个节点来运行指定应用,系统会根据顺序选定当前服务节点。如果节点挂了,后面的依次被选择。那些优先节点恢复后会抢夺运行权,重新由它提供服务
7. 代码中心
可以指定在指定机器运行代码。
它的具体实现是通过ssh在指定机器上运行erlang并把要运行的代码复制过去,然后执行。
1.4. 代码热升级
由于没有变量,而且都是基于函数式的实现,因而可以实现代码热升级。(执行的入口改了,所有的状态都在进程上下文中,下次调用时携带到参数里就行了)
1.5. Port管道
Erlang是DSL,不适合构建太复杂业务的系统。他提供了一种异构系统互通的机制,就是Port管道。
可以直接调用外部应用,跟外部应用stdin和stdout对接。也可以开发自己driver(可以做更加精细的控制,比如常驻内存select输入,输出,不同阶段有不同的回调)
三.
1. OTP
OTP把分布式应用开发的一些常用场景,进程依赖管理,反应式,状态机,事件驱动模式框架化;另外,提供了一个分布式存储。
1.1. 框架
1. supervisor
监控树。
a) 配置要管理进程们启动参数
进程的所处模块,启动函数(也支持匿名函数),启动参数
b) 定制子进程的重启策略
- l 当前进程挂掉了重启间隔时间
- l 指定时间内重启最大频率
- l 重启时是重启自己 || 所有的进程 || 配置时排在当前进程之后
2. gen_server
反应式框架。自身一个进程。
支持同步的call和异步的cast消息投递,也支持Pid!Message的原语方式(这点可以让其跟很多异步接口对接起来)。
3. gen_fsm
有限状态机(本身没有状态,只能是有限)。自身一个进程。
State(S) x Event(E) -> Actions(A), State(S')
发送消息给该进程,它会回调{CurrentStateName}/2函数,CurrentStateName就是当前状态;如果是调用all_state相关的接口,会回调专门的handle_event等相关函数。
4. gen_event
消息中心。
运行的过程:
a) 启动交换器进程,监听指定消息
b) 注册消息回调
c) 发送消息
d) 交换器进程回调注册的模块相应接口
1.2. mnesia
分布式的数据库管理
1. 支持多个列
2. 支持多个副本
副本的策略有:
- ram (所有数据都在内存)
- ram_disk(数据存在内存和磁盘)
- disk(数据只放在磁盘)
3. 支持表分片
4. 使用时不用指定副本位置
自动选择合适的副本
限制
处理大文件有一定的性能问题
erlang浅谈的更多相关文章
- 【转】浅谈多核CPU、多线程、多进程
浅谈多核CPU.多线程.多进程 1.CPU发展趋势 核心数目依旧会越来越多,依据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的桌面PC有望在2017年末2018年初达到24核心(或者16核3 ...
- 线程池+同步io和异步io(浅谈)
线程池+同步io和异步io(浅谈) 来自于知乎大佬的一个评论 我们的系统代码从同步方式+线程池改成异步化之后压测发现性能提高了一倍,不再有大量的空闲线程,但是CPU的消耗太大,几乎打满,后来改成协程化 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
- 浅谈 LayoutInflater
浅谈 LayoutInflater 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/View 文中如有纰漏,欢迎大家留言指出. 在 Android 的 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈SQL注入风险 - 一个Login拿下Server
前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...
- 浅谈WebService的版本兼容性设计
在现在大型的项目或者软件开发中,一般都会有很多种终端, PC端比如Winform.WebForm,移动端,比如各种Native客户端(iOS, Android, WP),Html5等,我们要满足以上所 ...
- 浅谈angular2+ionic2
浅谈angular2+ionic2 前言: 不要用angular的语法去写angular2,有人说二者就像Java和JavaScript的区别. 1. 项目所用:angular2+ionic2 ...
- iOS开发之浅谈MVVM的架构设计与团队协作
今天写这篇博客是想达到抛砖引玉的作用,想与大家交流一下思想,相互学习,博文中有不足之处还望大家批评指正.本篇博客的内容沿袭以往博客的风格,也是以干货为主,偶尔扯扯咸蛋(哈哈~不好好工作又开始发表博客啦 ...
随机推荐
- Android ProGuard代码混淆技术详解
前言 受<APP研发录>启发,里面讲到一名Android程序员,在工作一段时间后,会感觉到迷茫,想进阶的话接下去是看Android系统源码呢,还是每天继续做应用,毕竟每天都是画UI ...
- 利用formdata对象上传文件时,需要添加的参数
function doUpload() { var formData = new FormData($( "#uploadForm" )[0]); $.ajax({ url: 'h ...
- 15个常用的javaScript正则表达式--来自于javascript公众号
摘要 收集整理了15个常用的javaScript正则表达式,其中包括用户名.密码强度.整数.数字.电子邮件地址(Email).手机号码.身份证号.URL地址. IPv4地址. 十六进制颜色. 日期. ...
- scrapy--介绍
Scrapy一个开源和协作的框架,其最初是为了页面抓取所设计的,使用它可以以快速.简单.可扩展的方式从网站中提取所需的数据.但目前Scrapy的用途十分广泛,可用于如数据挖掘.监测和自动化测试等领 ...
- c#中反射的用法(即如何根据字符找到已定义的变量)
2013-07-20 08:06 720人阅读 评论(0) 收藏 举报 分类: C#(9) 作者同类文章 X 版权声明:本文为博主原创文章,未经博主允许不得转载. 常常羡慕javascript中, ...
- [置顶]
WebService学习总结(1)——WebService相关概念
一.序言 大家或多或少都听过 WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成 分.但是不得不承认的是W ...
- Javascript和jquery事件--滚动条事件和自定义滚动条事件样式
很想把滚动条事件跟鼠标滚轮事件放在一起,那就直接写在这一篇了.除了事件以外,对滚动条样式的调整也记在这里吧. 滚动条是浏览器的默认事件,使用overflow:auto/scroll都有可能出现,它的默 ...
- 再记AE与AO的区别与联系
原文地址:转:ArcObjects与ArcEngine作者:梦游 ArcObjects(简称AO),一般都是指ArcGIS Desktop版本的组件开发集,即需要安装ArcGIS桌面版软件后才能安 ...
- 挖一挖不经常使用到而又非常有用的重载-Split
Split这个基本上全部的程序开发者都用到,一般使用单字符和长字符串拆分字符串的较多.事实上另一个重载很好用.那就是多种组合字符来进行拆分. 比如: "aaaaaaaaaa{@}bbbbbb ...
- nginx启用https访问
什么是https? https 全称:Hyper Text Transfer Protocol over Secure Socket Layer,是http的安全版.即http下加入SSL协议层,因此 ...