日期:2014-05-17  浏览次数:20725 次

servlet客户提交速度的限制
请教大侠们个问题,我在服务器端用servlet接受客户提交的数据。我们这边提供给一个http地址供客户调用,如:
http://134.134.23.67:8080/GetMsgServlet/er?username=&password&content=测试;假如客户同过一个循环语句来循环调用这个接口
  for(int i=0;i<100;i++)
  {
  调用......
  }
那我服务器这段要对客户的提交速度做一个限制。那我想要请问下,在servlet服务器端应该怎么实现。

------解决方案--------------------
限制不了,它根本就不是做这个用的。
你只能在程序中加入同步,然后里面加sleep之类的。
------解决方案--------------------
Servlet无法限制提交速度,最多只能线程Servlet,也就是说能限定Servlet的执行顺序,而不能限定有多少Servlet需要执行。唯一的部分就是冲运行环境入手。
因为http的特性,在每次调用的时候会新建一个socket进行数据传输,因此,每次传输的数据的socket相互独立。
可行的办法:1,配置运行环节的连接池,限制服务整体运行次数 。

------解决方案--------------------
可以考虑从request中获取用户ip地址. 在获得请求后将ip地址以及时间戳放入到一个map或者之类的缓存中. 第二次收到请求时判断缓存中是否有该ip, 有的话判断当前时间和记录时间是否小于某个间隔.是的话后面的业务逻辑不执行. 这样子设计的话有两个问题, 一个是虽然后面业务逻辑没有做处理但是实际还是收到该用户的请求. 也就是还是花了时间运行这个servlet. 另一个就是我不确定当一个局域网中同时几个用户发起请求是否会造成问题.这个需要你自己来测试判断了.
大致代码如下:
Java code

public class GetMsgServlet extends HttpServlet {
    /**
     * 用于存放请求IP以及时间戳数据
     */
    private static final Map<String, Long> REQ_IP_CACHE = 
        new HashMap<String, Long>();
    /**
     * 限定的请求时间间隔, 5s
     */
    private final static long TimeInterval = 5000;
    // 你的其他代码
    public void doGet(HttpServletRequest req, HttpServletResponse resp) {
        // 你预先要处理的一些代码.
        boolean isFast = false;
        String reqIp = req.getRemoteAddr();
        Long timestamp = Long.valueOf(System.currentTimeMillis());
        if ( REQ_IP_CACHE.contains(reqIp) ) {
            Long storedTime = REQ_IP_CACHE.get(reqIp);
            if ( (storedTime+TimeInterval) > timestamp ) {
                isFast = true;
            } else {
                REQ_IP_CACHE.put(reqIp, timestamp);
            }
        } else {
            REQ_IP_CACHE.put(reqIp, timestamp);
        }
        if ( !isFast ) {
            // 你的业务代码        
        }
    }
}