我正在开发基于play框架2的原型,其中一个要求是过滤来自客户端的重复发布请求。它是一个原型,并试图快速和肮脏的黑客。我有以下数据结构和代码来跟踪重复项。
public class DuplicityService {
private static ConcurrentHashMap<String,List<String>> keyIps = new ConcurrentHashMap<String,List<String>>();
public static boolean isDuplicate(String key,String ip){
List<String> value = keyIps.get(key);
return value != null && value.contains(ip);
}
public static void remove(String key){
keyIps.remove(key);
}
public static void add(String key,String ip){
List<String> value = keyIps.get(key);
if(value == null){
value = new ArrayList<String>();
}
value.add(ip);
keyIps.put(key, value);
}
}
我在我的控制器中使用它
def submitResponse(qkey:String) = CorsAction(parse.json){
req =>
val json = req.body
val key = json.\("Key").as[String]
....
if(DuplicityService.isDuplicate(key,req.remoteAddress)){
...
BadRequest("Duplicate Response " + key)
}
else{
...
DuplicityService.add(key,req.remoteAddress)
Ok(json)
...
}
}
并在单独的控制器方法中从并发hashmap中删除密钥
def publish(key: String) = Authenticated{
...
DuplicityService.remove(key)
...
}
现在问题是,当在我的本地计算机上手动测试时,它可以正常工作。我能够正确识别来自同一IP地址的重复发帖请求。
然而,在heroku上,这不起作用。我能够从同一个客户端发出重复的帖子请求。
我有一个Heroku play 2服务器的基本实例。
任何指针或帮助将不胜感激。
PS:没有使用数据库,是否有更好的方法来做我正在尝试的事情。
由于
答案 0 :(得分:1)
我怀疑Heroku可能会创建多个JVM实例,无论是刷新还是复制静态单例。
使用Memcached或等效的(但可能不是一个完全成熟的数据库,因为你基本上只是缓存)将是我的偏好。
或者,根据应用程序的可伸缩性需求,为避免缓存成为瓶颈,您可能希望以更懒惰和分散的方式处理重复请求的方式设计应用程序;符合http://en.m.wikipedia.org/wiki/Eventual_consistency精神的东西。