很久以前,我用 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())
我认为我能做的工作之一是:
在客户端添加sessionID,并将其保存在服务器的 map 中,并统计在线用户和关注人数。
这是好的且正确的方式吗?
最佳答案
全局处理程序、中间件(如果您使用的是路由器 pkg,请查看此)或仅在热门页面上调用统计函数就足够了。请小心排除机器人、RSS 点击或您不关心的其他流量。
假设您有一个进程,并且想要跟踪最近 5 分钟内的在线用户,是的, map 服务器端就可以了,您可以颁发 token (取决于用户允许 cookie,每个请求占用带宽),或者只是哈希 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()
类似的事情。
关于session - 在 Golang 中跟踪在线用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42434354/