流量监控实战

前言
流量监控(后面简称流控)是一个比较大的领域,也是互联网行业比较关注的领域。当业务发展到一定阶段的时候,性能网往往会成为业务发展的主要瓶颈。一个好的应用除了最基本的可以在低并发下对外服务之外,能否支撑高并发访问是大型互联网网站比较关心的问题。拿火车订票网(12306)来说,在平时低并发下都没有什么问题,很容易的可以登录系统,订到票,一旦到了春节等节假日就出现问题,这点如果在12306上订过票的同学就比较有感受。CSDN上不乏有牛人站在一个架构师的角度来思考12306。
支持高并发在流量方面除了单机性能最大化之外另外就是良好的水平扩展能力。单机性能的优化很容易就到达一个极致,而水平扩展可以说是无限的。前段时间在CSDN上看到哪个网站(好像是Amazon)已经达到自动扩容(也就是弹性扩容)的地步。当然这里会涉及到非常多的领域,这些都不是本文要讨论的。OK,回来看看我对流控的一些理解。
一、为什么需要流量监控
流量监控作为一个数据收集窗口,不管对开发还是运营都是做出决策和分析问题的一个基础和有力依据。一个没有任何监控的系统对于开发和运营而言完全是一场噩梦,因为系统的运行完全是黑盒。缩小范围到流控领域,如果没有监控也就无法判断当前系统的流量情况,是否需要加机器、是否需要限流、性能的瓶颈在哪里都不得而知。这些都没有任何的数据基础来做出这些决策,流量监控对于当前系统问题排查和后续系统的重构和解藕拆分都有重要的意义。这里也稍微举个简单的例子:比如之前有两个应用部署在同一台机器上,由于业务的增长,两个应用的压力都随之增大,通过监控可以实时掌握两个应用的性能情况,后续两个应用可以在出现问题之前进行拆分,而不是到问题出现了再解决。
二、流量监控的粒度
理论上来讲粒度越细越好。实际情况中需要考虑诸多因素,比如实现成本及价值(也就是成本收益)。当前整个系统的情况都会影响在做流控的粒度。一般来讲分为:系统级别>应用级别>方法级别。粒度越细数据收集越多,定位问题和做出决策也会更准确,当然在信息的分析上也要花更多时间。举个简单的例子:假设监控是系统级别,一次用户请求所涉及的应用有10个。现在发现请求非常慢,性能有问题。监控在系统级别的话可以知道系统有问题,但所涉及的10个应用中却无法知道是哪个或那些应用出了问题。如果是应用级别,就知道哪些应用除了问题。如果是方法级别甚至可以定位到哪个方法的性能有问题。实际场景中这三种粒度的监控都有。可以用来分析不同粒度的问题。对于管理者而言他可能只关心系统级别最多应用级别,而对于开发而言这三个都需要,解决问题则信息越容易找到问题所在。
三、监控的实现方法
一般来讲监控都会对系统造成一定的侵入性,粒度越细侵入性越强。很多人会想到Spring的aop这种方式来达到对原系统的无侵入监控。实践证明可行,但实现复杂,对个性化的监控有比较大的局限性,另外性能的损失也是需要考虑的。往往流量监控不会单独存在,会承担一部分决策性工作。比如简单的说发现目前某应用流量过大,容易导致系统的宕机会启动限流策略、分流以及服务降级等策略来保证主干应用的可用。
实现原理应该说非常简单,如果一次完整的请求比作一条河流的话,监控相当于水坝。洪水期间其实就相当于超大负荷的请求,为了不使下游遭殃。“水坝”会启动一些措施来防止“洪水”到达下游。当然整个防洪的经验也为后续的“水坝”加固也提供了数据基础。淘宝的双11其实就相当于一次“洪水”。所以淘宝双11不仅承担业务上指标,也是为系统提供一次宝贵的实战测试。
四、实践
讲了这么多理论来点实践,我在《学习项目》中对流控做了一个比较有限的实践,由于没有真实的高并发场景,模拟的效果也非常有限。这些都放一边,讲讲我整个的监控策略,功能实现的非常简单,主要是其中的一些思想。
先上一张UML图:
核心的类就是FlowMonitor。主要记录了当前正在运行的线程数,最大瞬时线程数,通过的线程数,丢失线程数。
这里解释一下这几个词的含义和产生背景。
运行的线程数:这个比较好理解,监控的当前应用或者方法有多少线程正在运行。
最大瞬时线程数:因为5分钟会把上面几个数据记录到数据库,5分钟内无法记录到最大的一个瞬时线程,只能记录记录的当时的一个运行线程数,这样对于整个数据是不完整的。
通过的线程数:由于监控的同时会做限流,比如我限制最大的运行线程数为10,所以当发现最大线程数已经大于我所设置允许最大线程数就会做丢弃处理(当然还会有其他处理策略,我这里只是以最简单的方法来描述整个监控的思想)。
丢失的线程数:参考通过的线程数。

介绍了这几个词后对整个监控大体上已经知道其工作原理。

下面帖一个具体的实现代码:
public abstract class MonitorHandler implements Handler{
	
	private static final FlowMonitor flowMonitor = FlowMonitorFactory.regist(AbstractHandler.class.getName());
	
	public void run(){
		//做流控方面的事情
		if(!flowMonitor.entry(this.getClass().getName())){
			return;
		}
		//通过
		try{
			handle();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//需要释放资源
			flowMonitor.release(this.getClass().getName());
		}
	}
}
我这里采用的是侵入性最强的一种应用实现,当然也最简单,监控的是方法级别的,因为整个应用场景是一个链式处理,只要继承于MonitorHandler然后配置最大的流量限制阀门就OK了,对于具体的实现者而言还是相对透明的。并非需要他关心整个流控的细节。
tour.ziubao.handler.DispatchHandler=10
上面是一条配置文件,DispatchHandler继承了MonitorHandler,这样就可以对 DispatchHandler作流量监控。

上面是一张对整个流量监控的展现图

一个简单流量监控就完了,我还实现了对于RT(应用响应时间)的监控,由于实现大同小异,就不再作阐述了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值