什么是actor,是一个封装了状态和行为的对象,每个actor都通过message交流,从自己的mailbox中读取别的actor发送的消息。
ActorSystem是一个进入Actor世界的入口点。ActorSystem在创建和停止Actors的时候自始至终都存在着。并且在关掉整个Actor环境的时候也存在着。
props 是一个指定创建Actor的配置类。
Props props1 = new Props(类名.class);
scala语言中 def props = Props(new 类名) |||||||||||||||||| 题外话,sparkSession spark的一个切入点 在Spark的早期版本,sparkContext是进入Spark的切入点。我们都知道RDD是Spark中重要的API,然而它的创建和操作得使用sparkContext提供的API; 对于RDD之外的其他东西,我们需要使用其他的Context。比如对于流处理来说,我们得使用StreamingContext;对于SQL得使用sqlContext; 而对于hive得使用HiveContext。然而DataSet和Dataframe提供的API逐渐称为新的标准API,我们需要一个切入点来构建它们, 所以在 Spark 2.0以及以上版本中我们引入了一个新的切入点 SparkSession SparkSession实质上是SQLContext和HiveContext的组合,所以在SQLContext和HiveContext上可用的API在SparkSession上同样是可以使用的。 SparkSession内部封装了sparkContext,所以计算实际上是由sparkContext完成的。 来说说创建sparkSession吧,SparkSession的设计遵循了工厂设计模式
def spark = SparkSession.builder().appName("spark session example").getOrCreate() 或者val spark = SparkSession. builder().master("local").appName("spark session example").getOrCreate()
如果你想创建hiveContext,可以使用下面的方法来创建SparkSession,以使得它支持Hive:
val spark = SparkSession.builder().master("local").appName("spark session example").enableHiveSupport().getOrCreate()
||||||||||||||||||
Actors的创建是通过Props实例进入actorOf工厂方法。
implicit val system = ActorSystem("给Actor来个名字吧") ActorSystem是重量级的对象,会创建1...N个线程,所以一个application一个ActorSystem。
ActorRef myActor = system.actorOf(new Props(类名.class).withDispatcher("mydispatcher"), "actors名");
名称参数是可选择的,但应该给你的acotr起一个好名字,因为它被用来记录log和确定actor。
名称不能为空,不能$开头。如果名字已经被使用,将会抛出InvalidActorNameException。
调用actorOf 并返回ActorRef的实例。
这是一个处理UntypedActor实例,您可以使用与UntypedActor交互。
ActorRef 是不可变得,并且与所表示的Actor有一对一的关系。
ActorRef也是serializable 和network-aware的。
你可以在网络上序列化并发送他,在远程主机端使用一个相同的Actor。
在上面的例子,actor被system创建,Actor还可能被别的actor通过actor context创建。不同的是管理层次结构是如何安排的。
当使用context创建时,当前Actor监督被创建的child Actor。当使用system创建时,被创建的Actor将会是顶级Actor,被系统监督。
Actor 被创建时将会异步自动开始。当你创建UntypedActor 类然后将自动调用preStart回调函数。可以Actor中添加初始化代码。
如果你的UntypedActor 有一个含参构造函数,那么你不能使用‘actorOf(new Props(clazz))’创建。你可以用‘new Props(new UntypedActorFactory() {..})’代替
当在写actor外的沟通与actor时,解决方案是ask模式,但是有两个事不能做。接受多个回复和观察其他actor的lifecycle。
send 方法包装了一个普通的tell并且支持内部的actor的引用作为一个sender。
com.typesafe.config加载任意位置的配置文件
val config = ConfigFactory.load() 加载配置文件,只能加载src/main/resources目录下的application.conf文件,不够灵活。 val config =ConfigFactory.parseFile(new File("*****.conf")) 响应http服务,根据服务处理不同业务以及逻辑 加载完配置文件可以获取配置文件中的ip 以及端口后期再说看累了- -~val bindingFuture = Http().bindAndHandle(类实例对象, ip, 端口) 在给定的ip和端口启动新的 http 服务器并使用给定的 "处理程序" 根据需要的请求创建一个链接的路由上次接收消息的引用发件人角色。def routes: Route = readData ~ writeData/** * Returns a Route that chains two Routes. If the first Route rejects the request the second route is given a * chance to act upon the request. */ def ~(other: Route): Route = { ctx ⇒ import ctx.executionContext route(ctx).fast.flatMap { case x: RouteResult.Complete ⇒ FastFuture.successful(x) case RouteResult.Rejected(outerRejections) ⇒ other(ctx).fast.map { case x: RouteResult.Complete ⇒ x case RouteResult.Rejected(innerRejections) ⇒ RouteResult.Rejected(outerRejections ++ innerRejections) } } } 然后就可以匹配路由连接串上的每一个请求,进行单独处理def readData = { 代码处理片段
}def writeData = { 代码处理片段}Actor消息传递(终于到了墨迹半天了)
最上面已经创建了一个ActorSystem
接下来使用ActorSystem创建了一个Teacher Actor的代理(ActorRef)
给代理发送QuoteRequest(请求格言)消息。
ActorRef是一个真实Actors的代理。客户端并不直接跟Actor对话。这这种Actor的模型是为了防止TeacherActor的自定义/私有方法或变量被直接访问。
你只会直接给ActorRef发送消息并且消息最终会到达实际的Actor。你永远不能直接跟Actor交互。要是你找到一些方式干这个,你会被大家诅咒。
你只需要将QuoteRequest消息tell告诉ActorRef。这个告诉的方法在Actor里面是!叹号。(ActorRef也有一个tell方法,作用是委托回调给!)
sender()是定义的, 如果消息是从另一个参与者发送的,