web系统流量控制



web系统流量控制 一个新系统上线之前都要做性能测试(并发数、QPS、TPS、页面响应时间等),该措施一个有效前提是我们知道系统的预估承载量,

比如我们知道网站的日访问PV,访问的时间段等,有了这些数据并根据下面的公式,就不难做性能测试了。

 

 

 

 

 

日PV和TPS之间如何对应?公式就是80%的日PV,发生在T小时内。则公式为:

 

TPS =  日PV * 80% / 24 * 60 * 60 * (T/24)

 

定义 R = 1万 * 80% / 24 * 60 * 60 * (T/24)  = 10000 * 24 * 0.8 / 24 * 3600 * T = 2.2222/T

 

TPS = 日PV(万) * R 这里的TPS就是平均的TPS。

 

 

 

但是也存在另外一种情况,比如一个网站要搞一个周年庆大型促销活动,由于第一次搞这样的活动,在数据方面并没有多少经验,只能凭经验粗略预估访问量。此时我们保证系统在满足预估访问量同时,还要重点考虑一些突发情况,比如那天pv量真的超过预值怎么办?如果系统设计不当,就会导致大量的请求阻塞,响应超时,后果相当严重。此时一个行之有效的方法是限流,也称之为流量控制。

 

 

 

今天介绍一种简单的流量控制方法,借助于servlet容器机制,对所有的请求进行拦截,并通过缓存计算每秒的访问数,如果超过了阀值,直接返回错误页面。好处是:配置简单,通过代码来实现 ;缺点:超过阀值的请求直接丢弃,不做处理。

 

1.在web.xml文件中配置一个Filter过滤器

 

 

 

  1.  <filter>
  2.        <filter-name>name</filter-name>
  3.        <filter-class>类名</filter-class>
  4.        <init-param>
  5.     <param-name>name</param-name>
  6.     <param-value>value</param-value>
  7. </init-param>
  8.    </filter>
  9.      <filter-mapping>
  10.        <filter-name>name</filter-name>
  11.        <url-pattern>/order/*</url-pattern>
  12.     </filter-mapping>

 


  <filter>
        <filter-name>name</filter-name>
        <filter-class>类名</filter-class>
        <init-param>
		<param-name>name</param-name>
		<param-value>value</param-value>
	</init-param>
    </filter>
      <filter-mapping>
        <filter-name>name</filter-name>
        <url-pattern>/order/*</url-pattern>
     </filter-mapping>


2.定义一个类实现Filer接口
将<init-param>标签里面用于初始化的属性读出来。

 

 

 

 

  1. public void init(FilterConfig arg0) throws ServletException {
  2.     //预设每秒系统处理请求数的最大值
  3.         String max= arg0.getInitParameter(“maxRequest”);
  4.         if (sd != null) {
  5.             max= max;
  6.         }
  7.     }

 

public void init(FilterConfig arg0) throws ServletException {
	//预设每秒系统处理请求数的最大值
        String max= arg0.getInitParameter("maxRequest");
        if (sd != null) {
            max= max;
        }
    }

核心拦截业务

 

 

 

 

  1.    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
  2.                                                                                             ServletException {
  3. //统一资源标识符,不含有域名
  4.        String uri = ((HttpServletRequest) request).getRequestURI();
  5.        if (enabled && isUriNeedFiltered(uri)) {
  6.            if (controller.isAllowed()) {
  7.                chain.doFilter(request, response);
  8.            } else {
  9.                request.getRequestDispatcher(“错误页面”).forward(request, response);
  10.            }
  11.        } else {
  12.            chain.doFilter(request, response);
  13.        }
  14.    }

 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
                                                                                             ServletException {
	//统一资源标识符,不含有域名
        String uri = ((HttpServletRequest) request).getRequestURI();
        if (enabled && isUriNeedFiltered(uri)) {
            if (controller.isAllowed()) {
                chain.doFilter(request, response);
            } else {
                request.getRequestDispatcher(“错误页面”).forward(request, response);
            }

        } else {
            chain.doFilter(request, response);
        }

    }

缓存的key值(以秒做为key值)

 

 

 

 

  1. public String getKey() {
  2.     return new SimpleDateFormat(“yyyyMMddHHmmss”).format(new Date());
  3. }

 

    public String getKey() {
        return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
    }