閱讀689 返回首頁    go 技術社區[雲棲]


Akka簡單性能分析

因為最近工作的關係,要把異步任務從應用服務器中拆分到專門的異步處理服務器中。

方案一

是采用MQ的方式將任務消息發出,在服務端進行處理,如下圖所示:

Sample Flowchart Template (2).png

這種方案是采用MQ作為中間的媒介,在服務端采用線程池異步處理任務,處理完成之後將結果發送到MQ中,客戶端采用偵聽的方式得到結果繼續進行處理。

這種方案的不足是,可能在某些需求的情況下,需要將結果存放到共享的HashMap或者Threadlocal中進行存放結果,客戶端會一直阻塞,直到得到結果,從多線程的角度來說,還是用了共享變量,雖然共享變量可能是線程安全的,但是從並發模型的角度來講,並不是一個最好的方式。

方案二

采用比較流行的Akka框架來實現。
Akka的五大特性

  • 易於構建並行和分布式應用
  • 可靠性(Resilient by Design)
    係統具備自愈能力,在本地/遠程都有監護。
  • 高性能(High Performance)
    在單機中每秒可發送50000000個消息。內存占用小,1GB內存中可保存2500000個actors。
  • 彈性,無中心(Elastic — Decentralized)
    自適應的負責均衡,路由,分區,配置
  • 可擴展(Extensible) 可以使用Akka 擴展包進行擴展。

因為之前一直研究Scala,Scala的多線程處理的性能是非常高的,那基於Scala語言而開發出來的Akka框架得到了廣泛使用。那麼接下來我將使用一個非常簡單的例子,以及一些測試用例展現一下它的性能。
代碼如下:

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.actor.UntypedActor;

/**
 * PROJECT_NAME: akkademo
 * DATE:         16/2/27
 * CREATE BY:    chao.cheng
 **/
public class ToStringActor extends UntypedActor {
    @Override
    public void onReceive(Object message) {
        System.out.println(message.toString());
        try {
            Thread.sleep(500);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void main(String[] args) {
        ActorSystem system = ActorSystem.create("toStringActor");
        final ActorRef toString = system.actorOf(Props.create(ToStringActor.class),"toString");
        for(int i=0;i<10000000;i++) {
            toString.tell("test"+i,toString);
        }
        System.out.println("[結束]=======================");
    }
}

程序的簡單說明:
采用事件的機製,循環發送一千萬條數據,通過onReceive方法異步處理任務。

用VisualVM工具截圖可以看到:

DFF8C31B-3886-4F75-A56B-EA78F85A6067.png

後台其實自適應隻起了三個線程在運行,分別是dispatcher-2,dispatcher-3,dispatcher-4。

最後更新:2017-05-19 17:32:05

  上一篇:go  跟我學Kafka之Controller控製器詳解
  下一篇:go  圖解微服務架構演進