Ejemplo n.º 1
0
        public async Task <bool> UpdateAsync(int id, SpiderDto viewModel)
        {
            if (ModelState.IsValid)
            {
                var spider = await _dockerCrawlerService.Get <SpiderDto>(x => x.Id == id);

                if (spider == null)
                {
                    throw new ApplicationException($"Spider {id} exists");
                }

                var exists = await _dockerCrawlerService.CountAsync <SpiderDto>(x =>
                                                                                x.Name == viewModel.Name && x.Id != id);

                if (exists > 0)
                {
                    ModelState.AddModelError("Name", "名称已经存在");
                }

                try
                {
                    CrontabSchedule.Parse(viewModel.Cron);
                }
                catch
                {
                    ModelState.AddModelError("Cron", "Cron 表达式不正确");
                }


                spider.Name        = viewModel.Name;
                spider.Cron        = viewModel.Cron;
                spider.Image       = viewModel.Image;
                spider.Volume      = viewModel.Volume;
                spider.Environment = viewModel.Environment;

                spider.LastModificationTime = DateTimeOffset.Now;

                await _dockerCrawlerService.AddOrUpdate <SpiderDto, int>(spider);

                _recurringJobManager.RemoveIfExists(spider.Name);
                await ScheduleJobAsync(spider);



                return(true);
            }
            else
            {
                throw new ApplicationException("ModelState is invalid");
            }
        }
Ejemplo n.º 2
0
        public async Task ExecuteJob(int spiderId)
        {
            var client = new DockerClientConfiguration(
                new Uri(_crawlerOptions.Docker))
                         .CreateClient();

            try
            {
                var containers = await client.Containers.ListContainersAsync(new ContainersListParameters
                {
                    All     = true,
                    Filters = new Dictionary <string, IDictionary <string, bool> >
                    {
                        {
                            "name", new Dictionary <string, bool>
                            {
                                { "dotnetspider*", true }
                            }
                        }
                    }
                });

                foreach (var container in containers)
                {
                    if (container.State == "exited")
                    {
                        await client.Containers.RemoveContainerAsync(container.ID, new ContainerRemoveParameters());
                    }
                }
            }
            catch { }

            try
            {
                _logger.LogInformation($"触发任务 {spiderId}");

                var spider = await _dockerCrawlerService.Get <SpiderDto>(x => x.Id == spiderId);

                if (spider == null)
                {
                    _logger.LogError($"任务 {spiderId} 不存在");
                    return;
                }

                if (!spider.Enabled)
                {
                    _logger.LogError($"任务 {spiderId} 被禁用");
                    return;
                }


                var batch = Guid.NewGuid().ToString("N");
                var env   = new List <string>((spider.Environment ?? "").Split(new[] { " ", "\n" },
                                                                               StringSplitOptions.RemoveEmptyEntries))
                {
                    $"DOTNET_SPIDER_ID={batch}",
                    $"DOTNET_SPIDER_NAME={spider.Name}"
                };

                var name       = $"dotnetspider-{spider.Id}-{batch}";
                var parameters = new CreateContainerParameters
                {
                    Image  = spider.Image,
                    Name   = name,
                    Labels = new Dictionary <string, string>
                    {
                        { "dotnetspider.spider.id", spider.Id.ToString() },
                        { "dotnetspider.spider.batch", batch },
                        { "dotnetspider.spider.name", spider.Name }
                    },
                    Env        = env,
                    HostConfig = new HostConfig()
                };
                var volumes = new HashSet <string>();
                foreach (var volume in _crawlerOptions.DockerVolumes)
                {
                    volumes.Add(volume);
                }

                var configVolumes = new List <string>((spider.Volume ?? "").Split(new[] { " ", "\n" },
                                                                                  StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()));
                foreach (var volume in configVolumes)
                {
                    volumes.Add(volume);
                }

                parameters.HostConfig.Binds       = volumes.ToList();
                parameters.HostConfig.NetworkMode = _crawlerOptions.NetworkMode ?? "";
                parameters.HostConfig.ExtraHosts  = _crawlerOptions.ExtraHosts.ToList();
                var result = await client.Containers.CreateContainerAsync(parameters);

                if (result.ID == null)
                {
                    _logger.LogError($"创建任务 {spiderId} 实例失败: {string.Join(", ", result.Warnings)}");
                }

                var spiderContainer = new SpiderHistoryDto
                {
                    ContainerId  = result.ID,
                    Batch        = batch,
                    SpiderId     = spider.Id,
                    SpiderName   = spider.Name,
                    Status       = "Created",
                    CreationTime = DateTimeOffset.Now
                };

                spiderContainer = await _dockerCrawlerService.AddSpiderContainer(spiderContainer);

                var startResult =
                    await client.Containers.StartContainerAsync(result.ID, new ContainerStartParameters());

                await _dockerCrawlerService.UpdateSpiderContainerStatus(spiderContainer.Id, startResult? "Success" : "Failed");


                _logger.LogInformation($"触发任务 {spiderId} 完成");
            }
            catch (Exception ex)
            {
                _logger.LogError($"触发任务 {spiderId} 失败: {ex}");
            }
        }