2012-06-21 32 views
12

Tôi đang chạy một ứng dụng web trên IIS 7.5 và nó cần phải tái chế đôi khi (nếu không sử dụng bộ nhớ được ra khỏi bàn giao, một cái gì đó tôi đang nhìn vào!).IIS app pool recycle + lịch trình thạch anh

Khi nó tái chế, nó có hiệu quả không chạy cho đến khi một yêu cầu khác đến, mà thạch anh sẽ không chạy.

Có cách nào để IIS tự động đưa lên 1 quy trình làm việc ngay sau khi tái chế hồ bơi ứng dụng để đảm bảo thạch anh luôn trực tuyến không?

+0

Bạn có nên lưu trữ thạch anh trong Dịch vụ Windows không? –

+0

@JakubKonecki, đó sẽ là kế hoạch của tôi b, nỗ lực của nó nhiều hơn so với lưu trữ nó trong ứng dụng, vì lịch trình chỉ tương tác với ứng dụng. –

+2

phải có kế hoạch A ;-) http://haacked.com/archive/2011/10/16/the-dangers-of-implementing-recurring-background-tasks-in-asp-net.aspx –

Trả lời

13

Có!

http://weblogs.asp.net/scottgu/archive/2009/09/15/auto-start-asp-net-applications-vs-2010-and-net-4-0-series.aspx chi tiết nó khá độc đáo, về cơ bản bạn cần phải:

  1. Sửa C: \ Windows \ System32 \ inetsrv \ config \ applicationHost.config bao gồm:

    <applicationPools> 
        <add name="MyAppWorkerProcess" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" /> 
    </applicationPools> 
    
  2. Khai báo gì nên được chạy khi "khởi động" cho trang web của bạn

    <sites> 
        <site name="MySite" id="1"> 
         <application path="/" serviceAutoStartEnabled="true" serviceAutoStartProvider="PreWarmMyCache" /> 
        </site> 
    </sites> 
    <serviceAutoStartProviders> 
        <add name="PreWarmMyCache" type="PreWarmCache, MyAssembly" /> 
    </serviceAutoStartProviders> 
    
  3. Cấu hình ứng dụng của bạn với bất cứ logic "khởi động" bạn muốn:

    public class PreWarmCache : System.Web.Hosting.IProcessHostPreloadClient { 
        public void Preload(string[] parameters) { 
         // Perform initialization and cache loading logic here... 
        } 
    } 
    

Lưu ý: Nếu bạn chỉ cần cho quá trình w3wp.exe có mặt Tôi tin rằng chỉ bước 1 là cần thiết. Nếu bạn cũng cần các mục khác (như một số thứ nhất định được nạp vào bộ nhớ) thì bước 2 và 3 cũng sẽ được sử dụng.

+0

Xin lỗi vì đã đụng phải một chủ đề cũ, nhưng ở đâu chính xác lớp học khởi động này nên được đặt trong dự án mvc4? –

+0

@StephenS.Cảm ơn nhưng nó đã không làm việc cho tôi như được chỉ ra trên [Không thể giữ ứng dụng Web còn sống trên IIS sau khi tái chế hoặc khởi động lại] (http://stackoverflow.com/questions/33593602/cannot-keep-alive-web-application-on-iis -Sau khi tái chế hoặc khởi động lại). Bất kỳ pls trợ giúp? –

+0

Đối với những người khác như tôi, những người cố gắng sử dụng notepad ++ hoặc trình soạn thảo khác để chỉnh sửa applicationHost.config, câu trả lời này trên SO đã giúp (về cơ bản, sử dụng notepad): [link] (http://stackoverflow.com/a/13335092/2506135) –

0

Tôi đã giải quyết vấn đề này. Trong khi Stephen's answer sẽ giữ cho ứng dụng chạy, trong môi trường Spring.Net, khung sẽ không khởi động và Quartz sẽ không chạy. Tôi đặt cùng một thực hiện của IProcessHostPreloadClient sẽ bắn ra một yêu cầu thực sự cho ứng dụng để có được tất cả các máy móc đang chạy. Điều này cũng được đăng tải on my blog:

public class Preloader : System.Web.Hosting.IProcessHostPreloadClient 
{ 
    public void Preload(string[] parameters) 
    { 
     var uris = System.Configuration.ConfigurationManager 
         .AppSettings["AdditionalStartupUris"]; 
     StartupApplication(AllUris(uris)); 
    } 

    public void StartupApplication(IEnumerable<Uri> uris) 
    { 
     new System.Threading.Thread(o => 
     { 
      System.Threading.Thread.Sleep(500); 
      foreach (var uri in (IEnumerable<Uri>)o) { 
       var client = new System.Net.WebClient(); 
       client.DownloadStringAsync(uris.First()); 
      } 
     }).Start(uris); 
    } 

    public IEnumerable<Uri> AllUris(string userConfiguration) 
    { 
     if (userConfiguration == null) 
      return GuessedUris(); 
     return AllUris(userConfiguration.Split(' ')).Union(GuessedUris()); 
    } 

    private IEnumerable<Uri> GuessedUris() 
    { 
     string path = System.Web.HttpRuntime.AppDomainAppVirtualPath; 
     if (path != null) 
      yield return new Uri("http://localhost" + path); 
    } 

    private IEnumerable<Uri> AllUris(params string[] configurationParts) 
    { 
     return configurationParts 
      .Select(p => ParseConfiguration(p)) 
      .Where(p => p.Item1) 
      .Select(p => ToUri(p.Item2)) 
      .Where(u => u != null); 
    } 

    private Uri ToUri(string value) 
    { 
     try { 
      return new Uri(value); 
     } 
     catch (UriFormatException) { 
      return null; 
     } 
    } 

    private Tuple<bool, string> ParseConfiguration(string part) 
    { 
     return new Tuple<bool, string>(IsRelevant(part), ParsePart(part)); 
    } 

    private string ParsePart(string part) 
    { 
     // We expect IPv4 or MachineName followed by | 
     var portions = part.Split('|'); 
     return portions.Last(); 
    } 

    private bool IsRelevant(string part) 
    { 
     var portions = part.Split('|'); 
     return 
      portions.Count() == 1 || 
      portions[0] == System.Environment.MachineName || 
      HostIpAddresses().Any(a => a == portions[0]); 
    } 

    private IEnumerable<string> HostIpAddresses() 
    { 
     var adaptors = System.Net.NetworkInformation 
          .NetworkInterface.GetAllNetworkInterfaces(); 
     return adaptors 
       .Where(a => a.OperationalStatus == 
          System.Net.NetworkInformation.OperationalStatus.Up) 
       .SelectMany(a => a.GetIPProperties().UnicastAddresses) 
       .Where(a => a.Address.AddressFamily == 
          System.Net.Sockets.AddressFamily.InterNetwork) 
       .Select(a => a.Address.ToString()); 
    } 
} 
-3

Hoặc bạn chỉ có thể sửa đổi "Application_Start" Phương pháp trong Global.asax để đảm bảo rằng Quortz đang chạy.

+2

Application_Start chỉ được gọi trong yêu cầu đầu tiên sau khi tái chế hoặc khởi động, đây không phải là hành vi mong muốn. –

1

Bắt đầu với IIS 8.0, có một tùy chọn để mô phỏng yêu cầu tới trang gốc, do đó khởi tạo ứng dụng đầy đủ: Cài đặt nâng cao của ứng dụng Pool -> Preload enabled = true.

Tất nhiên, startMode phải là AlwaysRunning.

Thông tin chi tiết về cách bật tính năng này có thể được tìm thấy here.

Các vấn đề liên quan