部署准备
当应用准备上线时,我们需要问自己若干问题:
- 应用是否测试过?
- 应用的特殊环境要求?
- 部署策略?
测试Akka应用
Akka提供了一个全面的测试工具模块-TestKit。包含以下两个方面:
- 单元测试:可以测试独立的逻辑单元。这层级主要测试actors,threads,消息的顺序,并发中的错误;
- 整合测试:测试Actors行为,包括多线程任务,不确定的消息事件的顺序。
TestKit提供了基本的结构可以用来写单元测试,如果想用ToolKit需要在maven中加入以下支持:
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit</artifactId>
<version>2.3.11</version>
</ dependency>
单元测试
为了测试业务逻辑,TestKit提供了TestActorRef,TestActorRef是一种特殊类型的引用,只用于测试目的。
TestActorRef提供了两种方式访问actor,如下:
- 它提供了一个对Actor对象的引用。只允许通过邮箱访问;
- 它允许执行actot的方法。
以下参见TickTock.java示例
访问Actor引用 通过以下方式获得:
TestActorRef<TickTock> actorRef = TestActorRef.apply(Props.create(TickTock.class), _system);
// get access to the underlying actor object
TickTock actor = actorRef.underlyingActor();
测试Actor行为
TestActorRef<TickTock> actorRef = TestActorRef.apply(Props.create(TickTock.class), _system);
String result = (String) Await.result(Patterns.ask(actorRef, new TickTock.Tick("msg"), 5000),
Duration.create(5, TimeUnit.SECONDS));
Assert.assertEquals("processed the tick message", result);
测试异常情况
测试不能处理的消息,抛出IllegalException。我们可以执行receive()方法,它将消息传给Actor,同时传播异常。
集成测试
不像传统的集成测试,测试系统中的各个组件,在Akka中,集成测试意味着测试Actor的功能。这就需要提套方案测试Actor,消息传递,actor返回,消息转发等。
如果我们又如下测试用例:
- EchoActor: It responds back with whatever has been passed to it
- BoomActor: It responds back with an exception to the string or integer passed
- ForwardingActor: It forwards the message to another actor
- SequencingActor: It replies back in a series of messages, but assumes we are interested in only one message *SupervisorActor: It manages a worker actor, and based on the exception thrown by it, applies the appropriate supervisor strategy
public void testEchoActor() {
ActorRef echoActorRef = _system.actorOf(Props.create(EchoActor.class));
// pass the reference to implicit sender testActor() otherwise
// message end up in dead mailbox
echoActorRef.tell("Hi there", super.testActor());
expectMsg("Hi there");
}
测试远程Actor
通过Akka扩展包管理应用配置
在一个典型的应用中,配置文件一般在应用外配置,根据环境不同而不同。Akka提供了一个有力的拓展机制。拓展通过静态加载,每个ActorSystem有一个实例,采用工厂模式实现。包含以下两个部分:
- Extension: Extension是一个接口,自定义实现。
- ExtensionId:一般继承AbstractExtensionId,是一个工厂类,提供对Extension的访问。需要实现lookup方法和createExtension方法。
通常应用部署根据环境不同,选择不同的配置文件,在不同的环境中,选择过程可能依赖构建工具等。
另一种方式就是把不同环境的配置放到一个配置文件中,通过一个系统变量来识别环境。
具体步骤如下: 创建一个类实现Extension接口,可以自定义方法;由于Extension是通过静态方式加载,因此可以很容易被其他actor引用。
接下来,需要写一个工厂类提供对Extension的访问。一般继承AbstractExtensionId,提供对Extension的访问。需要实现lookup方法和createExtension方法。lookup方法用来ActorSystem在启动时寻找Extension。createExtension用于初始化Extension实例。
使用Extension非常简单,只需要将ActorSystem引用传入Extension类。获取到Extension类就可以使用他的方法。
由于Extension是单例对象,一次所有的状态变量必须是线程安全的。
参见实例代码essentials
部署模型
- 作为一个jar包
- 微内核
详细参阅书籍,不细表。