source

까다로운 쿼츠.NET 시나리오

manycodes 2023. 10. 3. 11:06
반응형

까다로운 쿼츠.NET 시나리오

좋아요, 여기 배경이 좀.저는 모든 종류의 중요하지 않은 일을 하는 대규모 웹 애플리케이션(MVC3)을 가지고 있습니다.저는 이 웹 애플리케이션이 임시 쿼츠를 예약할 수 있는 능력을 갖추기 위해 필요합니다.오라클 데이터베이스의 NET 작업.그럼 나중에 윈도우 서비스를 통해 작업을 실행했으면 합니다.이상적으로는 짝수 간격으로 실행되도록 예약하고 싶지만 웹 앱을 통해 작업을 추가할 수도 있습니다.

기본적으로 원하는 아키텍처는 다음과 같은 몇 가지 변형입니다.

웹 앱 <--> 쿼츠.NET <--> 데이터베이스 <--> 석영.NET <--> Windows 서비스

지금까지 코딩한 내용:

  • (지금은) 작업을 예약하고 실행하는 윈도우 서비스입니다.이것은 장기적으로 볼 때 분명히 해당되지 않을 것입니다. 하지만 저는 이것만 유지하고 기본적으로 "쿼츠"를 둘 다 나타내도록 수정할 수 있는지 궁금합니다.위의 도표에서 NET's.
  • 웹 앱(자세한 내용은 여기서 별로 중요하지 않은 것 같습니다)
  • 작업(실제로는 다른 윈도우즈 서비스일 뿐임)

그리고 몇 가지 중요한 사항:

  • Windows 서비스에서 실행해야 하며 웹 앱을 통해 예약해야 합니다(IIS 부하를 줄이기 위해).
  • 위의 구조는 위의 탄환이 여전히 적용된다는 가정하에 약간 재정렬될 수 있습니다.

자, 몇 가지 질문이 있습니다.

  1. 이게 가능하긴 해요?
  2. (1)이 통과되었다고 가정할 때, 이에 가장 적합한 아키텍처는 무엇이라고 생각하십니까?내가 코드 작성한 것에 대한 첫번째 총알을 봅니다.
  3. 누군가 제게 작업이 이미 예약된 후 실행할 작업에 대해 DB를 조회하는 데 도움이 될 몇 가지 Quartz 방법을 알려주실 수 있나요?

이 문제는 적격인 즉시 현상금이 부과될 것입니다.만약 그 전에 만족스러운 방법으로 질문이 대답된다면, 저는 여전히 그 대답의 포스터에 현상금을 수여할 것입니다.그래서 어쨌든 여기서 좋은 대답을 해주면 현상금이 주어집니다.

있는 순서대로 답변을 해보겠습니다.

  1. 네, 가능합니다.Quartz와 함께 작업하는 일반적인 방법입니다.넷. 실제로 ASP를 작성할 수도 있습니다.Quartz를 관리하는 Net MVC 어플리케이션.네트워크 스케줄러.

  2. 건축.이상적이고 높은 수준에서 MVC 애플리케이션은 Quartz를 사용할 것입니다.Quartz와 대화할 넷 API입니다.어딘가에 윈도우즈 서비스로 설치되어 있는 넷 서버.석영.넷은 원격 통신을 위해 원격 통신을 사용하므로 원격 통신의 모든 제한 사항이 적용됩니다(Silverlight 등에서 지원되지 않는 경우).석영.Net은 즉시 Windows 서비스로 설치할 수 있는 방법을 제공하므로 AdoJobStore를 사용하도록 서비스 자체를 구성하고 원격을 활성화하는 것 외에는 할 일이 별로 없습니다.서비스를 제대로 설치하는 방법에 대해 주의해야 할 사항이 있으니 아직 설치하지 않았다면 이 게시물을 확인해 보세요.

내부적으로 MVC 애플리케이션에서 스케줄러에 대한 참조를 가져와 싱글톤으로 저장하고자 합니다.그러면 코드에서 작업을 예약하고 이 고유한 인스턴스를 통해 스케줄러에 대한 정보를 얻을 수 있습니다.다음과 같은 것을 사용할 수 있습니다.

public class QuartzScheduler
{
    public QuartzScheduler(string server, int port, string scheduler)
    {
        Address = string.Format("tcp://{0}:{1}/{2}", server, port, scheduler);
        _schedulerFactory = new StdSchedulerFactory(getProperties(Address));

        try
        {
            _scheduler = _schedulerFactory.GetScheduler();
        }
        catch (SchedulerException)
        {
            MessageBox.Show("Unable to connect to the specified server", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
        }
    }
    public string Address { get; private set; }
    private NameValueCollection getProperties(string address)
    {
        NameValueCollection properties = new NameValueCollection();
        properties["quartz.scheduler.instanceName"] = "RemoteClient";
        properties["quartz.scheduler.proxy"] = "true";
        properties["quartz.threadPool.threadCount"] = "0";
        properties["quartz.scheduler.proxy.address"] = address;
        return properties;
    }
    public IScheduler GetScheduler()
    {
        return _scheduler;
    }
}

이 코드는 쿼트를 설정합니다.넷 클라이언트.그런 다음 원격 스케줄러에 액세스하려면 전화만 걸면 됩니다.

GetScheduler()
  1. 쿼리 스케줄러에서 모든 작업을 가져오는 샘플 코드는 다음과 같습니다.

    public DataTable GetJobs()
    {
        DataTable table = new DataTable();
        table.Columns.Add("GroupName");
        table.Columns.Add("JobName");
        table.Columns.Add("JobDescription");
        table.Columns.Add("TriggerName");
        table.Columns.Add("TriggerGroupName");
        table.Columns.Add("TriggerType");
        table.Columns.Add("TriggerState");
        table.Columns.Add("NextFireTime");
        table.Columns.Add("PreviousFireTime");
        var jobGroups = GetScheduler().GetJobGroupNames();
        foreach (string group in jobGroups)
        {
            var groupMatcher = GroupMatcher<JobKey>.GroupContains(group);
            var jobKeys = GetScheduler().GetJobKeys(groupMatcher);
            foreach (var jobKey in jobKeys)
            {
                var detail = GetScheduler().GetJobDetail(jobKey);
                var triggers = GetScheduler().GetTriggersOfJob(jobKey);
                foreach (ITrigger trigger in triggers)
                {
                    DataRow row = table.NewRow();
                    row["GroupName"] = group;
                    row["JobName"] = jobKey.Name;
                    row["JobDescription"] = detail.Description;
                    row["TriggerName"] = trigger.Key.Name;
                    row["TriggerGroupName"] = trigger.Key.Group;
                    row["TriggerType"] = trigger.GetType().Name;
                    row["TriggerState"] = GetScheduler().GetTriggerState(trigger.Key);
                    DateTimeOffset? nextFireTime = trigger.GetNextFireTimeUtc();
                    if (nextFireTime.HasValue)
                    {
                        row["NextFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime);
                    }
    
                    DateTimeOffset? previousFireTime = trigger.GetPreviousFireTimeUtc();
                    if (previousFireTime.HasValue)
                    {
                        row["PreviousFireTime"] = TimeZone.CurrentTimeZone.ToLocalTime(previousFireTime.Value.DateTime);
                    }
    
                    table.Rows.Add(row);
                }
            }
        }
        return table;
    }
    

이 코드는 Github에서 볼 수 있습니다.

언급URL : https://stackoverflow.com/questions/10824581/tricky-quartz-net-scenario

반응형