2017-02-24 115 views
2

很久以前,我用Golang建了一个网站,现在我想跟踪在线用户。跟踪Golang的在线用户

我想在没有Redis的情况下使用SessionID进行操作。

什么是我工作的最佳方式?

我写了一个全球性的处理程序:

type Tracker struct { 
    http.Handler 
} 

func NewManager(handler http.Handler) *Tracker { 
    return &Tracker{Handler: handler} 
} 

func (h *Tracker) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    log.Println(r.RemoteAddr) 
    h.Handler.ServeHTTP(w,r) 
} 

。 。 。

srv := &http.Server{ 
     Handler:  newTracker(e), 
     Addr:   "127.0.0.1" + port, 
     WriteTimeout: 15 * time.Second, 
     ReadTimeout: 15 * time.Second, 
    } 

    log.Fatal(srv.ListenAndServe()) 

我认为我可以做的工作之一是:

在客户端地图在服务器和计数在线用户和下面有添加会话ID和保存。

它是好的和正确的方式?

回答

3

全局处理程序,中间件(如果你使用路由器pkg看这个)或者只是在热门页面上调用统计函数就足够了。请注意排除漫游器,rss点击或其他您不关心的流量。

假设你有一个进程,并且想要在最近5分钟内在线跟踪用户,是的,地图服务器端会没问题,你可以发放令牌(取决于允许cookies的用户,每个请求占用带宽) ,或者只是散列IP(工作得很好,可能会出现轻微的计数不足)。然后您需要在一段时间后过期,并使用互斥锁来保护它们。在重新启动时,您将失去计数,如果运行两个进程无法执行此操作,则这是内存存储的负面影响,您需要使用另一个缓存进程来保存。所以这不适用于大型网站,但您可以稍后转向使用更持久的存储。

var PurgeInterval = 5 * time.Minute 
var identifiers = make(map[string]time.Time) 
var mu sync.RWMutex 

...

// Hash ip + ua for anonymity in our store 
hasher := sha256.New() 
hasher.Write([]byte(ip)) 
hasher.Write([]byte(ua)) 
id := base64.URLEncoding.EncodeToString(hasher.Sum(nil)) 

// Insert the entry with current time 
mu.Lock() 
identifiers[id] = time.Now() 
mu.Unlock() 

...

// Clear the cache at intervals 
mu.Lock() 
for k, v := range identifiers { 
    purgeTime := time.Now().Add(-PurgeInterval) 
    if v.Before(purgeTime) { 
     delete(identifiers, k) 
    } 
} 
mu.Unlock() 

类似的东西。

+0

感谢您的完美解释,如何为每个未登录我网站的用户设置独家ID?也许很多用户使用单个IP地址,远程端口太多。你可以帮我吗 ? – ahmdrz

+1

不是一个真正的大问题(这是我提到的轻微计数),但是您可以将用户代理添加到散列id中,或者生成随机令牌并将其放入cookie中,但这需要cookie存储以及每个请求的读取/写入。将添加到示例。 –

+0

伟大的人!非常感谢你,哈希用户代理是特殊的哈希。 – ahmdrz