Отказ от функции SharePoint убивает пул приложений
Ранее на этой неделе разработчик решений в моей компании недавно предложил всем разработчикам найти ошибку в написанном им коде. Случилось так, что администраторы сборки забрали его пакет решений из SharePoint, когда что-то пошло не так и весь пул приложений умер.
Предполагается, что причиной является одно из следующих:
- Что-то в коде
- Было ли это как-то связано с отказом от решения от центрального администратора?
- C - ничего из вышеперечисленного
- D - все вышеперечисленное
Я просматривал код сегодня, но не смог найти что-нибудь искаженное. Я решил поместить его код здесь и узнать мнение любого, кто заинтересован в его предоставлении. Это не серьезный вопрос, и задача была поставлена в хорошем спорте, поэтому, пожалуйста, просто уделите ему внимание, если вы чувствуете такую склонность.
Сообщение с СД:
Как я упоминал вчера в DevDays, когда администраторы SharePoint отозвали пакет решений CityDepartments из SharePoint, весь пул приложений IIS умер. Это было до того, как задание таймера OWSTIMER.EXE смогло разблокировать все веб-приложения и сайты, которые были заблокированы до того, как фактические функции были деактивированы.
Итак, поскольку никто не знает, что пошло не так, я вознагражу первого человека, который это выяснит (включая меня).
Как и было обещано, если вы обнаружите проблему в одном из событий FeatureDeactivating, вызывающем эффектный сбой SharePoint, как это было на прошлой неделе, то я куплю вам 2 билета в кино на любой фильм NuMetro или SterKinekor, который показывается в данный момент. Доказательством будет успешное развертывание и удаление (всего три раза) пакетов фиксированных решений в средах DEV и QA.
Список возможностей приемника событий:
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.Taxonomy;
using Microsoft.Office.DocumentManagement.MetadataNavigation;
using Microsoft.Office.Server.SocialData;
namespace CityDepartmentStructure.SharepointExtractTimerJob.Features.CityDepartmentsListFeature
{
/// <summary>
/// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
/// </summary>
/// <remarks>
/// The GUID attached to this class may be used during packaging and should not be modified.
/// </remarks>
[Guid("ce0a04a0-b20b-4587-998a-6817dce2d4d8")]
public class CityDepartmentsListFeatureEventReceiver : SPFeatureReceiver
{
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPServiceContext context = SPServiceContext.GetContext(SPServiceApplicationProxyGroup.Default, SPSiteSubscriptionIdentifier.Default);
SocialTagManager stm = new SocialTagManager(context);
TaxonomySession taxonomySession = stm.TaxonomySession;
TermStore termStore = taxonomySession.DefaultSiteCollectionTermStore;
Group termGroup = termStore.Groups["CityDepartments"];
TermSet termSet = termGroup.TermSets["Directorates"];
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
web.Lists.Add("DepartmentSites", "This list maintains a list of web sites for all Org Units in CCT", SPListTemplateType.Links);
web.Update();
SPList departmentsList = web.Lists["DepartmentSites"];
TaxonomyField taxonomyField = departmentsList.Fields.CreateNewField("TaxonomyFieldType", "OrgLevel") as TaxonomyField;
taxonomyField.Description = "Org Unit in the Org Structure. Can be a Directorate, Department, Branch or Section.";
taxonomyField.SspId = termStore.Id;
taxonomyField.TermSetId = termSet.Id;
taxonomyField.AllowMultipleValues = false;
taxonomyField.CreateValuesInEditForm = false;
taxonomyField.Open = false;
taxonomyField.Group = "CCT Metadata Field Content Type";
taxonomyField.Required = true;
departmentsList.Fields.Add(taxonomyField);
TaxonomyField field = departmentsList.Fields["OrgLevel"] as TaxonomyField;
field.Title = "OrgLevel";
field.Update(true);
departmentsList.Update();
SPView view = departmentsList.DefaultView;
view.ViewFields.Add("OrgLevel");
view.Update();
var navigationField = departmentsList.Fields["OrgLevel"] as SPField;
MetadataNavigationSettings navigationSettings = MetadataNavigationSettings.GetMetadataNavigationSettings(departmentsList);
MetadataNavigationHierarchy navigationHierarchy = new MetadataNavigationHierarchy(navigationField);
navigationSettings.AddConfiguredHierarchy(navigationHierarchy);
MetadataNavigationSettings.SetMetadataNavigationSettings(departmentsList, navigationSettings, true);
departmentsList.Update();
MetadataNavigationKeyFilter navigationKeyFilter = new MetadataNavigationKeyFilter(navigationField);
navigationSettings.AddConfiguredKeyFilter(navigationKeyFilter);
MetadataNavigationSettings.SetMetadataNavigationSettings(departmentsList, navigationSettings, true);
departmentsList.Update();
}
}
catch (Exception ex)
{
throw ex;
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
try
{
using (SPWeb web = properties.Feature.Parent as SPWeb)
{
SPList departmentsList = web.Lists["DepartmentSites"];
departmentsList.Delete();
}
}
catch (Exception ex)
{
throw ex;
}
}
}
}
Приемник функции задания таймера:
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Linq;
namespace CityDepartmentStructure.SharepointExtractTimerJob.Features.Feature1
{
/// <summary>
/// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
/// </summary>
/// <remarks>
/// The GUID attached to this class may be used during packaging and should not be modified.
/// </remarks>
[Guid("10e80e0f-7be3-46f0-8a7f-fcf806ddf762")]
public class Feature1EventReceiver : SPFeatureReceiver
{
private const string JobName = "ExtractTimerJob";
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPService service = GetService();
// Remove job if it exists.
DeleteJobAndSettings(service);
// Create the job.
ExtractTimerJob job = new ExtractTimerJob(JobName, service);
// Create the schedule so that the job runs hourly, sometime
// during the first quarter of the hour.
SPHourlySchedule schedule = new SPHourlySchedule();
schedule.BeginMinute = 0;
schedule.EndMinute = 15;
job.Schedule = schedule;
job.Update();
// Configure the job.
ExtractTimerJobSettings jobSettings = new ExtractTimerJobSettings(service, Guid.NewGuid());
jobSettings.Name = "ExtractTimerJobSettings";
jobSettings.WebServiceLocation = "http://r3pci01.capetown.gov.za:8150/sap/zget_orgstruct";
jobSettings.Update(true);
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
DeleteJobAndSettings(GetService());
}
private void DeleteJobAndSettings(SPService service)
{
// Find the job and delete it.
foreach (SPJobDefinition job in service.JobDefinitions)
{
if (job.Name == JobName)
{
job.Delete();
break;
}
}
// Delete the job's settings.
ExtractTimerJobSettings jobSettings = service.GetChild<ExtractTimerJobSettings>("ExtractTimerJobSettings");
if (jobSettings != null)
{
jobSettings.Delete();
}
}
private static SPService GetService()
{
// Get an instance of the SharePoint farm.
SPFarm farm = SPFarm.Local;
// Get an instance of the service.
var results = from s in farm.Services
where s.Name == "SPSearch4"
select s;
SPService service = results.First();
return service;
}
}
}
1 ответ
Без журналов может быть трудно понять, что именно произошло, но я бы предположил, что Disposing Properties.Feature.Parent не очень хорошая идея.
Если вы делаете это из powershell, это может привести к некоторым проблемам, потому что, скорее всего, он всегда будет пытаться использовать один и тот же объект.
Следующим шагом будет использование сценария, в котором вы развертываете / убираете решение. Вы явно активируете / деактивируете функцию каждый раз?
Более чрезмерное уничтожение пулов приложений - это нормальное поведение для развертывания и отвода, но проблема с их повторным запуском может быть связана с какими-то тайм-аутами - например, запуск пула приложений пытается произойти до того, как он действительно отключится.