Actor模型

#Actor模型

Actor的目的是爲了解決分佈式編程中的一系列問題。全部消息都是異步交付的,所以將消息發送方與接收方分開,正是因爲這種分離,致使actor系統具備內在的併發性:能夠不受限制地並行執行任何擁有輸入消息的 actor。用Actor寫的程序能夠不用管是怎麼實現的,只用傳遞數據就能夠,操做簡單。固然Actor的NB之處,還在於能夠遠程鏈接,像RPC同樣。下面的例子用的是Nuget中的【Akka】、遠程的【Akka.Remote】ios

#Actor的特色

> 1. 系統由Actor構成
> 2. Actor徹底獨立
> 3. 消息傳遞是非阻塞和異步的
> 4. 全部消息都是並行的編程

#Actor使用

> 能夠經過特定的Actor工具或直接使用編程語言實現Actor模型,目前C#語言中有兩類比較流行,Akka.NET框架和Orleans框架。
> 1. Akka是一個基於scala語言的Actor模型庫,旨在構建一套高併發、分佈式、自動容錯、消息驅動應用的工具集。
> 2. Orleans框架能夠構建大規模、高併發、分佈式應用程序,而不須要學習專業分佈式以及併發知識框架。它是由微軟研究和設計應用於雲計算。併發

簡單Actor例子

public class ActorDemo
{
    public static void Test()
    {
        var system = ActorSystem.Create("test");
        var greeter = system.ActorOf<JasonActor>("jason");

        for (int i = 0; i < 100; i++) {
            Task.Run(() =>  //異步發送數據
            {
                var id = Math.Abs(Guid.NewGuid().GetHashCode());
                greeter.Tell(new JasonMessage() { Id = id, Name = $"{DateTime.Now.Ticks} {id}  {i}  " });
            });
        }
    }
}

/// <summary>
/// Actor可接受消息處理
/// </summary>
public class JasonActor : ReceiveActor {
    public JasonActor() {
        Receive<JasonMessage>(greet => {
            Console.WriteLine($"當前時間:{DateTime.Now.Ticks}, Name:{greet.Name}, Id:{greet.Id} ");
        });
    }
}

/// <summary>
/// 用於傳遞消息的實體類
/// </summary>
public class JasonMessage {
    public long Id { get; set; }
    public string Name { get; set; }
}

遠程Actor

/// <summary>
/// 用於傳遞消息的實體類(公共類庫)
/// </summary>
public class JasonMessage
{
    public long Id { get; set; }
    public string Name { get; set; }
}
//Actor客戶端
namespace AkkaClient
{
    class Program
    {
        static void Main(string[] args)
        {
            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
        }
    }
}
");

            using (var system = ActorSystem.Create("MyClient", config))
            {
                var greeting = system.ActorSelection("akka.tcp://MyServer@localhost:51179/user/Greeting");

                while (true)
                {
                    var input = Console.ReadLine();
                    if (input != "exit")
                    {
                        var id = Math.Abs(Guid.NewGuid().GetHashCode());
                        greeting.Tell(new JasonMessage() { Id = id, Name = $"{DateTime.Now} {input} " });
                    }
                    else
                    {
                        break;
                    }

                }
            }

            Console.WriteLine("Hello World!");
        }
    }
}
//Actor服務端
namespace ServerAkka
{
    class Program
    {
        static void Main(string[] args)
        {
            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 = 51179
            hostname = localhost
        }
    }
}
");

            using (var system = ActorSystem.Create("MyServer", config))
            {
                system.ActorOf<JasonActor>("Greeting");

                Console.ReadLine();
            }

            Console.WriteLine("Hello World!");
        }
    }

    public class JasonActor : UntypedActor
    {
        protected override void OnReceive(object greet)
        {
            var greet1 = (JasonMessage)greet;
            Console.WriteLine($"當前時間:{DateTime.Now.Ticks}, Name:{greet1.Name}, Id:{greet1.Id} ");
        }
    }
}
相關文章
相關標籤/搜索