2013-06-24 2 views
1

Google 서비스 및 MVC4 웹 사이트를 클라우드로 이전 했으므로이 프로세스가 전반적으로 잘되었습니다. 캐싱을 제외하고 Azure로 이동 했으므로 azure가 제공하는 일종의 캐싱을 사용하는 것이 현명합니다. 우리는 캐시가 모든 인스턴스에서 사용된다는 장점이있는 공동 배치/전용 캐싱 역할을 선택합니다.여러 인스턴스가 같은 위치에있는 캐싱을 사용하지만 액세스에 실패했습니다. 좋은 캐싱 구현이 필요합니다.

캐싱 설정이 잘되었으므로 필요한 경우에만 초기화하는 명명 된 캐싱 클라이언트가 있습니다. 컨트롤러의 상속 된 레이어에 설정됩니다. 함수 중 하나가 호출 되 자마자 데이터 캐시에 대한 연결이 여전히 존재하는지 또는 생성되었는지 확인합니다. 이 모든 것이 잘 작동하는 것으로 보이지만 가격을 검색하는 모듈을 구축하고 있습니다. 그리고 여러 아약스 삽입 (자바 스크립트를 사용하여 페이지에 삽입되는보기)은 이러한 함수를 사용하며, 그 중 일부는 동시에 여러 아약스보기에서 호출됩니다. 이러한 뷰 중 일부는 404 또는 500 오류를 반환하며 작동하지 않는 캐싱을 제외하고 어디에서 오는지 설명 할 수 없습니다.

DataCacheFactory의 초기화를 보여주는 많은 예제가 있지만 데이터 삽입 및 검색이 아니라 이름 붙여진 캐싱 (동일 위치 또는 전용) 구현을 도와 줄 수 있습니까?

아래 코드는 지금 가지고있는 코드입니다. 잠금 등을 사용하여 더 많은 방법을 시도했지만 지금까지이 코드가 가장 효과적이었습니다. 마자 내가 거기에 가격리스트는 위의 기능이 동일한 인수를 여러 번 호출하는 페이지로로

private static object magicStick = new object(); 

    private static DataCacheFactory dcf = null; 
    private static DataCache priceCache = null; 

    protected void CreateCacheFactory() 
    { 
     dcf = new DataCacheFactory(); 

    } 
    protected void CreatePricesCache() 
    { 
     if (dcf == null) 
     { 
      CreateCacheFactory(); 
     } 
     priceCache = dcf.GetCache("Prices"); 

    } 
protected PriceData GetPrices(int productID) 
{ 
    if (priceCache == null) 
    { 
     CreatePricesCache(); 
    } 
    string cacheKey = "something"; 
    lock (magicStick) 
    { 
     PriceData datas = priceCache.Get(cacheKey) as PriceData; 
     if (datas == null) 
     { 
      lock (magicStick) 
      { 
       Services svc = new Services(); 
       PriceData pData = svc.PriceService.GetPrices(productID); 
       if (pData != null && pData.Offers != null && pData.Offers.Count() > 0) 
       { 
        datas = pData; 
        datas.Offers = datas.Offers.OrderBy(pr => (pr.BasePrice + pr.ShippingCosts)).ToArray(); 
        priceCache.Add(cacheKey, datas, new TimeSpan(0, cachingTimePricesKK, 0)); 
       } 
      } 
     } 
     return datas; 
    } 
} 

는 오히려 다음 결과를 반환하는 오류를 반환 5 ~ 10 %의 확률이 . 아무도 나를 도울 수 있습니까, 메신저 완전히 일주일 동안 이걸 붙잡 았고 그 안쪽에서 나를 먹었습니다.

+0

하나의 가능성은 CreatePricesCache에서 null이 될 수 있고 create는 Creatd가 될 수 있습니다. 그래서 그것을 설명하기 위해 예외 처리를 추가 할 것입니다. 잠재적으로 여러 스레드가이 코드를 동시에 사용하므로 타이밍을 중요하게 고려해야합니다. – BrentDaCodeMonkey

+0

아, 아주 똑바로 해보 려구요! 덕분에 – DerDee

답변

1

먼저 캐시 및 cacheFactory 인스턴스를 getPrices 메소드 밖으로 옮깁니다. 또한 잠금 장치에 대한 필요성을 평가하십시오. 이로 인해 시간 초과가 발생할 수 있습니다. 또 다른 중요한 사실은 동일한 캐시 키를 사용하여 일정한 캐시 키를 사용하고 모든 제품 ID에 대한 데이터를 저장/검색한다는 것입니다. 다음과 같은 캐시 키를 사용해야합니다 : var cacheKey = string.format("priceDatabyProductId-{0}", productId);. 몇 가지 중단 점을 설정하고 캐시에서 캐시를 정확히 검사하고 캐시에서 검색해야합니다. 작성된 코드는 첫 번째 productId를 캐시에 저장 한 다음 productId에 관계없이 해당 데이터를 계속 반환합니다. 여기

우리가 전용 캐시 역할 "기본"이라는 캐시를 사용하여 생산에 사용하는 전체 작업 예입니다

public static class MyCache 
{ 
    private static DataCacheFactory _cacheFactory = null; 
    private static DataCache ACache 
    { 
     get 
     { 
      if (_cacheFactory == null) 
      { 
       try 
       { 
        _retryPolicy.ExecuteAction(() => { _cacheFactory = new DataCacheFactory(); }); 
        return _cacheFactory == null ? null : _cacheFactory.GetDefaultCache(); 
       } 
       catch (Exception ex) 
       { 
        ErrorSignal.FromCurrentContext().Raise(ex); 
        return null; 
       } 
      } 

      return _cacheFactory.GetDefaultCache(); 
     } 
    } 

    public static void FlushCache() 
    { 
     ACache.Clear(); 
    } 

    // Define your retry strategy: retry 3 times, 1 second apart. 
    private static readonly FixedInterval _retryStrategy = new FixedInterval(3, TimeSpan.FromSeconds(1)); 

    // Define your retry policy using the retry strategy and the Windows Azure storage 
    // transient fault detection strategy. 
    private static RetryPolicy _retryPolicy = new RetryPolicy<StorageTransientErrorDetectionStrategy>(_retryStrategy); 

    // Private constructor to prevent instantiation 
    // and force consumers to use the Instance property 
    static MyCache() 
    { } 

    /// <summary> 
    /// Add an item to the cache with a key and set a absolute expiration on it 
    /// </summary> 
    public static void Add(string key, object value, int minutes = 90) 
    { 
     try 
     { 
      _retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); }); 
     } 
     catch (Exception ex) 
     { 
      ErrorSignal.FromCurrentContext().Raise(ex); 
     } 
    } 

    /// <summary> 
    /// Add the object with the specified key to the cache if it does not exist, or replace the object if it does exist and set a absolute expiration on it 
    /// only valid for Azure caching 
    /// </summary> 
    public static void Put(string key, object value, int minutes = 90) 
    { 
     try 
     { 
      _retryPolicy.ExecuteAction(() => { ACache.Put(key, value, TimeSpan.FromMinutes(minutes)); }); 
     } 
     catch (Exception ex) 
     { 
      ErrorSignal.FromCurrentContext().Raise(ex); 
     } 
    } 

    /// <summary> 
    /// Get a strongly typed item out of cache 
    /// </summary> 
    public static T Get<T>(string key) where T : class 
    { 
     try 
     { 
      object value = null; 

      _retryPolicy.ExecuteAction(() => { value = ACache.Get(key); }); 

      if (value != null) return (T) value; 
      return null; 
     } 
     catch (DataCacheException ex) 
     { 
      ErrorSignal.FromCurrentContext().Raise(ex); 
      return null; 
     } 
     catch (Exception ex) 
     { 
      ErrorSignal.FromCurrentContext().Raise(ex); 
      return null; 
     } 
    } 
    /// <summary> 
    /// Microsoft's suggested method for cleaning up resources such as this in a static class 
    /// to ensure connections and other consumed resources are returned to the resource pool 
    /// as quickly as possible. 
    /// </summary> 
    public static void Uninitialize() 
    { 
     if (_cacheFactory == null) return; 
     _cacheFactory.Dispose(); 
     _cacheFactory = null; 
    } 
} 

참고 :이 또한 과도에 대한 엔터프라이즈 라이브러리에서 과도 오류 처리 블록을 사용하고 있습니다 예외 오류 처리.

+0

위대한 예를 들어 주셔서 감사합니다. 구현했고 매력적으로 작동합니다. – DerDee

+0

재시도 정책에서 CacheTransientErrorDetectionStrategy를 통해 StorageTransientErrorDetectionStrategy를 사용하는 이유가 궁금합니다. – Eilimint

관련 문제