我们都知道一个新系统上线之前都要做性能测试(并发数、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过滤器
<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>标签里面用于初始化的属性读出来。
public void init(FilterConfig arg0) throws ServletException {
//预设每秒系统处理请求数的最大值
String max= arg0.getInitParameter("maxRequest");
if (sd != null) {
max= max;
}
}
核心拦截业务
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值)
public String getKey() {
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}