2009-07-11 8 views
2

Ich versuche herauszufinden, die Anzahl der aktiven Sitzungen mit einer Memcached-Speicheroption am einfachsten und sichersten zählen. Mit dem DB-basierten Sitzungsspeicher kann ich nur die Anzahl der Zeilen in der Tabelle zählen, kann aber nicht dasselbe mit memcached tun.Rails - Liste der aktiven Sitzungen

Danke, Vikram

Antwort

0

Ich glaube nicht, dass Sie mit memcache tun können.

Muss zugeben, ich bin noch MemCacheStore verwenden, aber Sie könnten wahrscheinlich etwas vor Filter im Anwendungscontroller mit einem Cron-Job und einer Tabelle in Ihrer Datenbank implementieren.

1

Memcache bietet explizit keine Möglichkeit, über die verwendeten Schlüssel zu iterieren. Sie können basierend auf einem bestimmten Schlüssel lesen oder schreiben, aber Sie können nicht eine Liste aller Schlüssel erhalten oder über sie iterieren. Dies ist eine Beschränkung von Memcache.

Leider funktioniert eine before_filter nicht, da Sitzungen in Memcached abgelaufen sein können, ohne dass Ihre App darüber benachrichtigt wird.

Warum möchten Sie diese Informationen erhalten?

+0

Hallo, Danke für die Antwort. Ich möchte, dass diese Informationen die Anzahl der Benutzer auf der Website anzeigen, ob angemeldet oder anderweitig. Vikram –

0

Ich weiß, dass dieser Beitrag wirklich alt ist, aber ich dachte, ich würde hier eine mögliche Lösung hinzufügen und sehen, welche Art von Kommentaren kommen aus der Gemeinschaft.

Wir erwägen, unsere Sitzungen in memcached zu verschieben, da wir sie für das Fragment-Caching (und andere Dinge) verwenden. Dieser Ansatz funktioniert auf meinem Computer, hatte aber keine Chance, den Code aufzuräumen und in einer robusteren Umgebung zu testen.

Die Lösung ist ziemlich einfach. Es verwendet einen Schlüssel basierend auf Stunde: Minute und erhöht/erniedrigt die Tasten, wenn eine Sitzung verlängert wird. Der Bucket (Schlüssel), in den die Sitzung eingefügt wird, wird zurückgegeben und in der Sitzung gespeichert. Wenn die Sitzung das nächste Mal auf die App trifft, wird der vorherige Bucket, in den sie eingefügt wurde, der Zählmethode bereitgestellt. Auf diese Weise eine Sitzung zwischen den Tasten (verschoben aus früheren Eimern zu neuen Eimern) bewegen kann

Hier ist die Methode:

def count(previous_bucket) 
    # All this does is construct a key like this: 
    # _session_counter_10:15 
    key = KEY_PREFIX + time_key(Time.now.hour, Time.now.min) 

    # do nothing if previous bucket = key 
    return key if previous_bucket.present? && key.eql?(previous_bucket) 

    # Increment the count in the cache 
    Rails.cache.increment(key, 1, expires_in: 30.minutes) 

    # If there is a previous bucket, decrement the count there 
    if previous_bucket.present? 
     Rails.cache.decrement(previous_bucket, 1) 
    end 

    # Return the key used so it can be stored in the session which was counted. This will be returned on the next 
    # call to bump to keep the numbers accurate 
    return key 
end 

zu verwenden, wird die anrufende Methode dies zu tun:

counter = SessionCounter.new 
session[:counter_bucket] = counter.count(session[:counter_bucket]) 

Um eine Anzahl von Sitzungen in einem bestimmten Zeitraum zu erhalten, können Sie einfach ein Array von Schlüsseln für den Zeitraum erstellen und dann read_multi verwenden, um die Zählungen in dieser Zeit abzurufen.

Zum Beispiel:

keys = ["_session_count_10:15","_session_count_10:14","_session_count_10:13"] 
values = Rails.cache.read_multi(*keys) 

Werte ist ein Hash, die keine passenden Schlüssel enthält. Summieren Sie einfach die Werte der Schlüssel, um die Anzahl in diesem Zeitraum zu erhalten.

Frage:

  • Wird diese Skala? Es wird eine Menge Treffer geben, die Zähler im Cache erhöhen/verringern, wenn die App stark ausgelastet ist. Wird der Schlüssel gesperrt, wodurch die App langsamer wird? Ich habe darüber nachgedacht, den Inkrement/Dekrement-Abschnitt in einen Thread einzufügen, aber Sie wissen, dass die Performance erst dann eingestellt wird, wenn ein bekanntes Problem vorliegt.

Update:

Wir haben dieses Muster implementiert haben und es in die Produktion. Es hat sehr gut für uns funktioniert und es sind noch keine Performance-Probleme aufgetaucht.