Akka.net开发第一个分布式应用

系列主题:基于消息的软件架构模型演变

既然这个系列的主题是”基于消息的架构模型演变“,少不了说说Actor模型。Akka.net是一个基于Actor模型的分布式框架。如果你对分布式应用还非常陌生,当别人在谈”分布式“、”云计算“等名词时你感到茫然,那么本篇文章将带你进行一次分布式开发之旅。

一、什么是Actor模型

Actor模型由Carl Hewitt于上世纪70年代早期提出并在Erlang语言中得到了广泛应用,目的是为了解决分布式编程中一系列问题。其主要特点如下:

  • 系统由Actor构成
  • Actor之间完全独立
  • 消息传递是非阻塞和异步的
  • 所有消息发送都是并行的

在Actor模型中Everything is an Actor。为什么感觉忽悠又开始了。。。

如果你看过了我写的”基于消息的架构演变“系列,你就会发现软件系统从观察者模式到事件然后再到消息,经过了不断的抽象。当软件通过消息来交互的时候再没有了直接引用,没有了耦合,所有的一切都变成了异步和并行。这时候再加上分布式支持,云计算也就变成了可能。

二、什么是Akka.net

Akka是一个基于scala语言的Actor模型库,旨在构建一套高并发、分布式、自动容错、消息驱动应用的工具集。Akka.net则是C#写的Akka版本,并且有很友好的F#Api接口。git地址:https://github.com/akkadotnet/akka.net

出自微软研究院的另一个Actor模型库:Orleans。此项目旨在提供分布式、高伸缩性的云计算框架。git地址:https://github.com/dotnet/orleans,我随后将写关于orleans的入门文章,请关注。

三、响应式宣言

说到Akka.net不得不提到响应式宣言。随着互联网和软件行业的发展,早先的软件架构已经不适应社会发展的需求。软件系统的架构应该具备:弹性、松耦合、可伸缩性,更加容易开发和维护,发生错误时能够自我容错。所以响应式系统的概念随之而来:

  • Responsive:The system responds in a timely manner if at all possible(系统应尽可能的及时响应)
  • Resilient: The system stays responsive in the face of failure(系统在发生错误时任然能够及时响应)
  • Elastic: The system stays responsive under varying workload(系统在各种负载之下都能及时响应)
  • Message Driven: Reactive Systems rely on asynchronous message-passing to establish a boundary between components that ensures loose coupling, isolation, location transparency, and provides the means to delegate errors as messages.(反应式系统依赖于异步消息组件之间建立边界确保松耦合、隔离、位置透明并提供委托错误消息的手段,这句翻译的有点不够准确)

之所以要提到这个宣言是因为Akka.net正是这样一个能够帮你建立响应式系统的框架。

四、从HelloWorld开始

1、新建一个Console Application

2、从Nuget中安装Akka

3、新建一个GreetMessage类来通知Actor

1
2
3
public class GreetingMessage
{
}

3、重点来了,既然在Akka.net中一切都是Actor,那么我们想要输出一个”Hello world”也需要通过一个Actor来完成。新建GreetingActor类:

1
2
3
4
5
6
7
public class GreetingActor : ReceiveActor
{
    public GreetingActor()
    {
        Receive<GreetMessage>(greet =>Console.WriteLine("Hello World"));
    }
}

正如代码所示:当Actor收到GreetMessage消息时,输出”Hello World”。

4、在Main方法中发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
static void Main(string[] args)
{
    // Create a new actor system (a container for your actors)
    var system = ActorSystem.Create("MySystem");
 
    // Create your actor and get a reference to it.
    var greeter = system.ActorOf<GreetingActor>("greeter");
 
    // Send a message to the actor
    greeter.Tell(new GreetingMessage());
 
    Console.ReadLine();
}

一个ActorSystem是一组Actor的容器。

1
var greeter = system.ActorOf<GreetingActor>("greeter");

创建了一个名为"greeter”的Actor。

1
greeter.Tell(new GreetingMessage());

向greeter这个Actor发送GreetMessage消息。

Ctrl+F5跑起来看看:

这个例子虽然和简单,但是向大家展示了Akka.net中如何使用消息和Actor。

五、开发一个分布式的HelloWorld

这个HelloWorld它的NB之处在于它不是一个简单的HelloWorld,他是一个分布式的HelloWorld。。。

既然是分布式,我们需要建立两个Console Application分别部署在云端和本地,另外新建一个Class liabrary项目用来放公用的message等类型。

这次Client和Server两个项目都需要从Nuget中安装Akka.Remote用来远程通信。

先从Client端开始说起:

1、既然涉及到了远程通信,免不了要配置本地的地址,通信协议,端口等信息。所有的这些配置都可以配置到web.config中。Akka.net使用HOCON(Human-Optimized Config Object Notation)的格式来配置,为了简单期间,我们将这个配置直接写到代码里-其实内容跟写web.config是一样的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var config = ConfigurationFactory.ParseString(@"
akka { 
    actor {
        provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
    }
    remote {
        helios.tcp {
            transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
            applied-adapters = []
            transport-protocol = tcp
            port = 0
            hostname = localhost
        }
    }
}
");

你可以看到这个配置描述了远程通信的provider、使用了helios来做TCP通信,另外定义了client的hostname,端口号等。

2、定义Client端的ActorSystem,并向远程发送消息

1
2
3
4
5
6
7
8
9
10
11
12
13
using (var system = ActorSystem.Create("MyClient", config))
    {
        var greeting = system.ActorSelection("akka.tcp://MyServer@localhost:8081/user/Greeting");
 
        while (true)
        {
            var input = Console.ReadLine();
            if (input.Equals("sayHello"))
            {
                greeting.Tell(new GreetingMessage());
            }
        }
    }

这次的重点在于创建Actor是通过system.ActorSelection方法来实现,因为此Actor在云端,我们没有通过引用云端的程序集,而是通过云端的Actor地址akka.tcp://MyServer@localhost:8081/user/Greeting来访问GreetingActor。MyServer是云端的ActorSystem名称,localhost:8081是云端的地址和ip,由于我们在本地模拟,所以任然为localhost。user/Greeting表示我们要选取名称为Greeting的Actor。

当用户在client端输入"sayHello"之后,会向GreetingActor发送一个GreetingMessage的消息。

3、Server端的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var config = ConfigurationFactory.ParseString(@"
akka { 
    actor {
        provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote""
    }
    remote {
        helios.tcp {
            transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote""
            applied-adapters = []
            transport-protocol = tcp
            port = 8081
            hostname = localhost
        }
    }
}
");

Server端的配置跟Client端大同小异,只是拥有不同的端口号,如果部署在云端,应该输入云端的ip。

4、Server端的ActorSystem

1
2
3
4
5
6
using (var system = ActorSystem.Create("MyServer", config))
  {
      system.ActorOf<GreetingActor>("Greeting");
 
      Console.ReadLine();
  }

这个代码很简单,跟第一个例子中的代码有点相似。

5、运行

在解决方案中把Client和Server同时设置为启动项

然后Ctrl+F5,在client中输入"sayHello"之后,sever端会输出Hello World。

六、Actor结构

Akka.net中的Actor是一个具有层级结构的模型,每个ActorSystem都有多个Actor构成,而每个父Actor又可以创建自己的子Actor,对应到业务处理过程中,不同的Actor可以模拟面向对象的结构来处理具体的工作。而这个过程又可以分布在不同的服务器上,从而构成了一套完整的分布式计算系统。

七、总结

本文提到的例子非常简单,但是展示了Actor和基于消息通信的方式。Akka.net的强大之处在于它不仅像ESB那样解决消息的生产和消费,而且他提供了Actor并行消费消息的策略和机制,他更多的强调如何让大量的Actor之间协调工作,从而构建分布式和响应式的系统。

使用Akka.net还可以轻松实现CQRS,如果说DDD玩的是面向对象分析,那么Akka.net将为你解决剩下的技术细节。已经有人使用scala在Akka上进行这样的尝试ddd-leaven-akka,期待.net平台下也有更好的应用让我们进一步去学习和了解。

 
分类: .NET

Akka.net开发第一个分布式应用的更多相关文章

  1. 使用Akka.net开发第一个分布式应用

    系列主题:基于消息的软件架构模型演变 既然这个系列的主题是"基于消息的架构模型演变",少不了说说Actor模型.Akka.net是一个基于Actor模型的分布式框架.如果你对分布式 ...

  2. Electron-使用Electron开发第一个应用

    使用Electron开发第一个应用 Electron 应用的目录结构如下: app/ ├── package.json ├── main.js └── index.html 新建一个app文件夹 将这 ...

  3. Cordova - 使用Cordova开发iOS应用实战1(配置、开发第一个应用)

    Cordova - 使用Cordova开发iOS应用实战1(配置.开发第一个应用) 现在比较流行使用 html5 开发移动应用,毕竟只要写一套html页面就可以适配各种移动设备,大大节省了跨平台应用的 ...

  4. iOS开发——高级技术精选&底层开发之越狱开发第一篇

    底层开发之越狱开发第一篇 做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结.个人不推荐使用盗版,这里主要以技术介绍为主. 这个系列里面主要介绍怎样进 ...

  5. 【翻译习作】 Windows Workflow Foundation程序开发-第一章05

    1.3      开发我们的第一个工作流 也许你曾经在这样的产品经理手下搞过开发:他总是在你身边转悠,并不时的问一句“你还没做完吗?”.在这一部分,我们将用一个简单的Windows Workflow程 ...

  6. 【翻译习作】 Windows Workflow Foundation程序开发-第一章04

    1.2.3  Windows Workflow运行时 从Windows Workflow的角度看,可以将工作流活动当成是交给一个工作流处理器去执行的一系列指令或操作码.在Windows Workflo ...

  7. 【翻译习作】 Windows Workflow Foundation程序开发-第一章03

    1.2.2.Visual Studio 2005扩展包 微软也为Windows Workflow开发者提供了Visual Studio 2005扩展包.扩展包将许多功能集成到Visual Studio ...

  8. 【翻译习作】 Windows Workflow Foundation程序开发-第一章02

    1.2      Windows Workflow概览 微软的Windows Workflow Foundation(简称WF)是.NET框架3.0版的一部分..NET3.0其它主要部分是Window ...

  9. EJB开发第一个无状态会话bean、开发EJBclient

    开发第一个无状态会话bean EJB中的三中bean: 会话Bean(Session Bean) 负责与client交互,是编写业务逻辑的地方.在会话bean中能够通过JDBC直接操作数据库.但大多数 ...

随机推荐

  1. VBoxGuestAdditions.iso下载地址

    http://download.virtualbox.org/virtualbox/4.1.2/VBoxGuestAdditions_4.1.2.iso 其它版本号可依次判断..

  2. struts(三)——struts框架实现登录示例

    前两篇讲解了struts框架的基本实现,自己感觉讲的也有些枯燥,今天拿登录的例子来做一个实现. 1.新建一个javaweb项目,并将struts的jar包拷贝到WebRoot/WEB-INF/lib下 ...

  3. Velocity缓存与穿透(转)

    原文  http://fantaxy025025.iteye.com/blog/2283904 主题 Java 总评:只是标记一下这种用法hack方法.这种场景下用这种方法还是比较雷人的. Veloc ...

  4. Xamarin 安装步骤

    原文:Xamarin 安装步骤 1.下载并解压吾乐吧软件站提供的“Mono for Android 离线包” 安装:jdk-6u45-windows-i586.exe (就算你是64位系统,也要安装i ...

  5. Windows Phone开发(37):动画之ColorAnimation

    原文:Windows Phone开发(37):动画之ColorAnimation 上一节中我们讨论了用double值进行动画处理,我们知道动画是有很多种的,今天,我向大家继续介绍一个动画类--Colo ...

  6. leetcode第一刷_Pow(x, n)

    高速乘方的算法,写了好多变,出了各种错,真是服了我自己了. 思想是每次对n减半,将当前的temp平方.须要注意的是假设当前的n是个奇数,减半之后会丢失掉一次乘积,因此假设当前的n为奇数,应该先在结果里 ...

  7. HDU1028Ignatius and the Princess III母函数入门

    这个题也能够用递归加记忆化搜索来A,只是因为这题比較简单,所以用来做母函数的入门题比較合适 以展开后的x4为例,其系数为4,即4拆分成1.2.3之和的拆分数为4: 即 :4=1+1+1+1=1+1+2 ...

  8. USACO comehome Dijkstra

    USER: Kevin Samuel [kevin_s1] TASK: comehome LANG: C++ Compiling... Compile: OK Executing... Test 1: ...

  9. shell脚本中的数学运算

    shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法.以后用到的时候能够来看,呵呵 1.错误方法举例 a) var=1+1 echo $var 输出的结果是1+1 ...

  10. Ctrl+Alt+T 文档大纲