- 浏览: 2594972 次
- 来自: 杭州
文章分类
- 全部博客 (1190)
- webwork (4)
- 网摘 (18)
- java (104)
- hibernate (1)
- Linux (85)
- 职业发展 (1)
- activeMQ (2)
- netty (15)
- svn (1)
- webx3 (12)
- mysql (81)
- css (1)
- HTML (6)
- apache (3)
- 测试 (2)
- javascript (1)
- 储存 (1)
- jvm (5)
- code (13)
- 多线程 (12)
- Spring (18)
- webxs (2)
- python (119)
- duitang (0)
- mongo (3)
- nosql (4)
- tomcat (4)
- memcached (20)
- 算法 (28)
- django (28)
- shell (1)
- 工作总结 (5)
- solr (42)
- beansdb (6)
- nginx (3)
- 性能 (30)
- 数据推荐 (1)
- maven (8)
- tonado (1)
- uwsgi (5)
- hessian (4)
- ibatis (3)
- Security (2)
- HTPP (1)
- gevent (6)
- 读书笔记 (1)
- Maxent (2)
- mogo (0)
- thread (3)
- 架构 (5)
- NIO (5)
- 正则 (1)
- lucene (5)
- feed (4)
- redis (17)
- TCP (6)
- test (0)
- python,code (1)
- PIL (3)
- guava (2)
- jython (4)
- httpclient (2)
- cache (3)
- signal (1)
- dubbo (8)
- HTTP (4)
- json (3)
- java socket (1)
- io (2)
- socket (22)
- hash (2)
- Cassandra (1)
- 分布式文件系统 (5)
- Dynamo (2)
- gc (8)
- scp (1)
- rsync (1)
- mecached (0)
- mongoDB (29)
- Thrift (1)
- scribe (2)
- 服务化 (3)
- 问题 (83)
- mat (1)
- classloader (2)
- javaBean (1)
- 文档集合 (27)
- 消息队列 (3)
- nginx,文档集合 (1)
- dboss (12)
- libevent (1)
- 读书 (0)
- 数学 (3)
- 流程 (0)
- HBase (34)
- 自动化测试 (1)
- ubuntu (2)
- 并发 (1)
- sping (1)
- 图形 (1)
- freemarker (1)
- jdbc (3)
- dbcp (0)
- sharding (1)
- 性能测试 (1)
- 设计模式 (2)
- unicode (1)
- OceanBase (3)
- jmagick (1)
- gunicorn (1)
- url (1)
- form (1)
- 安全 (2)
- nlp (8)
- libmemcached (1)
- 规则引擎 (1)
- awk (2)
- 服务器 (1)
- snmpd (1)
- btrace (1)
- 代码 (1)
- cygwin (1)
- mahout (3)
- 电子书 (1)
- 机器学习 (5)
- 数据挖掘 (1)
- nltk (6)
- pool (1)
- log4j (2)
- 总结 (11)
- c++ (1)
- java源代码 (1)
- ocr (1)
- 基础算法 (3)
- SA (1)
- 笔记 (1)
- ml (4)
- zokeeper (0)
- jms (1)
- zookeeper (5)
- zkclient (1)
- hadoop (13)
- mq (2)
- git (9)
- 问题,io (1)
- storm (11)
- zk (1)
- 性能优化 (2)
- example (1)
- tmux (1)
- 环境 (2)
- kyro (1)
- 日志系统 (3)
- hdfs (2)
- python_socket (2)
- date (2)
- elasticsearch (1)
- jetty (1)
- 树 (1)
- 汽车 (1)
- mdrill (1)
- 车 (1)
- 日志 (1)
- web (1)
- 编译原理 (1)
- 信息检索 (1)
- 性能,linux (1)
- spam (1)
- 序列化 (1)
- fabric (2)
- guice (1)
- disruptor (1)
- executor (1)
- logback (2)
- 开源 (1)
- 设计 (1)
- 监控 (3)
- english (1)
- 问题记录 (1)
- Bitmap (1)
- 云计算 (1)
- 问题排查 (1)
- highchat (1)
- mac (3)
- docker (1)
- jdk (1)
- 表达式 (1)
- 网络 (1)
- 时间管理 (1)
- 时间序列 (1)
- OLAP (1)
- Big Table (0)
- sql (1)
- kafka (1)
- md5 (1)
- springboot (1)
- spring security (1)
- Spring Boot (3)
- mybatis (1)
- java8 (1)
- 分布式事务 (1)
- 限流 (1)
- Shadowsocks (0)
- 2018 (1)
- 服务治理 (1)
- 设计原则 (1)
- log (0)
- perftools (1)
最新评论
-
Aqu415:
,默认是netty还是hassion?
dubbo入门 -
siphlina:
课程——基于Python数据分析与机器学习案例实战教程分享网盘 ...
Python机器学习库 -
san_yun:
leibnitz 写道hi,我想知道,无论在92还是94版本, ...
hbase的行锁与多版本并发控制(MVCC) -
leibnitz:
hi,我想知道,无论在92还是94版本,更新时(如Puts)都 ...
hbase的行锁与多版本并发控制(MVCC) -
107x:
不错,谢谢!
Latent Semantic Analysis(LSA/ LSI)算法简介
最近有点痴呆,因为解决了太多的痴呆问题,
服务框架实施面超来超广,已有50多个项目在使用,
每天都要去帮应用查问题,来来回回,
发现大部分都是配置错误,或者重复的文件或类,或者网络不通等,
所以准备在新版本中加入防痴呆设计,估且这么叫吧,
可能很简单,但对排错速度还是有点帮助,
希望能抛砖引玉,也希望大家多给力,想出更多的防范措施共享出来。
(1) 检查重复的jar包
最痴呆的问题,就是有多个版本的相同jar包,
会出现新版本的A类,调用了旧版本的B类,
而且和JVM加载顺序有关,问题带有偶然性,误导性,
遇到这种莫名其妙的问题,最头疼,
所以,第一条,先把它防住,
在每个jar包中挑一个一定会加载的类,加上重复类检查,
给个示例:
static {
Duplicate.checkDuplicate(Xxx.class);
}
检查重复工具类:
(2) 检查重复的配置文件
配置文件加载错,也是经常碰到的问题,
用户通常会和你说:“我配置的很正确啊,不信我发给你看下,但就是报错”,
然后查一圈下来,原来他发过来的配置根本没加载,
平台很多产品都会在classpath下放一个约定的配置,
如果项目中有多个,通常会取JVM加载的第一个,
为了不被这么低级的问题折腾,
和上面的重复jar包一样,在配置加载的地方,加上:
Duplicate.checkDuplicate("xxx.properties");
(3) 检查所有可选配置
必填配置估计大家都会检查,因为没有的话,根本没法运行,
但对一些可选参数,也应该做一些检查,
比如:服务框架允许通过注册中心关联服务消费者和服务提供者,
也允许直接配置服务提供者地址点对点直连,
这时候,注册中心地址是可选的,
但如果没有配点对点直连配置,注册中心地址就一定要配,
这时候也要做相应检查。
(4) 异常信息给出解决方案
在给应用排错时,最怕的就是那种只有简单的一句错误描述,啥信息都没有的异常信息,
比如上次碰到一个Failed to get session异常,
就这几个单词,啥都没有,哪个session出错? 什么原因Failed?
看了都快疯掉,因是线上环境不好调试,而且有些场景不是每次都能重现,
异常最基本要带有上下文信息,包括操作者,操作目标,原因等,
最好的异常信息,应给出解决方案,比如上面可以给出:
“从10.20.16.3到10.20.130.20:20880之间的网络不通,
请在10.20.16.3使用telnet 10.20.130.20 20880测试一下网络,
如果是跨机房调用,可能是防火墙阻挡,请联系SA开通访问权限”
等等,上面甚至可以根据IP段判断是不是跨机房。
另外一个例子,是spring-web的context加载,
如果在getBean时spring没有被启动,
spring会报一个错,错误信息写着:
请在web.xml中加入:<listener>…<init-param>…
多好的同学,看到错误的人复制一下就完事了,我们该学学,
可以把常见的错误故意犯一遍,看看错误信息能否自我搞定问题,
或者把平时支持应用时遇到的问题及解决办法都写到异常信息里。
(5) 日志信息包含环境信息
每次应用一出错,应用的开发或测试就会把出错信息发过来,询问原因,
这时候我都会问一大堆套话,
用的哪个版本呀?
是生产环境还是开发测试环境?
哪个注册中心呀?
哪个项目中的?
哪台机器呀?
哪个服务?
。。。
累啊,最主要的是,有此开发或测试人员根本分不清,
没办法,只好提供上门服务,浪费的时间可不是浮云,
所以,日志中最好把需要的环境信息一并打进去,
最好给日志输出做个包装,统一处理掉,免得忘了。
包装Logger接口如:
public void error(String msg, Throwable e) {
delegate.error(msg + " on server " + InetAddress.getLocalHost() + " using version " + Version.getVersion(), e);
}
获取版本号工具类:
(6) kill之前先dump
每次线上环境一出问题,大家就慌了,
通常最直接的办法回滚重启,以减少故障时间,
这样现场就被破坏了,要想事后查问题就麻烦了,
有些问题必须在线上的大压力下才会发生,
线下测试环境很难重现,
不太可能让开发或Appops在重启前,
先手工将出错现场所有数据备份一下,
所以最好在kill脚本之前调用dump,
进行自动备份,这样就不会有人为疏忽。
dump脚本示例:
服务框架实施面超来超广,已有50多个项目在使用,
每天都要去帮应用查问题,来来回回,
发现大部分都是配置错误,或者重复的文件或类,或者网络不通等,
所以准备在新版本中加入防痴呆设计,估且这么叫吧,
可能很简单,但对排错速度还是有点帮助,
希望能抛砖引玉,也希望大家多给力,想出更多的防范措施共享出来。
(1) 检查重复的jar包
最痴呆的问题,就是有多个版本的相同jar包,
会出现新版本的A类,调用了旧版本的B类,
而且和JVM加载顺序有关,问题带有偶然性,误导性,
遇到这种莫名其妙的问题,最头疼,
所以,第一条,先把它防住,
在每个jar包中挑一个一定会加载的类,加上重复类检查,
给个示例:
static {
Duplicate.checkDuplicate(Xxx.class);
}
检查重复工具类:
public final class Duplicate { private Duplicate() {} public static void checkDuplicate(Class cls) { checkDuplicate(cls.getName().replace('.', '/') + ".class"); } public static void checkDuplicate(String path) { try { // 在ClassPath搜文件 Enumeration urls = Thread.currentThread().getContextClassLoader().getResources(path); Set files = new HashSet(); while (urls.hasMoreElements()) { URL url = urls.nextElement(); if (url != null) { String file = url.getFile(); if (file != null && file.length() > 0) { files.add(file); } } } // 如果有多个,就表示重复 if (files.size() > 1) { logger.error("Duplicate class " + path + " in " + files.size() + " jar " + files); } } catch (Throwable e) { // 防御性容错 logger.error(e.getMessage(), e); } } }
(2) 检查重复的配置文件
配置文件加载错,也是经常碰到的问题,
用户通常会和你说:“我配置的很正确啊,不信我发给你看下,但就是报错”,
然后查一圈下来,原来他发过来的配置根本没加载,
平台很多产品都会在classpath下放一个约定的配置,
如果项目中有多个,通常会取JVM加载的第一个,
为了不被这么低级的问题折腾,
和上面的重复jar包一样,在配置加载的地方,加上:
Duplicate.checkDuplicate("xxx.properties");
(3) 检查所有可选配置
必填配置估计大家都会检查,因为没有的话,根本没法运行,
但对一些可选参数,也应该做一些检查,
比如:服务框架允许通过注册中心关联服务消费者和服务提供者,
也允许直接配置服务提供者地址点对点直连,
这时候,注册中心地址是可选的,
但如果没有配点对点直连配置,注册中心地址就一定要配,
这时候也要做相应检查。
(4) 异常信息给出解决方案
在给应用排错时,最怕的就是那种只有简单的一句错误描述,啥信息都没有的异常信息,
比如上次碰到一个Failed to get session异常,
就这几个单词,啥都没有,哪个session出错? 什么原因Failed?
看了都快疯掉,因是线上环境不好调试,而且有些场景不是每次都能重现,
异常最基本要带有上下文信息,包括操作者,操作目标,原因等,
最好的异常信息,应给出解决方案,比如上面可以给出:
“从10.20.16.3到10.20.130.20:20880之间的网络不通,
请在10.20.16.3使用telnet 10.20.130.20 20880测试一下网络,
如果是跨机房调用,可能是防火墙阻挡,请联系SA开通访问权限”
等等,上面甚至可以根据IP段判断是不是跨机房。
另外一个例子,是spring-web的context加载,
如果在getBean时spring没有被启动,
spring会报一个错,错误信息写着:
请在web.xml中加入:<listener>…<init-param>…
多好的同学,看到错误的人复制一下就完事了,我们该学学,
可以把常见的错误故意犯一遍,看看错误信息能否自我搞定问题,
或者把平时支持应用时遇到的问题及解决办法都写到异常信息里。
(5) 日志信息包含环境信息
每次应用一出错,应用的开发或测试就会把出错信息发过来,询问原因,
这时候我都会问一大堆套话,
用的哪个版本呀?
是生产环境还是开发测试环境?
哪个注册中心呀?
哪个项目中的?
哪台机器呀?
哪个服务?
。。。
累啊,最主要的是,有此开发或测试人员根本分不清,
没办法,只好提供上门服务,浪费的时间可不是浮云,
所以,日志中最好把需要的环境信息一并打进去,
最好给日志输出做个包装,统一处理掉,免得忘了。
包装Logger接口如:
public void error(String msg, Throwable e) {
delegate.error(msg + " on server " + InetAddress.getLocalHost() + " using version " + Version.getVersion(), e);
}
获取版本号工具类:
public final class Version { private Version() {} private static final Logger logger = LoggerFactory.getLogger(Version.class); private static final Pattern VERSION_PATTERN = Pattern.compile("([0-9][0-9\\.\\-]*)\\.jar"); private static final String VERSION = getVersion(Version.class, "2.0.0"); public static String getVersion(){ return VERSION; } public static String getVersion(Class cls, String defaultVersion) { try { // 首先查找MANIFEST.MF规范中的版本号 String version = cls.getPackage().getImplementationVersion(); if (version == null || version.length() == 0) { version = cls.getPackage().getSpecificationVersion(); } if (version == null || version.length() == 0) { // 如果MANIFEST.MF规范中没有版本号,基于jar包名获取版本号 String file = cls.getProtectionDomain().getCodeSource().getLocation().getFile(); if (file != null && file.length() > 0 && file.endsWith(".jar")) { Matcher matcher = VERSION_PATTERN.matcher(file); while (matcher.find() && matcher.groupCount() > 0) { version = matcher.group(1); } } } // 返回版本号,如果为空返回缺省版本号 return version == null || version.length() == 0 ? defaultVersion : version; } catch (Throwable e) { // 防御性容错 // 忽略异常,返回缺省版本号 logger.error(e.getMessage(), e); return defaultVersion; } } }
(6) kill之前先dump
每次线上环境一出问题,大家就慌了,
通常最直接的办法回滚重启,以减少故障时间,
这样现场就被破坏了,要想事后查问题就麻烦了,
有些问题必须在线上的大压力下才会发生,
线下测试环境很难重现,
不太可能让开发或Appops在重启前,
先手工将出错现场所有数据备份一下,
所以最好在kill脚本之前调用dump,
进行自动备份,这样就不会有人为疏忽。
dump脚本示例:
JAVA_HOME=/usr/java OUTPUT_HOME=~/output DEPLOY_HOME=`dirname $0` HOST_NAME=`hostname` DUMP_PIDS=`ps --no-heading -C java -f --width 1000 | grep "$DEPLOY_HOME" |awk '{print $2}'` if [ -z "$DUMP_PIDS" ]; then echo "The server $HOST_NAME is not started!" exit 1; fi DUMP_ROOT=$OUTPUT_HOME/dump if [ ! -d $DUMP_ROOT ]; then mkdir $DUMP_ROOT fi DUMP_DATE=`date +%Y%m%d%H%M%S` DUMP_DIR=$DUMP_ROOT/dump-$DUMP_DATE if [ ! -d $DUMP_DIR ]; then mkdir $DUMP_DIR fi echo -e "Dumping the server $HOST_NAME ...\c" for PID in $DUMP_PIDS ; do $JAVA_HOME/bin/jstack $PID > $DUMP_DIR/jstack-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jinfo $PID > $DUMP_DIR/jinfo-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jstat -gcutil $PID > $DUMP_DIR/jstat-gcutil-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jstat -gccapacity $PID > $DUMP_DIR/jstat-gccapacity-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jmap $PID > $DUMP_DIR/jmap-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jmap -heap $PID > $DUMP_DIR/jmap-heap-$PID.dump 2>&1 echo -e ".\c" $JAVA_HOME/bin/jmap -histo $PID > $DUMP_DIR/jmap-histo-$PID.dump 2>&1 echo -e ".\c" if [ -r /usr/sbin/lsof ]; then /usr/sbin/lsof -p $PID > $DUMP_DIR/lsof-$PID.dump echo -e ".\c" fi done if [ -r /usr/bin/sar ]; then /usr/bin/sar > $DUMP_DIR/sar.dump echo -e ".\c" fi if [ -r /usr/bin/uptime ]; then /usr/bin/uptime > $DUMP_DIR/uptime.dump echo -e ".\c" fi if [ -r /usr/bin/free ]; then /usr/bin/free -t > $DUMP_DIR/free.dump echo -e ".\c" fi if [ -r /usr/bin/vmstat ]; then /usr/bin/vmstat > $DUMP_DIR/vmstat.dump echo -e ".\c" fi if [ -r /usr/bin/mpstat ]; then /usr/bin/mpstat > $DUMP_DIR/mpstat.dump echo -e ".\c" fi if [ -r /usr/bin/iostat ]; then /usr/bin/iostat > $DUMP_DIR/iostat.dump echo -e ".\c" fi if [ -r /bin/netstat ]; then /bin/netstat > $DUMP_DIR/netstat.dump echo -e ".\c" fi echo "OK!"
发表评论
-
如何更好地学习dubbo源代码
2018-09-14 17:28 443http://jm.taobao.org/2013/11/ ... -
一种队列限流方案
2014-08-26 19:29 1748参考:http://my.oschina.net/le284 ... -
dubbo入门
2013-07-02 10:00 22067dubbo是阿里巴巴开源的 ... -
dubbo性能测试报告
2012-10-04 12:07 16158Scene a、本次性能测试,测试了dubbo2.0所有支持 ... -
dubbo协议参考
2012-10-03 14:15 25726http://code.alibabatech.com/wik ... -
dubbo导致死锁问题
2012-09-27 14:03 7533延迟暴露 (+ ) (# ) 如果 ... -
服务化需要考虑的问题
2012-09-27 13:36 1655在大规模服务化之前,应用可能只是通过RMI或Hessian等工 ...
相关推荐
血管性痴呆重在预防
常按几个穴位预防老年痴呆
手机电磁波或可预防老人痴呆症.pdf
手机电磁波可能有预防老年痴呆的作用.pdf
老年痴呆Meta分析,有关老年痴呆的多因素Meta分析;
我国老年痴呆研究概况.pdf
以中医“五神”学说辨析老年性痴呆,滕晶,,初步探讨了五神学说的内涵及特点。结合老年性痴呆主要表现为神志异常的特点,以五神学说辨析痴呆形成的发病机制及病证特点,提出�
老年痴呆症的心理治疗,老年痴呆症的心理治疗课件,老年痴呆症的心理治疗PPT
本研究使用辅助数据分析的目的是确定影响住在疗养院中的痴呆患者言语激动的因素。 这项研究是对现有原始定量数据集(n = 193)的二次分析。 本研究共纳入166名受试者的数据,原因是27名受试者的数据没有出现口头躁动...
一种算法,一天(每天一小步,回首大进步。一天刷一题,防老防痴呆)坚持刷题,回首过往,能有一些习惯一直坚持是一种习惯。2020加油。使用记录。
线粒体与老年性痴呆,曾芳,唐勇,线粒体形态结构和功能的变化在AD的发生发展中起着重要的作用,本文从AD与线粒体形态结构异常(包括线粒体形态结构异常、线粒体基�
在日本和其他发达国家,老年痴呆症患者的医疗保健是重要的医疗保健问题。 重要的是,日本的医护人员也正在变老。 为了解决该问题,人们正在意识到使用机器人,并开始满足医疗保健和福利实践的需求。 这项研究的目的...
这项研究的目的是澄清合格的痴呆症照护者认为,为老年痴呆症患者提供的“照顾个性的护理”的内容。 我们采访了21位在A州团体家庭中合格的痴呆症护理人员,他们的实际内容和对“尊重个性的护理”的想法。 使用改进的...
七福饮治疗痴呆健忘古籍数据挖掘.pdf
通过将John Stuart Mill和Austin Bradford Hill爵士的因果模型应用于机理和流行病学证据,可以得出电离辐射对痴呆症的影响。 由于已知电离辐射会以中等剂量杀死动物实验中的脑细胞并影响动物实验中的海马神经发生,...
对于患有痴呆症的老年人来说,流浪是最成问题,频繁和危险的行为之一。 由于流浪行为的普遍性,负面结果和照顾者的负担,管理流浪行为已变得越来越重要。 我们研究提出了一种主动的基于红外的方法,通过监视老年人...
缺氧诱导因子-1在慢性脑缺血血管性痴呆中的研究进展,金香兰,,血管性痴呆发病机制复杂,其中慢性脑缺血成为血管性痴呆发生的重要病理生理学基础,缺氧诱导因子-1(HIF-1)作为缺血、缺氧性损伤中最
老年痴呆CT数据集,使用模糊彩色图像增强(FCIE)算法重建原始脑MRI数据集。轻度痴呆中度痴呆非轻度痴呆非常轻度痴呆共计6400张MRI图像,训练-验证-测试的分割比例为75% -15- 10%。
findPicture uniapp实现防痴呆小游戏最后编译为微信小程序《你变笨了吗?》
氧化应激与老年痴呆的关系,陈爽,黄菊芳,氧化应激是导致阿尔兹海默病发病过程的一个关键因素。因为这种应激在衰老过程中随着脑组织氧化损伤而影响学习和记忆能力,在轻度