Example #1
0
        /// <summary>
        /// 开启套接字监听
        /// 向主节点发送登记,登记成功,并返回可用的端口,然后开启指定端口的子节点server
        /// </summary>

        public static void Start()
        {
            try
            {
                if (false == GlobalContext.IsConfigClusteringMode)//是否开启集群模式
                {
                    return;
                }

                //一旦主控节点开启并正确返回结果
                if (!MasterRemoteServer.IsMasterStarted())
                {
                    return;
                }

                //进入监控进程broker
                AppBroker.MonitorIsMasterCenterAlive();

                int port = 0;

                var slaveIdentity = Guid.NewGuid().ToString().ToLower();
                //开启监听前 ,发送注册当前从节点到主节点,如果可以登记注册成功,那么服务端分配端口
                port = MasterRemoteServer.RegisterSlaveToMaster(slaveIdentity);
                int counter = 1;
                //注册失败后 再次尝试3次
                while (port <= 0 && counter <= 3)
                {
                    port     = MasterRemoteServer.RegisterSlaveToMaster(slaveIdentity);
                    counter += 1;
                    RunningLocker.CreateNewLock().CancelAfter(1000);//延迟并发,防止端口资源抢占
                }
                if (port <= 0)
                {
                    Console.WriteLine("未成功注册从节点端口!");
                    return;//一旦服务端返回无效端口 那么禁止从节点启动监听
                }



                listener = new NTCPMessage.Server.NTcpListener(new IPEndPoint(IPAddress.Any, port));
                listener.DataReceived       += new EventHandler <ReceiveEventArgs>(ReceiveEventHandler);
                listener.ErrorReceived      += new EventHandler <ErrorEventArgs>(ErrorEventHandler);
                listener.RemoteDisconnected += new EventHandler <DisconnectEventArgs>(DisconnectEventHandler);

                GlobalContext.IsInSlaveMode = true;//标识正在从节点下工作

                //开启从节点的监听
                listener.Listen();
            }

            catch (Exception ex)
            {
                Logger.Error(ex);
            }


            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
        }
 /// <summary>
 /// 构造函数
 /// </summary>
 /// <param name="SellerId"></param>
 /// <param name="ItemId"></param>
 public YouhuiquanExistsTaskBuffer(long SellerId, long ItemId)
 {
     this.cancelTokenSource   = new CancellationTokenSource();
     this.TaskBufferQueue     = new System.Collections.Concurrent.ConcurrentQueue <FuncForQueryQuanExists>();
     this.OnQueryQuanComplete = this.OnCompleteTaskHandler;
     //this.TaskAssertFunc = this.OnCompleteTaskHandler;
     this.ResultModel          = new YouhuiquanExistsModel();
     this.ResultModel.SellerId = SellerId;
     this.ResultModel.ItemId   = ItemId;
     //构建任务标识 空委托,依赖取消任务标识 判定任务的完成
     this.QueryTaskEndPoint = new Task(() =>
     {
         RunningLocker.CreateNewLock().Pause();
     }, this.cancelTokenSource.Token);
 }
Example #3
0
        public static int Init(string[] args)
        {
            //1 设定当前程序运行的主上下文
            GlobalContext.SyncContext = SynchronizationContext.Current;



            //1-1 集群节点的判定 一旦进程启动参数有此标识,那么表示是子节点进程需要启动
            //子节点仅仅用来做负载均衡的分流,不承载cef 运行时
            //"type=slavemode mainProcessId={0}";
            if (null != args &&
                string.Concat(args).Contains("slavemode"))
            {
                GlobalContext.IsInSlaveMode = true;
                //从启动参数 获取主进程的id
                var paramProcess = args.FirstOrDefault(x => x.Contains("mainProcessId"));
                if (null != paramProcess)
                {
                    GlobalContext.MainProcessId = int.Parse(paramProcess.Split('=')[1]);
                    SlaveRemoteServer.Start();
                }

                return(0);//子节点的进程启动完毕后,返回
            }


            //2 初始化CEF运行时
            #region 初始化CEF运行时

            try
            {
                //加载CEF 运行时  lib cef
                CefRuntime.Load();

                var mainArgs = new CefMainArgs(args);
                var app      = new HeadLessWebBrowerApp();


                //执行CEF启动进程,如果是二级进程 ,那么执行后返回exitCode,启动进程是 -1

                /*// CefExecuteProcess returns -1 for the host process
                 * CefExecuteProcess()方法来检测是否要启动其它的子进程。此处的CefExecuteProcess是在libcef_dll_wrapper.cc中的,它内部又调用了cef_execute_process方法(libcef_dll.cc),cef_execute_process又调用了libcef/browser/context.cc文件内实现的CefExecuteProcess方法
                 * 它分析了命令行参数,提取”type”参数,如果为空,说明是Browser进程,返回-1,这样一路回溯到wWinMain方法里,然后开始创建Browser进程相关的内容。
                 * 如果”type”参数不为空,做一些判断,最后调用了content::ContentMain方法,直到这个方法结束,子进程随之结束。
                 *  */

                var exitCode = CefRuntime.ExecuteProcess(mainArgs, app, IntPtr.Zero);
                if (exitCode != -1)
                {
                    return(exitCode);
                }

                //一旦为 -1 ,那么表示为Host  进程,对cef  运行时进行初始化操作---

                // CEF的配置参数,有很多参数,我们这里挑几个解释一下:
                //SingleProcess = false:此处目的是使用多进程。
                //注意: 强烈不建议使用单进程,单进程不稳定,而且Chromium内核不支持
                //MultiThreadedMessageLoop = true:此处的目的是让浏览器的消息循环在一个单独的线程中执行
                //注意: 强烈建议设置成true,要不然你得在你的程序中自己处理消息循环;自己调用CefDoMessageLoopWork()
                //Locale = "zh-CN":webkit用到的语言资源,如果不设置,默认将为en - US
                //注意: 可执行文件所在的目录一定要有locals目录,而且这个目录下要有相应的资源文件

                var settings = new CefSettings
                {
                    // BrowserSubprocessPath = @"D:\fddima\Projects\Xilium\Xilium.CefGlue\CefGlue.Demo\bin\Release\Xilium.CefGlue.Demo.exe",
                    SingleProcess              = false, //开启多进程模型,tab  进程独立模式
                    MultiThreadedMessageLoop   = true,  //开启多线程任务
                    WindowlessRenderingEnabled = true,  //开启无头模式
                                                        //Locale = "en-US",
                    LogSeverity = CefLogSeverity.Disable,
                    //LogFile = "CefGlue.log",
                    PersistSessionCookies = true,
                    UserAgent             = GlobalContext.ChromeUserAgent,
                    UserDataPath          = System.IO.Path.Combine(Environment.CurrentDirectory, "UserData"),
                    CachePath             = System.IO.Path.Combine(Environment.CurrentDirectory, "LocalCache")
                };


                // DevTools doesn't seem to be working when this is enabled
                // http://magpcss.org/ceforum/viewtopic.php?f=6&t=14095



                // Disable GPU in WPF and Offscreen examples until #1634 has been resolved
                //settings.CefCommandLineArgs.Add("disable-gpu", "1");
                //初始化  CEF进程参数设置
                CefRuntime.Initialize(mainArgs, settings, app, IntPtr.Zero);
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
                return(3);
            }

            #endregion


            //3 开启总控TCP端口,用来接收站点的请求--开启后 会阻塞进程 防止结束
            // 总控端口 负责 1 收集请求 响应请求 2 收集分布的采集客户端 登记注册可用的端,用来做CDN 任务分发,做负载均衡
            MasterRemoteServer.Start();
            #region 开启集群模式
            if (GlobalContext.IsConfigClusteringMode)
            {
                var clusterNodeCount = ConfigHelper.GetConfigInt("ClusterNodeCount");
                if (clusterNodeCount <= 0)
                {
                    clusterNodeCount = 1;
                }

                try
                {
                    //清理残留进程
                    AppBroker.ClearGarbageProcess();

                    var    mainProcess = Process.GetCurrentProcess();
                    string appName     = Assembly.GetExecutingAssembly().GetName().Name;
                    //开启子节点进程
                    for (int i = 0; i < clusterNodeCount; i++)
                    {
                        Process p = new Process();
                        p.StartInfo.FileName        = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, string.Format("{0}.exe", appName));
                        p.StartInfo.Arguments       = string.Format(GlobalContext.SlaveModelStartAgrs, mainProcess.Id);//集群节点的启动参数标识
                        p.StartInfo.UseShellExecute = true;
                        p.StartInfo.WindowStyle     = ProcessWindowStyle.Hidden;
                        p.Start();
                        //延迟启动下一个从节点进程,防止并发分配端口资源导致失败
                        RunningLocker.CreateNewLock().CancelAfter(1000);
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }
            }
            #endregion


            //4 定时清理器
            #region 定时清理控制台
            //ConsoleClean.Start();
            #endregion

            //5 阿里妈妈等平台登录
            #region  阿里妈妈等平台网页初始化操作



            //----------注意:由于开启了多进程模型,不同的网址在不同的tab,每个tab 在其独立的进程中-------
            //每次打开一个程序进程,让进程开启一个端口server,向总控端口,发送注册登记,用来接受请求转发,做负载均衡---

            //初始化平台网页进程
            //1 通过反射 获取所有的webpage service --正式版

            var ass                 = Assembly.GetExecutingAssembly();
            var typeFinder          = new AppDomainTypeFinder();
            var targetType          = typeof(BaseWebPageService);
            var webPageServiceTypes = typeFinder.FindClassesOfType(targetType, new Assembly[] { ass }, true);
            if (webPageServiceTypes.IsNotEmpty())
            {
                foreach (Type itemPageService in webPageServiceTypes)
                {
                    #region 没用的服务 先不启用


                    if (typeof(VipWebPageService).Equals(itemPageService))
                    {
                        continue;
                    }
                    if (typeof(MogujieWebPageService).Equals(itemPageService))
                    {
                        continue;
                    }
                    if (typeof(YhdWebPageService).Equals(itemPageService))
                    {
                        continue;
                    }

                    #endregion

                    try
                    {
                        BaseWebPageService servieInstance = Activator.CreateInstance(itemPageService) as BaseWebPageService;
                        //静态属性访问一次 即可触发打开页面
                        var loader = servieInstance.RequestLoader;
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(ex);
                    }
                }
            }

            // --------------测试环境begin 不建议打开多个tabpage,影响测试加载-------------
            //var tmallService = new TmallWebPageService();
            //var loader = tmallService.RequestLoader;

            //var loader_taobao = new TaobaoWebPageService().RequestLoader;
            //var loader_jd = new JingdongWebPageService().RequestLoader;
            //var loader_dangdang = new DangdangWebPageService().RequestLoader;
            //--------------测试环境end-------使用一个tabpage ,即可测试是否正确加载----------


            #endregion


            //6 监视残留的render进程
            AppBroker.MonitorClearRenderProcessByLifeTime();
            return(0);
        }
Example #4
0
        private static void Main(string[] args)
        {
            //破解淘宝客加密的链接

            //string url = "http://s.click.taobao.com/t?spm=1002.8113010.1999451588.1.197829d2xOjGWY&e=m%3D2%26s%3DmP8QGUZCl18cQipKwQzePOeEDrYVVa64LKpWJ%2Bin0XK3bLqV5UHdqU7FFcTKJEXpBuky%2F0Sep%2BFpvEi8xmC0PQfgGrPFD%2FD7ItsJf7xhZUukOrdzMLy3g0C9MWo3ZAy5ZtvIAOb0yL8buZkKjgqa4LRqys2RxTiLmiP8wiUuCvFDEV8PXh1a5UciGQ2l2vvBJoe7ipwP0MtRLBgaW5udaw%3D%3D";

            //string content = new Http.HttpServerProxy().GetRequestTransfer(url,null);


            //var rl = TaobaoWebPageService.GetTaobaoUnionOfficalUrl(url);
            // return;

            try
            {
                //初始化CEF运行时 等操作
                InitApp.Init(args);
            }
            catch (Exception ex)
            {
                // CefRuntime.PostTask(CefThreadId.IO, new MySomeTask());

                // Clean up CEF.
                CefRuntime.Shutdown();
                MasterRemoteServer.Stop();
                Logger.Error(new Exception("未能正确启动CEF爬行蜘蛛!异常信息如下:"));
                Logger.Error(ex);
                return;
            }


            //var locker1 = RunningLocker.CreateNewLock();
            //locker1.CancelAfter(20000);


            //BaseWebPageService etaoWeb = new TaobaoWebPageService();

            //var paras = new NTCPMessage.EntityPackage.Arguments.TaobaoFetchWebPageArgument { KeyWord = "洗面奶男" };

            //var con = etaoWeb.QuerySearchContent(paras);

            //System.Diagnostics.Debug.WriteLine(con.Result);

            //etaoWeb = new JingdongWebPageService();

            // con = etaoWeb.QuerySearchContent(paras);

            //var headlessForm = new HeadLessMainForm();
            //headlessForm.NavigateToUrl("https://pub.alimama.com/myunion.htm?spm=a219t.7900221/1.1998910419.dbb742793.21214865YeCJuR#!/promo/self/items");



            Console.WriteLine("ShoppingWebCrawler.Host is started.....");

            if (null != args &&
                string.Concat(args).Contains("slavemode"))
            {
                Console.WriteLine("SlaveRemoteServer is started.....");
            }

            //注册窗口关闭的时候 退出子进程
            // we have to keep the handler routine alive during the execution of the program,
            // because the garbage collector will destroy it after any CTRL event
            GC.KeepAlive(cancelHandler);
            SetConsoleCtrlHandler(cancelHandler, true);

            var locker = RunningLocker.CreateNewLock();

            locker.Pause();

            //6 主进程退出的事件
        }
        /// <summary>
        /// 自身健康监测
        /// </summary>
        /// <param name="callbackHandlerOnFailed">失败的时候 执行的委托回调</param>
        public void BeginSelfHelthCheck(Action <string> callbackHandlerOnFailed)
        {
            if (isRunningHelthCheck == true)
            {
                return;
            }

            //1 向此节点对应的端口 发送ping
            //2 失败3次  定性为错误无效节点
            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    RunningLocker.CreateNewLock().CancelAfter(1000);

                    try
                    {
                        bool isBeUsed = SocketHelper.IsUsedIPEndPoint(this.Port);
                        if (isBeUsed == false)
                        {
                            if (counterStatusCheck >= 10)
                            {
                                this.IsActiveNode = false;
                                if (null != callbackHandlerOnFailed)
                                {
                                    callbackHandlerOnFailed(this.Identity);
                                }
                                break;
                            }
                            else
                            {
                                counterStatusCheck += 1;
                                continue;//端口暂未开启
                            }
                        }

                        using (var conn = new SoapTcpConnection(this.IpAddress, this.Port, 4))
                        {
                            if (conn.State != ConnectionState.Open)
                            {
                                conn.Open();
                            }
                            var result = conn.Ping();//发送Ping 命令,是否可以ping 通子节点端口
                            if (result != true)
                            {
                                //一旦超过3此ping 不通,表示这是一个坏节点,中集群中心移除此节点--进行回调通知
                                if (this.failCounter >= 2)
                                {
                                    this.IsActiveNode = false;
                                    if (null != callbackHandlerOnFailed)
                                    {
                                        callbackHandlerOnFailed(this.Identity);
                                    }
                                    break;
                                }
                                this.failCounter += 1;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        this.IsActiveNode = false;
                        Common.Logging.Logger.Error(ex);
                        break;
                    }
                }
            });
        }
Example #6
0
        //private static int count = 0;

        /// <summary>
        /// 开启N 个线程,将从redis 中抓取数据进行消费
        /// </summary>
        private static void ProcessMessageDataQueue()
        {
            //var tm = new System.Timers.Timer();
            //tm.Interval = 1000;
            //tm.Elapsed += (s, e) => {
            //    System.Diagnostics.Debug.WriteLine(count);
            //};
            //tm.Start();

            for (int i = 0; i < ExcuteThreadCount; i++)
            {
                var th = new Thread(new ThreadStart(() =>
                {
                    IMessageProcessor QianLangQuanProcessor = new QianLangPlanQuanProcessor();
                    _LstProcessors.Enqueue(QianLangQuanProcessor);

                    while (true)
                    {
                        try
                        {
                            if (_token.IsCancellationRequested == true)
                            {
                                break;//终止信号
                            }

                            ////如果集合都是空 那么等待休眠
                            if (QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.IsEmpty == true)
                            {
                                RunningLocker.CreateNewLock().CancelAfter(1000 * 2);//休眠2秒
                            }

                            //count++;

                            //并行执行
                            Parallel.Invoke(

                                () =>
                            {
                                //处理消息
                                if (QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.IsEmpty)
                                {
                                    return;
                                }
                                var pair = QianLangPlanQuanProcessor.PopOneQianLangQuanMessage();
                                if (default(KeyValuePair <string, IMessage>).Equals(pair))
                                {
                                    return;
                                }
                                string key       = pair.Key;
                                IMessage itemFee = pair.Value;

                                QianLangQuanProcessor.Process(key, itemFee);
                            }



                                );
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                        }
                    }
                }));
                th.IsBackground = true;
                th.Priority     = ThreadPriority.Normal;

                //压入处理线程队列
                _TheadQueuePool_Processor.Enqueue(th);

                th.Start();
            }
        }
Example #7
0
        /// <summary>
        /// 从redis 中不间断的批量读取消息
        /// </summary>
        private static void FetchDataFromRedis()
        {
            while (true)
            {
                RedisCacheManager redisClient = null;
                try
                {
                    if (_token.IsCancellationRequested == true)
                    {
                        break;//终止信号
                    }
                    //目前仅处理千浪计划消息
                    string matchPattern = string.Concat(BaseMessageModel.CachePrefix, "*");



                    //Logging.Logger.Info("组件匹配的键模式:"+matchPattern);

                    redisClient = new RedisCacheManager();
                    var scanResult = redisClient.Scan(matchPattern, 10, _redis_scan_cursor);

                    #region 限流策略---针对不同的积压阶段实施限流措施,防止拖死进程和redis

                    //游标置为0 的时候 标识已经回到起始的位置

                    if (null == scanResult || _redis_scan_cursor == 0)
                    {
                        _sleepTimeSpan = 1000;
                        RunningLocker.CreateNewLock().CancelAfter(_sleepTimeSpan);
                        if (null == scanResult)
                        {
                            continue;//如果null 结果 那么不用继续下面的逻辑
                        }
                    }

                    //积压2000
                    if (QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.Count > 2000)
                    {
                        _sleepTimeSpan = 2000;
                        RunningLocker.CreateNewLock().CancelAfter(_sleepTimeSpan);
                    }
                    //积压5000
                    if (QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.Count > 5000)
                    {
                        _sleepTimeSpan = 3000;
                        RunningLocker.CreateNewLock().CancelAfter(_sleepTimeSpan);
                    }

                    if (QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.Count > 100000)
                    {
                        Logger.Error(new Exception("消费队列过于缓慢!内存积压严重!"));
                        break;
                    }

                    #endregion

                    //回写游标
                    _redis_scan_cursor = scanResult.Cursor;

                    var allKeys = scanResult.Results;
                    if (allKeys.IsEmpty())
                    {
                        RunningLocker.CreateNewLock().CancelAfter(1000);
                        continue;
                    }

                    if (null != allKeys && allKeys.IsNotEmpty())
                    {
                        //var redisClient = new RedisCacheManager().RedisClient;

                        foreach (var key in allKeys)
                        {
                            //Logging.Logger.Info("恭喜大人,key is:"+key);
                            try
                            {
                                var isInHistory = CheckIsInProcessHistory(key);
                                if (isInHistory == true)
                                {
                                    continue;
                                }
                                else
                                {
                                    LocalProcessdHistoryHashTable.Add(key);
                                }

                                //处理管线
                                if (key.Contains(ProcessPipeLine.QianLangPlanQuan.ToString()))
                                {
                                    //将当前扫描的键  获取对象结果,添加到集合中
                                    QianLangQuanMessage item = redisClient.Get <QianLangQuanMessage>(key);
                                    if (null != item)
                                    {
                                        if (!QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.ContainsKey(key))
                                        {
                                            QianLangPlanQuanProcessor.MessageDataQueueOfQianLangQuan.TryAdd(key, item);
                                        }
                                    }
                                }
                                else
                                {
                                    redisClient.Remove(key);
                                    continue;//无效的消息  直接移除掉
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.Error(ex);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Logger.Error(ex);
                }
                finally
                {
                    if (null != redisClient)
                    {
                        redisClient.Dispose();
                    }
                }
            }
        }