如何提高问题排查效率——给项目加入依赖环境扫描器

生产环境问题排查往往费时费力,有的时候还要被迫加班。如何提高问题排查效率呢?

本文介绍一个提高效率的小技巧:给每个项目加入一个简单的组件,类似360的“体检报告”,打开页面就能多线程扫描这些环境是否异常。

最终效果

打开该html页面,稍等片刻即可看到该项目依赖环境的http状态码。

状态码里,404说明项目出了问题,Failed代表服务器没返回http状态码,http服务器有问题(可能是服务器挂了,中间件没起,防火墙屏蔽了等原因)

问题描述

项目部署在某全国专线网络,微服务化后一个区域可能部署多个节点多个项目,彼此之间互相依赖。

问题在于,如果A项目的冗余度不足,A挂掉之后会导致依赖该项目的B项目异常,B项目异常可能导致C项目异常。

最终反馈到开发这的问题现象可能是“C项目出了问题”,如果开发同学看日志能看出来问题所在还好,如果日志读不出问题原因,就得花时间排查。

解决方案

给每个项目加入一个简单的组件,类似360的“体检报告”,打开页面就能查看当前依赖的环境有没有配置错,以及多线程扫描这些环境的http状态码。

前端

html页面

就是拿bootstrap画个表格,拿vue绑定数据。

js多线程扫描

说到多线程扫描,自然会想到后端用线程池扫描。

但是那样做太麻烦,更简单的方法是前端js多线程扫描,思路是每个任务发一个ajax请求,多个ajax请求到了后端,中间件自己有线程池,中间件会为这多个请求分配多线程。

代码如下:

if (typeof String.prototype.startsWith != 'function') {
	String.prototype.startsWith = function(prefix) {
		return this.slice(0, prefix.length) === prefix;
	};
}

var app = new Vue({
			el : "#js-container",
			data : {
				//全用小写
				KEY_WORD:["url","nameserver"],
				configList : []
			},
			methods : {
				init : function() {
					var _this=this;
					$.getJSON("show", function(data) {
								// filter
								for (var k in data) {
									if (k && _this.isKeyOfUrl(k)) {
										var temp = {
											key : k,
											value : data[k],
											status : ''
										}
										// put into the list
										_this.configList.push(temp);
										// ajax to scan the http status
										_this.checkHttpStatus(temp);
									}
								}

							});
				},
				checkHttpStatus : function(item) {
					var url = item.value;
					if (!app.isHttpUrl(url)) {
						return;
					}
					item.status = "Loading";
					$.getJSON("detect", {
								url : item.value
							}, function(result) {
								if (result.success) {
									item.status = result.data;
								} else {
									item.status = "Failed";
								}
							});

				},
				isKeyOfUrl : function(key) {
					
					var lo=key.toLowerCase();
					if(!this.KEY_WORD){
						return false;
					}
					for(var k=0;k< this.KEY_WORD.length;k++){
						if(lo.indexOf(this.KEY_WORD[k])!=-1){
							return true;
						}
					}
					return false;
				},
				isHttpUrl : function(url) {
					return url && url.startsWith("http");
				}
			},
			created : function() {
				this.init();
			},
			mounted : function() {
			}
		});

后端

后端需提供两个接口

  • /show 一个获取配置的接口。
  • /detect?url=http://xxx/ 接收url参数,发送http请求获得状态码,将状态码返回给前端。

具体代码依赖公司框架的API,这里就不放了。

权限

采用项目统一的sso验证,只有管理员权限才能打开该页面、调用后端接口。

Written on June 11, 2018