博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Akka.net路径里的user
阅读量:5339 次
发布时间:2019-06-15

本文共 11397 字,大约阅读时间需要 37 分钟。

  因为经常买双色球,嫌每次对彩票号麻烦,于是休息的时候做了个双色球兑奖的小程序,做完了发现业务还挺复杂的,于是改DDD重做设计,拆分服务,各种折腾...,不过这和本随笔没多大关系,等差不多了再总结一下,有空就写出来。

  上面说了拆服务,拆成了录入,开奖,兑奖三个服务,三个服务开始是用消息队列的,不过后来发现其实就是服务的领域对象之间的交互,就联想到了Actor,面向对象于是一切都是对象,actor也是一切都是actor,看着就门当户对,于是就干掉消息队列。。。细节以后有机会再说。

  上面其实也和这随笔没啥关系,有关系的是,因为时间关系,没去了解akka的文档,于是好奇一件事,服务器连接地址中的"user"是哪来的:

//var section = (AkkaConfigurationSection)ConfigurationManager.GetSection("akka");

//using (var system = ActorSystem.Create("TestClient", section.AkkaConfig))

using (var system = ActorSystem.Create("TestClient"))            {                var actor = system.ActorSelection("akka.tcp://TestServer@localhost:8081/user/tester");                while (true)                {                    var input = Console.ReadLine();                    if (input.Equals("1"))                    {                        actor.Tell(new DTO("11111"));                    }                    else if (input.Equals("2"))                    {                        actor.Tell(new DTO("22222"));                    }                    else                    {                        actor.Tell(new DTO("H W"));                    }                }            }

    上面是客户端,下面是服务端:

1             var config = ConfigurationFactory.ParseString(@" 2             akka {   3                 actor { 4                     provider = ""Akka.Remote.RemoteActorRefProvider, Akka.Remote"" 5                 } 6                 remote { 7                     helios.tcp { 8                         transport-class = ""Akka.Remote.Transport.Helios.HeliosTcpTransport, Akka.Remote"" 9                         applied-adapters = []10                         transport-protocol = tcp11                         port = 808112                         hostname = localhost13                     }14                 }15             }16             ");17 18             using (var system = ActorSystem.Create("TestServer", config))19             {20                 system.ActorOf
("tester");21 22 Console.ReadLine();23 }

  文档想必很多,最近有别的要看,于是想想看看代码得了,反正一时还不会用到生产环境,到时候再说吧,先解决好奇的问题。

  于是首先是ActorSystem的实现类ActorSystemImpl,system.ActorOf<TestDTOActor>("tester")对服务端路径影响的应该是ActorOf:

public override IActorRef SystemActorOf
(string name = null) { return _provider.SystemGuardian.Cell.ActorOf
(name); }

  于是找找_provider:

public ActorSystemImpl(string name, Config config)        {            if(!Regex.Match(name, "^[a-zA-Z0-9][a-zA-Z0-9-]*$").Success)                throw new ArgumentException(                    "invalid ActorSystem name [" + name +                    "], must contain only word characters (i.e. [a-zA-Z0-9] plus non-leading '-')");            if(config == null)                throw new ArgumentNullException("config");            _name = name;                        ConfigureSettings(config);            ConfigureEventStream();            ConfigureProvider();            ConfigureTerminationCallbacks();            ConfigureScheduler();            ConfigureSerialization();            ConfigureMailboxes();            ConfigureDispatchers();            ConfigureActorProducerPipeline();        }        private void ConfigureSettings(Config config)        {            _settings = new Settings(this, config);        }        private void ConfigureProvider()        {            Type providerType = Type.GetType(_settings.ProviderClass);            global::System.Diagnostics.Debug.Assert(providerType != null, "providerType != null");            var provider = (IActorRefProvider)Activator.CreateInstance(providerType, _name, _settings, _eventStream);            _provider = provider;        }
public Settings(ActorSystem system, Config config)        {            _userConfig = config;            _fallbackConfig = ConfigurationFactory.Default();                        RebuildConfig();            System = system;                        ConfigVersion = Config.GetString("akka.version");            ProviderClass = Config.GetString("akka.actor.provider");            var providerType = Type.GetType(ProviderClass);            if (providerType == null)                throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid type name : '{0}'", ProviderClass));            if (!typeof(IActorRefProvider).IsAssignableFrom(providerType))                throw new ConfigurationException(string.Format("'akka.actor.provider' is not a valid actor ref provider: '{0}'", ProviderClass));                        SupervisorStrategyClass = Config.GetString("akka.actor.guardian-supervisor-strategy");            AskTimeout = Config.GetTimeSpan("akka.actor.ask-timeout", allowInfinite: true);            CreationTimeout = Config.GetTimeSpan("akka.actor.creation-timeout");            UnstartedPushTimeout = Config.GetTimeSpan("akka.actor.unstarted-push-timeout");            SerializeAllMessages = Config.GetBoolean("akka.actor.serialize-messages");            SerializeAllCreators = Config.GetBoolean("akka.actor.serialize-creators");            LogLevel = Config.GetString("akka.loglevel");            StdoutLogLevel = Config.GetString("akka.stdout-loglevel");            Loggers = Config.GetStringList("akka.loggers");            LoggerStartTimeout = Config.GetTimeSpan("akka.logger-startup-timeout");            //handled            LogConfigOnStart = Config.GetBoolean("akka.log-config-on-start");            LogDeadLetters = 0;            switch (Config.GetString("akka.log-dead-letters"))            {                case "on":                case "true":                    LogDeadLetters = int.MaxValue;                    break;                case "off":                case "false":                    LogDeadLetters = 0;                    break;                default:                    LogDeadLetters = Config.GetInt("akka.log-dead-letters");                    break;            }            LogDeadLettersDuringShutdown = Config.GetBoolean("akka.log-dead-letters-during-shutdown");            AddLoggingReceive = Config.GetBoolean("akka.actor.debug.receive");            DebugAutoReceive = Config.GetBoolean("akka.actor.debug.autoreceive");            DebugLifecycle = Config.GetBoolean("akka.actor.debug.lifecycle");            FsmDebugEvent = Config.GetBoolean("akka.actor.debug.fsm");            DebugEventStream = Config.GetBoolean("akka.actor.debug.event-stream");            DebugUnhandledMessage = Config.GetBoolean("akka.actor.debug.unhandled");            DebugRouterMisconfiguration = Config.GetBoolean("akka.actor.debug.router-misconfiguration");            Home = Config.GetString("akka.home") ?? "";            DefaultVirtualNodesFactor = Config.GetInt("akka.actor.deployment.default.virtual-nodes-factor");            SchedulerClass = Config.GetString("akka.scheduler.implementation");            //TODO: dunno.. we dont have FiniteStateMachines, dont know what the rest is            /*                              final val SchedulerClass: String = getString("akka.scheduler.implementation")                final val Daemonicity: Boolean = getBoolean("akka.daemonic")                                final val DefaultVirtualNodesFactor: Int = getInt("akka.actor.deployment.default.virtual-nodes-factor")             */        }

  很明显,看配置文件的akka.actor.provider:

  于是RemoteActorRefProvider:

public LocalActorRef SystemGuardian { get { return _local.SystemGuardian; } }        public RemoteActorRefProvider(string systemName, Settings settings, EventStream eventStream)        {            settings.InjectTopLevelFallback(RemoteConfigFactory.Default());            var remoteDeployer = new RemoteDeployer(settings);            Func
deadLettersFactory = path => new RemoteDeadLetterActorRef(this, path, eventStream); _local = new LocalActorRefProvider(systemName, settings, eventStream, remoteDeployer, deadLettersFactory); RemoteSettings = new RemoteSettings(settings.Config); Deployer = remoteDeployer; _log = _local.Log; }

  好吧,看LocalActorRefProvider:

public void Init(ActorSystemImpl system)        {            _system = system;            //The following are the lazy val statements in Akka            var defaultDispatcher = system.Dispatchers.DefaultGlobalDispatcher;            _defaultMailbox = () => new ConcurrentQueueMailbox(); //TODO:system.Mailboxes.FromConfig(Mailboxes.DefaultMailboxId)            _rootGuardian = CreateRootGuardian(system);            _tempContainer = new VirtualPathContainer(system.Provider, _tempNode, _rootGuardian, _log);            _rootGuardian.SetTempContainer(_tempContainer);            _userGuardian = CreateUserGuardian(_rootGuardian, "user");            _systemGuardian = CreateSystemGuardian(_rootGuardian, "system", _userGuardian);            //End of lazy val            _rootGuardian.Start();            // chain death watchers so that killing guardian stops the application            _systemGuardian.Tell(new Watch(_userGuardian, _systemGuardian));    //Should be SendSystemMessage            _rootGuardian.Tell(new Watch(_systemGuardian, _rootGuardian));      //Should be SendSystemMessage            _eventStream.StartDefaultLoggers(_system);        }
private LocalActorRef CreateUserGuardian(LocalActorRef rootGuardian, string name)   //Corresponds to Akka's: override lazy val guardian: LocalActorRef        {            return CreateRootGuardianChild(rootGuardian, name, () =>            {                var props = Props.Create
(UserGuardianSupervisorStrategy); var userGuardian = new LocalActorRef(_system, props, DefaultDispatcher, _defaultMailbox, rootGuardian, RootPath/name); return userGuardian; }); }

  看样子,这个RootPath还重载了操作符:

public static ActorPath operator /(ActorPath path, string name)        {            return new ChildActorPath(path, name, 0);        }        public static ActorPath operator /(ActorPath path, IEnumerable
name) { var a = path; foreach (string element in name) { a = a / element; } return a; }

   现在_userGuardian路径是看到了,生拼上去的,那么哪里用的呢

LocalActorRefProvider:     public LocalActorRef Guardian { get { return _userGuardian; } }RemoteActorRefProvider:     public LocalActorRef Guardian { get { return _local.Guardian; } }

  再回来看system.ActorOf<TestDTOActor>("tester")这句:

public override IActorRef ActorOf(Props props, string name = null)        {            return _provider.Guardian.Cell.ActorOf(props, name: name);        }

  这就是我自己配的provider造成的,其实还是配置问题,当然,这么看我们其实可以实现自己的provider,想怎么搞就怎么搞,有时间其实还是应该看下文档,不过想来文档应该会说怎么用什么样,当应该不会说怎么实现的,要知道为什么,怎么改,估计还是要自己看代码,此致。

转载于:https://www.cnblogs.com/saaav/p/5250647.html

你可能感兴趣的文章
luoguP3414 SAC#1 - 组合数
查看>>
五一 DAY 4
查看>>
(转)接口测试用例设计(详细干货)
查看>>
【译】SSH隧道:本地和远程端口转发
查看>>
win8.1安装Python提示缺失api-ms-win-crt-runtime-l1-1-0.dll问题
查看>>
图片点击轮播(三)-----2017-04-05
查看>>
直播技术细节3
查看>>
《分布式服务架构:原理、设计于实战》总结
查看>>
java中new一个对象和对象=null有什么区别
查看>>
字母和数字键的键码值(keyCode)
查看>>
IE8调用window.open导出EXCEL文件题目
查看>>
Spring mvc初学
查看>>
有意思的代码片段
查看>>
C8051开发环境
查看>>
VTKMY 3.3 VS 2010 Configuration 配置
查看>>
01_1_准备ibatis环境
查看>>
windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决
查看>>
JavaScript中的BOM和DOM
查看>>
360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)
查看>>
spring注入Properties
查看>>