http://blog.chinaunix.net/uid-25885064-id-3400549.html
我们相信编写出正确的具有容错性和可扩展性的并发程序太困难了。这多数是因为我们使用了错误的工具和错误的抽象级别。Akka就是为了改变这种状况而生的。通过使用Actor模型我们提升了抽象级别,为构建正确的可扩展并发应用提供了一个更好的平台。在容错性方面我们采取了“let it crash”(让它崩溃)模型,人们已经将这种模型用在了电信行业,构建出“自愈合”的应用和永不停机的系统,取得了巨大成功。Actor还为透明的分布式系统以及真正的可扩展高容错应用的基础进行了抽象。
Akka是开源的,可以通过Apache 2许可获得。可以从 http://akka.io/downloads/ 下载。
事务性Actor是actor与STM(Software Transactional Memory)的组合。它使你能够使用自动重试和回滚来组合出原子消息流。
- 以库的形式:在web应用中使用,放到 WEB-INF/lib 中或者作为一个普通的Jar包放进classpath。
- 以微内核的形式:你可以将应用放进一个独立的内核。
Akka的商业支持早先被叫作Cloudy Akka. 它包括两部分:
- Akka的集群支持
- 监控和管理(早先称为Atmos)
Cloudy Akka已经停止了。集群支持已经被移进了Akka的开源版本中(即将到来的Akka 2.1),而监控和管理(Atmos)现在被重新命名为Typesafe控制台,是Typesafe Stack(详见下文)商业合约的一部分。
Akka现在是 Typesafe Stack 的一部分。
Typesafe stack是一个让开发者更容易地构建可扩展软件应用的现代软件平台。它在一个简单的包里组合了Scala语言、Akka、Play! Web框架和其它鲁棒的开发工具,能够与现有的Java基础设施无缝集成。Typesafe Stack是完全开源的。
Typesafe控制台
在Typesafe Stack的顶端,我们还有名叫Typesafe控制台的商业产品,提供以下功能:
- 漂亮的Web界面,实时展示系统内部状态
- 通过Dashboard、JMX和REST进行管理
- 组件间及远程节点间消息的跟踪
- 实时统计
- 开销非常小的监控程序(生产系统中应该保持运行)
- 单节点上统计与日志信息的合并
- 统计数据的存储,以备后续处理
- 安装升级及滚动升级
Akka提供可扩展的实时事务处理,是一个运行时与编程模型一致的系统,为以下目标设计:
- 垂直扩展(并发)
- 水平扩展(远程调用)
- 高容错
在Akka的世界里,只有一个内容需要学习和管理,具有高内聚和高一致的语义。
Akka是一种高度可扩展的软件,这不仅仅表现在性能方面,也表现在它所适用的应用的大小。Akka的核心,Akka-actor是非常小的,可以非常方便地放进你的应用中,提供你需要的异步无锁并行功能,不会有任何困扰。
你可以任意选择Akka的某些部分集成到你的应用中,也可以使用完整的包——Akka 微内核,它是一个独立的容器,可以直接部署你的Akka应用。随着CPU核数越来越多,即使你只使用一台电脑,Akka也可作为一种提供卓越性能的选择。 Akka还同时提供多种并发范型,允许用户选择正确的工具来完成工作。
我们看到Akka被成功运用在众多行业的众多大企业,从投资业到商业银行、从零售业到社会媒体、仿真、游戏和赌博、汽车和交通系统、数据分析等等等等。任何需要高吞吐率和低延迟的系统都是使用Akka的候选。
Actor使你能够进行服务失败管理(监管者),负载管理(缓和策略、超时和隔离),水平和垂直方向上的可扩展性(增加cpu核数和/或增加更多的机器)管理。
下面的链接中有一些Akka用户关于他们如何使用Akka的描述: http://stackoverflow.com/questions/4493001/good-use-case-for-akka
所有以上这些都在这个Apache2许可的开源软件中。
以下是Akka被部署到生产环境中的领域
事务处理 (在线游戏,金融/银行业,贸易,统计,赌博,社会媒体,电信):垂直扩展,水平扩展,容错/高可用性
服务后端 (任何行业,任何应用):提供REST, SOAP, Cometd, WebSockets 等服务 作为消息总线/集成层 垂直扩展,水平扩展,容错/高可用性
并发/并行 (任何应用):运行正确,方便使用,只需要将jar包添加到现有的JVM项目中(使用Scala,java, Groovy或jruby)
仿真:主/从,计算网格,MaReduce等等.
批处理 (任何行业):Camel集成来连接批处理数据源 Actor来分治地批处理工作负载
通信Hub (电信, Web媒体, 手机媒体):垂直扩展,水平扩展,容错/高可用性
游戏与赌博 (MOM, 在线游戏, 赌博):垂直扩展,水平扩展,容错/高可用性
商业智能/数据挖掘/通用数据处理:垂直扩展,水平扩展,容错/高可用性
复杂事件流处理:垂直扩展,水平扩展,容错/高可用性
http://blog.chinaunix.net/uid-25885064-id-3401962.html
1.确保安装的java环境是1.6或以上;
2.设置JAVA_HOME环境变量(java SDK所安装的目录)
# export JAVA_HOME=..root of Java distribution..
# export PATH=$PATH:$JAVA_HOME/bin
3.可以使用以下指令查看java的版本
# java -version
java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.5) (6b24-1.11.5-0ubuntu1~10.04.2)
OpenJDK Server VM (build 20.0-b12, mixed mode)
二、下载开发包及设置开发环境
1.从http://akka.io/downloads/处下载最新的Akka开发包,并将其加压到相应的目录,例如/srv目录下;
2.设置开发包的环境变量AKKA_HOME
# export AKKA_HOME=/srv/akka-2.0.3
三、编辑、编译源码及执行
1.在/srv/akka-2.0.3/tutorial目录下,创建Pi.java,写入以下内容:
- import akka.actor.ActorRef;
- import akka.actor.ActorSystem;
- import akka.actor.Props;
- import akka.actor.UntypedActor;
- import akka.actor.UntypedActorFactory;
- import akka.routing.RoundRobinRouter;
- import akka.util.Duration;
- import java.util.concurrent.TimeUnit;
- public class Pi {
- public static void main(String[] args) {
- Pi pi = new Pi();
- pi.calculate(4, 10000, 10000);
- }
- static class Calculate {
- }
- static class Work {
- private final int start;
- private final int nrOfElements;
- public Work(int start, int nrOfElements) {
- this.start = start;
- this.nrOfElements = nrOfElements;
- }
- public int getStart() {
- return start;
- }
- public int getNrOfElements() {
- return nrOfElements;
- }
- }
- static class Result {
- private final double value;
- public Result(double value) {
- this.value = value;
- }
- public double getValue() {
- return value;
- }
- }
- static class PiApproximation {
- private final double pi;
- private final Duration duration;
- public PiApproximation(double pi, Duration duration) {
- this.pi = pi;
- this.duration = duration;
- }
- public double getPi() {
- return pi;
- }
- public Duration getDuration() {
- return duration;
- }
- }
- public static class Worker extends UntypedActor {
- private double calculatePiFor(int start, int nrOfElements) {
- double acc = 0.0;
- for (int i = start * nrOfElements; i <= ((start + 1) * nrOfElements - 1); i++) {
- acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1);
- }
- return acc;
- }
- public void onReceive(Object message) {
- if (message instanceof Work) {
- Work work = (Work) message;
- double result = calculatePiFor(work.getStart(), work.getNrOfElements());
- getSender().tell(new Result(result), getSelf());
- } else {
- unhandled(message);
- }
- }
- }
- public static class Master extends UntypedActor {
- private final int nrOfMessages;
- private final int nrOfElements;
- private double pi;
- private int nrOfResults;
- private final long start = System.currentTimeMillis();
- private final ActorRef listener;
- private final ActorRef workerRouter;
- public Master(final int nrOfWorkers, int nrOfMessages, int nrOfElements, ActorRef listener) {
- this.nrOfMessages = nrOfMessages;
- this.nrOfElements = nrOfElements;
- this.listener = listener;
- workerRouter = this.getContext().actorOf(new Props(Worker.class).withRouter(new RoundRobinRouter(nrOfWorkers)),
- "workerRouter");
- }
- public void onReceive(Object message) {
- if (message instanceof Calculate) {
- for (int start = 0; start < nrOfMessages; start++) {
- workerRouter.tell(new Work(start, nrOfElements), getSelf());
- }
- } else if (message instanceof Result) {
- Result result = (Result) message;
- pi += result.getValue();
- nrOfResults += 1;
- if (nrOfResults == nrOfMessages) {
- // Send the result to the listener
- Duration duration = Duration.create(System.currentTimeMillis() - start, TimeUnit.MILLISECONDS);
- listener.tell(new PiApproximation(pi, duration), getSelf());
- // Stops this actor and all its supervised children
- getContext().stop(getSelf());
- }
- } else {
- unhandled(message);
- }
- }
- }
- public static class Listener extends UntypedActor {
- public void onReceive(Object message) {
- if (message instanceof PiApproximation) {
- PiApproximation approximation = (PiApproximation) message;
- System.out.println(String.format("\n\tPi approximation: \t\t%s\n\tCalculation time: \t%s",
- approximation.getPi(), approximation.getDuration()));
- getContext().system().shutdown();
- } else {
- unhandled(message);
- }
- }
- }
- public void calculate(final int nrOfWorkers, final int nrOfElements, final int nrOfMessages) {
- // Create an Akka system
- ActorSystem system = ActorSystem.create("PiSystem");
- // create the result listener, which will print the result and shutdown the system
- final ActorRef listener = system.actorOf(new Props(Listener.class), "listener");
- // create the master
- ActorRef master = system.actorOf(new Props(new UntypedActorFactory() {
- public UntypedActor create() {
- return new Master(nrOfWorkers, nrOfMessages, nrOfElements, listener);
- }
- }), "master");
- // start the calculation
- master.tell(new Calculate());
- }
- }
2.编译
# javac -cp ../lib/scala-library.jar:../lib/akka/akka-actor-2.0.3.jar:../lib/akka/config-0.3.1.jar:. Pi.java
3.执行
# java -cp ../lib/scala-library.jar:../lib/akka/akka-actor-2.0.3.jar:../lib/akka/config-0.3.1.jar:. Pi
Pi approximation: 3.1415926435897883
Calculation time: 744 milliseconds