ファーム全体で、1日に1回だけ実行したいタイマージョブがあります。どうすればいいですか
- 複数のWFE環境に展開しますか?stsadm -o deploysolutionコマンドをすべてのWFEで実行しますか、それとも実行したい場所だけで実行しますか?
- この機能はどこでアクティブ化する必要がありますか?特定のWFEからのみアクティブ化する必要がありますか?
- SPJobLockTypeの値はどうあるべきですか。
ファーム全体で、1日に1回だけ実行したいタイマージョブがあります。どうすればいいですか
このジョブを実行するサービスをインストールするファームスコープの機能が必要なようです。これが私がそれをした方法です(正直に言うと、同僚によって書かれたコードを使用していますが、彼はSOにいません)。
機能イベントレシーバーを使用してfeature.xmlファイルを作成します。
<Feature
Id="..."
Title="..."
Description="..."
Scope="Farm"
Version="1.0.0.0"
Hidden="FALSE"
ReceiverAssembly="XXX.FarmService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxx"
ReceiverClass="XXX.FarmService.XXXFarmFeatureEventReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>
イベントレシーバーの内部:
public override void OnFeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPFarm farm = SPFarm.Local;
// Get Service, if it already exists
JobService myService = null; // JobService is a subclass of SPService
foreach (SPService service in farm.Services)
{
if (String.Compare(service.Name, JobService.XXXServiceName, true) == 0)
{
myService = (service as JobService);
break;
}
}
if (cegService == null)
{
// Create service
myService = new JobService(farm);
myService.Update();
// Create service instances
JobServiceInstance myServiceInstance; // JobServiceInstance is a subclas of SPServiceInstance
foreach (SPServer server in farm.Servers)
{
myServiceInstance = new JobServiceInstance(server, myService);
myServiceInstance.Update();
}
}
// Dayly schedule
SPDailySchedule schedule = new SPDailySchedule();
schedule.BeginHour = 1;
schedule.EndHour = 1;
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
// Our own job; JobCheckDocDates is a subclass of SPJobDefinition
JobCheckDocDates newJob = new JobCheckDocDates(cegService, null, SPJobLockType.Job);
newJob.Schedule = schedule;
newJob.Update();
myService.JobDefinitions.Add(newJob);
myService.Update();
}
catch (Exception e)
{
Logger.Error("[" + properties.Feature.Definition.DisplayName + "] Error during feature activation", e);
}
}
これにより、ファーム内のすべてのサーバーで利用可能なサービスが作成されます。
サブクラスの詳細:
public class JobCheckDocDates: Common.BaseJob
{
/// <summary>
/// The job name
/// </summary>
public static string JobName = "XXX job";
/// <summary>
/// Constructor
/// </summary>
public JobCheckDocDates() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="service"></param>
/// <param name="server"></param>
/// <param name="lockType"></param>
public JobCheckDocDates(SPService service, SPServer server, SPJobLockType lockType)
: base(JobName, service, server, lockType) { }
..。
そしてもちろん、Executeメソッド。
public class JobService : SPService
{
public static string XXXServiceName = "XXX Service";
public override string DisplayName
{
get
{
return XXXServiceName;
}
}
public override string TypeName
{
get
{
return "XXX Service Type";
}
}
/* An empty public constructor required for serialization. */
public JobService() { }
public JobService(SPFarm farm)
: base(XXXServiceName, farm)
{
}
}
public class JobServiceInstance : SPServiceInstance
{
/// <summary>
/// Eos Service Instance Name
/// </summary>
public static string XXXServiceInstanceName = "XXXServiceInstance";
/// <summary>
/// Manage Link
/// </summary>
private SPActionLink _manageLink;
/// <summary>
/// Provision Link
/// </summary>
private SPActionLink _provisionLink;
/// <summary>
/// Unprovision Link
/// </summary>
private SPActionLink _unprovisionLink;
/// <summary>
/// Roles
/// </summary>
private ICollection<string> _roles;
/// <summary>
/// Manage Link
/// </summary>
public override SPActionLink ManageLink
{
get
{
if (_manageLink == null)
{
_manageLink = new SPActionLink(SPActionLinkType.None);
}
return _manageLink;
}
}
/// <summary>
/// Provision Link
/// </summary>
public override SPActionLink ProvisionLink
{
get
{
if (_provisionLink == null)
{
_provisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _provisionLink;
}
}
/// <summary>
/// Unprovision Link
/// </summary>
public override SPActionLink UnprovisionLink
{
get
{
if (_unprovisionLink == null)
{
_unprovisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _unprovisionLink;
}
}
/// <summary>
/// Roles
/// </summary>
public override ICollection<string> Roles
{
get
{
if (_roles == null)
{
_roles = new string[1] { "Custom" };
}
return _roles;
}
}
/// <summary>
/// Empty constructor
/// </summary>
public JobServiceInstance() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="server">The server</param>
/// <param name="service">The Eos service</param>
public JobServiceInstance(SPServer server, JobService service)
: base(XXXServiceInstanceName, server, service)
{
}
次に、サーバーの全体管理で、サーバーの[操作]/[サービス]に移動します。目的のサーバーを選択して、サービスを開始します。
質問のリストに回答するには、次の手順に従います。1. WFEとは関係なく、ソリューションを1回だけ展開します。2.この機能はファームスコープであるため、サーバーの全体管理でアクティブ化する必要があります。3.SPJobLockTypeはSPJobLockType.Jobです。
これはあなたが想像した通りではありませんが、機能をインストールした後でも(たとえば、サーバーが他のもので過負荷になった場合)、ジョブを実行する場所を簡単に選択できるという利点があります。
OnFeatureActivatedメソッドはよりスマートで、サービスが存在するかどうかを各サーバーでチェックし、必要に応じて追加することができます。ただし、OnFeatureDeactivate内のすべてのサービスからサービスを削除する方が簡単です。したがって、新しいサーバーを追加する場合は、機能を非アクティブ化してから再度アクティブ化します。