Java REST服务:防止每个用户并发调用
我正在开发一个REST服务(使用RESTeasy),它执行大量计算并生成大量结果(将下载到文件中)。 为了保护系统,我们决定通过防止并发调用来限制同一用户的执行 我想在会话中加入一个变量,如下所示:Java REST服务:防止每个用户并发调用,java,rest,web-services,concurrency,resteasy,Java,Rest,Web Services,Concurrency,Resteasy,我正在开发一个REST服务(使用RESTeasy),它执行大量计算并生成大量结果(将下载到文件中)。 为了保护系统,我们决定通过防止并发调用来限制同一用户的执行 我想在会话中加入一个变量,如下所示: //check if service is running before execution if (Boolean.parseBoolean((String) session.getAttribute("isRunning"))) { throw new WebApplicatio
//check if service is running before execution
if (Boolean.parseBoolean((String) session.getAttribute("isRunning"))) {
throw new WebApplicationException(Response.status(
Response.Status.FORBIDDEN).entity("Service is currently running!").build());
}
//on execution
session.setAttribute("isRunning", "true");
//after execution
finally {
session.setAttribute("isRunning", "false");
}
但这限制了每个会话的使用量,,而不是每个用户的使用量您走在正确的轨道上 在会话中存储一个集合(我称之为UserSet) 当你收到请求时, 请执行以下操作:
编辑:根据John Wu的评论更正了范围。基于@dwb建议的方法,以下是我的答案:
//globally defined set holding ids of users currently executing the service
private static Set<String> currentUsers = Collections.synchronizedSortedSet(new TreeSet<String>());
//check if service is running before execution
if (isCurrentlyRunningByUser(request.getRemoteUser())) {
throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN).entity("Service is currently running!").build());
}
//after execution
finally {
currentUsers.remove(user);
}
/**
* checks if user is currently running the service. if yes, returns true.
* if no, add user to current users set, and returns false
* @param remoteUser user asking to execute the service
* @return true if service is being run by the user
*/
private boolean isCurrentlyRunningByUser(String user) {
synchronized (currentUsers) {
Iterator it = currentUsers.iterator();
while (it.hasNext()) {
if (user.equals(it.next())) {
return true;
}
}
currentUsers.add(user);
}
return false;
}
//保存当前执行服务的用户ID的全局定义集
private static Set currentUsers=Collections.synchronizedSortedSet(new TreeSet());
//执行前检查服务是否正在运行
if(isCurrentlyRunningByUser(request.getRemoteUser())){
抛出新的WebApplicationException(Response.status(Response.status.FORBIDDEN).entity(“服务当前正在运行!”).build();
}
//行刑后
最后{
当前用户。删除(用户);
}
/**
*检查用户当前是否正在运行该服务。如果是,则返回true。
*如果否,则将用户添加到当前用户集,并返回false
*@param remoteUser请求执行服务的用户
*@如果用户正在运行服务,则返回true
*/
私有布尔值isCurrentlyRunningByUser(字符串用户){
已同步(当前用户){
Iterator it=currentUsers.Iterator();
while(it.hasNext()){
if(user.equals(it.next())){
返回true;
}
}
currentUsers.add(用户);
}
返回false;
}
您的系统如何识别用户?它是否接受登录操作并创建会话,是否随每个请求一起发送凭据,是否使用客户端证书等?是。我可以通过请求对象访问用户。身份验证是在基本模式下完成的。您必须将“用户集”存储在应用程序状态,而不是会话状态。否则,它将始终只包含一个用户,即当前用户。