我目前正在处理用户登录应用程序后我想将他的 IP、用户名插入数据库的场景。
现在,我只能这样做一次的方法是使用缓存将用户的 ip 和用户名存储在缓存中。
现在,当每个 gunicorn 进程初始化自己的缓存时,问题就出现了。如果为 proc1 的缓存添加用户名 + ip 组合,如果 proc2 接收同一用户的下一个请求,它将不会在其缓存中找到它,因此将其再次添加到其缓存和数据库中,这是不合适的。因此,在这种情况下,线程安全(进程安全)缓存很重要。
示例日志:
2015-07-07 22:42:31 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:31 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:40 - myapp.views:30 - DEBUG - from cache : user1100.100.100.100, <type 'unicode'> [14776]
2015-07-07 22:42:41 - myapp.views:29 - DEBUG - not from cache user1100.100.100.100, <type 'unicode'> [14779]
2015-07-07 22:42:41 - myapp.views:30 - DEBUG - from cache : None, <type 'NoneType'> [14779]
2015-07-07 22:42:41 - myapp.views:32 - DEBUG - new username ip [14779]
2015-07-07 22:42:41 - myapp.views:38 - DEBUG - User : user1, ip : 100.100.100.100, noted at time : Tue Jul 7 22:42:41 2015, login_count : None [14779]
您可以看到 gunicorn 进程 14776 首先将其添加到其缓存中,并且下一个请求被 14776 拾取,因此数据库条目仅发生一次,但之后下一个请求被 14779 拾取,并将其添加到其缓存中并因此分贝。
cache = SimpleCache(threshold=1000, default_timeout=3600)
使用基于 memcache 或 redis 的缓存可能会解决这个问题。我自己也在试验。