原文地址:http://my.oschina.net/jingxing05/blog/290567
非阻塞的程序 应该保障的一些特性
:
- 等待无关性wait-free:能确保每次的调用在有限的步数之内完成,不管其他调用的步骤有多少。杀掉几个线程
- 锁无关性lock-free:执行这段程序的某些线程会被延迟,但必须确保至少有一个线程能持续步骤到执行完毕。这一点需防止可能出现的饿死,就是说防止某个线程永远被延迟。
- 阻碍阻塞无关性obstruction-free:有个时间点,在这个点之后非阻塞方法独立的在有限次步骤内执行完毕
- 锁无关的程序一定是阻碍无关的,反之不一定。
- 乐观并行控制法是障碍阻塞无关的,当检测到有冲突时,回滚修改,然后接受某种调度策略,过一会再试。
如果不得不进行阻塞操作,如线程sleep不确定的一段时间、等待时间发生,rdbms驱动,消息APi,IO,放到 future中很简单,但是可能带来性能问题和OOM。处理阻塞问题的解决方法:
将阻塞调用放到一个或管理一组actor的router中。确保配置一个线程池
将阻塞放到Future中时一定要确保对这个Future的调用是有上限的,否则容易oom。也可以配置带上限的线程池
使用单个线程来管理一组阻塞的资源,通过actor的消息分发出事件。
Actor容器人
ActorRef
State 可序列化 和还原
Behavior
MailBox
默认是先进先出的队列,可以自行实现优先级队列,但akka中当前behavior必须总是处理下一个出队的消息,而且没有扫描mailbox的动作,处理消息失败时,即认为failure发生了,当然这个行为可以被重写
is Supervisor ,can create许多Children,创建和停止都是异步的,马上返回,请记住!
监控策略也就是失效处理机制
上级将任务委托给下级 进行执行,监督的层级
root
/user /system
自定义的 系统支持的
一对一监督,OneForOneStrategy
多对一监督,AllForOneStrategy,一个Actor的失效会影响同组同辈的Actor失效时,适用
重启时,不会清空mailbox
Actor的路径和地址路由
不同类型的ActorReferences
纯本地Actor Ref,不能跨网络发送消息到远程的jvm上
开启远程功能的本地Actor Ref,带有protocol和远程地址信息
router型本地Actor Ref,消息直接发给其children
远程Ref ,序列化的消息传送
PromiseActorRef
DeadLetterActorRef
EmptyLocalActorRef
用不到但存在的:root的监测这the one pseudo-supervisor
Logging.StandarOutLogger
Actor实例化
不要在一个Actor中申明另一个Actor
不要传递Actor的this 指针到Props
Props是一个配置工具类,用来配置创建Actor时所需的信息,如参数和类名
为每个Actor提供一个Props的工厂,来新创actor
建议actor的层级结构来支持failure处理
path和UID代表一个actor,重启时 path和UID不会变
MessgeDispatchers是akka系统的引擎,同时也是ExecutionContext执行上下文环境
,可以用来执行任何代码
ActorSystem都有个默认的可配置的dispatcher
fork-join-executor thread-pool-executor
四种类型的dispatcher来新建actor或者说线程
Dispatcher:默认的,事件驱动的,将一组actor绑到一个线程池中,共享线程的,
PinnedDispatcher:一个actor一个线程,线程不共享,
BalancingDispatcher:事件驱动的,会将任务繁重的actor的一些任务分发到 空闲的actor上,所有actors共享一个mailbox,前提是这些actor的所有实例都能处理 mailbox中的消息,不能用作Router Dispatcher
CallingThreadDispatcher:仅在当前线程 执行 invocations,不新建线程,可由不同线程对同一个actor进行调用,适于测试
MailBox信箱
按以下步骤确定mailbox的类型:
1、以 actor的deployment配置中的mailbox项为准,否则
2、以 actor的Props包含mailbox的配置,(如withMailbox)为准,否则
3、以 actor的Dispatcher配置中mailbox-type为准,否则
4、以actor包含的mailbox type为准,如with RequiresMessageQueue[BoundedMessageQueueSemantics],否则
5、以 actor的 Dispatcher包含的mailbox type为准,否则
6、默认为akka.actor.default-mailbox(无限邮箱,java.util.concurrent.ConcurrentLinkedQueue,SingleconsumerOnlyUnboundedMailbox是个更高效的信箱,但不能用于BalancingDispatcher)
实现MailboxType[ActorSystem.Settings, Config]即可自定义信箱,Akka自带实现的信箱类型有akka.dispatch.:
UnboundedMailbox-java.util.concurrent.ConcurrentLinkedQueue,非阻塞,无限消息,unbounded
SingleConsumerOnlyUnboundedMailbox-一个高效的多生产者单消费者队列,非阻塞,无限消息
BoundedMailbox-java.util.concurrent.LinkedBlockingQueue,阻塞,有限消息,bounded
UnboundedPriorityMailbox-java.util.concurrent.PriorityBlockingQueue,阻塞,无限消息
BoundedPriorityMailbox-由akka.util.BoundedBlockingQueue封装的java.util.concurrent.PriorityBlockingQueue,阻塞,有限消息
消息路由Routing routeees
akka自带的路由规则器有:akka.routing.
akka.routing.RoundRobinRoutingLogic
akka.routing.RandomRoutingLogic
• akka.routing.SmallestMailboxRoutingLogic
• akka.routing.BroadcastRoutingLogic
• akka.routing.ScatterGatherFirstCompletedRoutingLogic
• akka.routing.ConsistentHashingRoutingLogic
case class 、object中case的作用,生成大量模板代码
,使用case的class会自动生成如下:
apply方法:无需使用new来新建对象了,
给构造函数的参数(默认为val的)自动创建了 get 方法,如果参数申明为 var则自动生成get/set方法了
toString, equals ,hashCode, copy方法
unapply: 方便用于 match表达式中
case class的目标是创建不可变 记录,以更好地用于模式识别
链式调用
返回:this.type可实现链式调用,如果是不能被继承的类则方法最后直接返回 this亦可
method 方法 function 函数
def methodname(arg: Type, funcname(argn: Type) =>Type){
}
输入 => 输出 =>映射 转换
val funcname = (argn: Type1) : Type2 =>{ …. Type2 }
method不能作为参数传递,而 function可以,function就是个函数类型的 变量
function函数是一个对象,继承自trait: Function0, Function1, …… Function22
部分函数
函数式编程思想: 将函数apply到参数上面
java中是对参数 进行全函数处理
而scala中可以只传入部分参数,函数进行部分处理,偏函数
将一个多参数函数的一部分参数赋值,而另一部分作为新 函数的 参数的方法
不是一一映射 部分映射而已,不能对所有输入进行处理,过滤掉一部分输入
PartialFunction[InputargsType, ReturnType] = { 。。。。。。 }
Scala集合
明确: 预测器:predicate是个返回boolean的 函数或方法
匿名函数: () => { …….. }
隐式loop:集合方法filter foreach map reduceLeft …都能隐式的对元素进行for循环
集合层级
顶级的三层trait:始于 Traversable 中间 iterable ,然后三分天下: Seq Set Map
以这三个 散枝阔叶出庞大的集合系
序列最好用不可变的vector 或者可变的arraybuffer
map
其他看起来像集合的类
枚举enumeration:有限集合 iterator:提供很多遍历方法 option:处理null的有效工具 tuple元祖:异种数据集合
当集合元素数量很大时,需要使用lazy集合而不是strict 集合,内存没这么大 :使用集合的view方法
scala中 :结尾的方法是 从右向左 估值的