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

既然这个系列的主题是”基于消息的架构模型演变“,少不了说说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

    public class GreetingMessage
{
}

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

    public class GreetingActor : ReceiveActor
{
public GreetingActor()
{
Receive<GreetMessage>(greet =>Console.WriteLine("Hello World"));
}
}

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

4、在Main方法中发送消息

        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的容器。

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

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

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是一样的。

 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,并向远程发送消息

        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端的配置

 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

          using (var system = ActorSystem.Create("MyServer", config))
{
system.ActorOf<GreetingActor>("Greeting"); Console.ReadLine();
}

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

5、Server端的GreetingActor几乎跟第一个例子一样,不同之处在于使用了IHandle<TMessage>接口,这样显得Actor职责更加清晰,Actor能够处理哪些消息一目了然。

     public class GreetingActor:TypedActor,IHandle<GreetingMessage>
{
public void Handle(GreetingMessage message)
{
Console.WriteLine("Hello world!");
}
}

6、运行

在解决方案中把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平台下也有更好的应用让我们进一步去学习和了解。

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

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

    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. Delphi容器类之---TList、TObjectList、TComponentList、TClassList

    转载自:http://blog.csdn.net/iseekcode/article/details/4922001 从Delphi5开始VCL中增加了新的Contnrs单元,单元中定义了8个新的类, ...

  2. 【Java EE 学习 79 上】【mybatis 基本使用方法】

    一.简介 mybatis类似于hibernate,都是简化对数据库操作的框架,但是和hibernate不同的是,mybatis更加灵活,整体来说框架更小,这体现在它需要我们手写SQL语句,而hiber ...

  3. 批量下载小说网站上的小说(python爬虫)

    随便说点什么 因为在学python,所有自然而然的就掉进了爬虫这个坑里,好吧,主要是因为我觉得爬虫比较酷,才入坑的. 想想看,你可以批量自动的采集互联网上海量的资料数据,是多么令人激动啊! 所以我就被 ...

  4. POJ 3009 Curling 2.0【带回溯DFS】

    POJ 3009 题意: 给出一个w*h的地图,其中0代表空地,1代表障碍物,2代表起点,3代表终点,每次行动可以走多个方格,每次只能向附近一格不是障碍物的方向行动,直到碰到障碍物才停下来,此时障碍物 ...

  5. Beginning Scala study note(4) Functional Programming in Scala

    1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...

  6. 学习微信小程序之css3display

    一display diaplay改变标签的模式,行内装块级(block),块级转行内(inline) 通过设置display为none,可以 让整个标签在页内移除掉 设置visibility为hidd ...

  7. flume使用示例

    flume的特点: flume是一个分布式.可靠.和高可用的海量日志采集.聚合和传输的系统.支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受 ...

  8. 关于在django框架里取已登录用户名字的问题

    在 views里取值是这样的 request.user.username而在模板页面取值是这样的:{{request.user}} 判断是否通过验证是这样的 {% if request.user.is ...

  9. iOS Start developing ios apps (OC) pdf

    这是苹果官方最后一次更新的基于OC的iOS开发基础教程, 如果英文的看不懂,还有中文的版本哦. 点击下面的链接 好东西,分享给大家! 如果确实有帮到你,麻烦star一下我的github吧!

  10. Chrome一直提示“adobe flash player 因过期而遭阻止” ,如何解决?

    完全不用安装最新版的 Chrome,只需要将 Flash 组件安装一下最新版即可. 并且这里需要的不是网上随处可见的 NPAPI 版本,而是冷门的 PPAPI 版本. 请收藏好这个链接,是某位大牛从 ...