2013-06-11 10 views
5

Jestem węzłem węzłowym i próbuję zrozumieć, w jaki sposób można wdrożyć auto discovery w aplikacji node.js. Zamierzam użyć cluster module i chcę, aby każdy proces roboczy był aktualizowany (i stale podłączony) do węzłów elastycznej tkanki.Jak zaimplementować automatyczne wykrywanie AWS Elasticache dla node.js

Ponieważ nie ma koncepcji pamięci współdzielonej (np. PHP APC), czy musiałbyś mieć kod działający w każdym z robotów, który budzi się co X sekund i jakoś aktualizuje listę adresów IP i ponownie łączy klienta memcache?

Jak ludzie rozwiązują to dzisiaj? Przykładowy kod byłby bardzo doceniany.

Odpowiedz

3

Należy pamiętać, że w tej chwili funkcja Automatyczne wykrywanie jest dostępna tylko dla klastrów pamięci podręcznej z mechanizmem memcached.

Dla Cache silnika wersja 1.4.14 lub nowsza trzeba utworzyć gniazda TCP/IP do pamięci podręcznej klastra Konfiguracja punktu końcowego (lub dowolnej Cache węzła końcowego) i wysłać polecenie:

config get cluster 

z węzłem. js możesz użyć do tego celu net.Socket class.

Odpowiedź składa się z dwóch linii:

  • Numer wersji informacji konfiguracyjnych. Za każdym razem, gdy węzeł jest dodawany lub usuwany z klastra pamięci podręcznej, numer wersji zwiększa się o jeden.

  • Lista węzłów pamięci podręcznej. Każdy węzeł na liście jest reprezentowany przez nazwę hosta | ip-address | port, a każdy węzeł jest ograniczony spacją.

Na końcu każdej linii pojawia się znak powrotu karetki i znak przekazania linii (CR + LF).

Tutaj znajdziesz dokładniejszy opis, jak wykonać add Auto Discovery to your client library.

Korzystanie z modułu klastra trzeba przechowywać te same informacje w każdym procesie (czyli dziecko) i chciałbym użyć „setInterval” za dziecko okresowo sprawdzać (np co 60 sekund) listę węzłów i ponownie podłączyć tylko jeśli lista się zmieniła (to nie powinno się zdarzać zbyt często).

Opcjonalnie można zaktualizować listę tylko na wzorcu i użyć "worker.send", aby zaktualizować pracowników. Dzięki temu wszystkie procesy działające na jednym serwerze mogą być zsynchronizowane, ale nie pomoże to w architekturze z wieloma serwerami, dlatego bardzo ważne jest, aby używać spójnego hashu, aby móc zmienić listę węzłów i poluzować "minimalna" liczba kluczy przechowywanych w memcached cluster.

Chciałbym użyć zmiennej globalnej do przechowywania tego rodzaju konfiguracji.

Dwa razy można użyć zestawu SDK AWS dla pliku Node.js, aby uzyskać listę węzłów elastiCache (a także dla silnika Redis).

W tym przypadku kod byłoby coś takiego:

var util = require('util'), 
    AWS = require('aws-sdk'), 
    Memcached = require('memcached'); 

global.AWS_REGION = 'eu-west-1'; // Just as a sample I'm using the EU West region                      
global.CACHE_CLUSTER_ID = 'test'; 
global.CACHE_ENDPOINTS = []; 
global.MEMCACHED = null; 

function init() { 

    AWS.config.update({ 
     region: global.AWS_REGION 
    }); 
    elasticache = new AWS.ElastiCache(); 

    function getElastiCacheEndpoints() { 

     function sameEndpoints(list1, list2) { 
      if (list1.length != list2.length) 
       return false; 
      return list1.every(
       function(e) { 
        return list2.indexOf(e) > -1; 
       }); 
     } 

     function logElastiCacheEndpoints() { 
      global.CACHE_ENDPOINTS.forEach(
       function(e) { 
        util.log('Memcached Endpoint: ' + e); 
       }); 
     } 

     elasticache.describeCacheClusters({ 
       CacheClusterId: global.CACHE_CLUSTER_ID, 
       ShowCacheNodeInfo: true 
      }, 
      function(err, data) { 
       if (!err) { 
        util.log('Describe Cache Cluster Id:' + global.CACHE_CLUSTER_ID); 
        if (data.CacheClusters[0].CacheClusterStatus == 'available') { 
         var endpoints = []; 

         data.CacheClusters[0].CacheNodes.forEach(
          function(n) { 
           var e = n.Endpoint.Address + ':' + n.Endpoint.Port; 
           endpoints.push(e); 
          }); 
         if (!sameEndpoints(endpoints, global.CACHE_ENDPOINTS)) { 
          util.log('Memached Endpoints changed'); 
          global.CACHE_ENDPOINTS = endpoints; 
          if (global.MEMCACHED) 
           global.MEMCACHED.end(); 
          global.MEMCACHED = new Memcached(global.CACHE_ENDPOINTS); 
          process.nextTick(logElastiCacheEndpoints); 
          setInterval(getElastiCacheEndpoints, 60000); // From now on, update every 60 seconds       
         } 
        } else { 
         setTimeout(getElastiCacheEndpoints, 10000); // Try again after 10 seconds until 'available'      
        } 
       } else { 
        util.log('Error describing Cache Cluster:' + err); 
       } 
      }); 
    } 

    getElastiCacheEndpoints(); 

} 

init(); 
+0

Yea ale gdzie można przechowywać listę adresów IP? Global var? A jak rozwiązać ten problem w module klastra? 'SetTimeout()', który ustawia globalny var na dziecko? – rynop

+0

Dodałem kilka wyjaśnień, daj mi znać, jeśli to pomoże. – danilop

+0

Dzięki. Jeśli ja/ktoś dostarczy kompletny przykład, oznaczę te ans jako prawidłowe. – rynop

Powiązane problemy