java程序跟踪分析
需要的安装包:
[root@liujiangbu src]# ll
总用量 572540
-rw-r--r--. 1 root root 8534562 7月 6 14:06 apache-maven-3.5.0-bin.tar.gz
-rw-r--r--. 1 root root 8975395 7月 6 13:38 apache-tomcat-7.0.79.tar.gz
-rw-r--r--. 1 root root 108090836 6月 20 18:41 hbase-1.1.11-bin.tar.gz
-rw-r--r--. 1 root root 153530841 7月 6 13:49 jdk-7u80-linux-x64.tar.gz
-rw-r--r--. 1 root root 185540433 6月 29 17:50 jdk-8u131-linux-x64.tar.gz
-rw-r--r--. 1 root root 31339914 7月 6 15:07 pinpoint-collector-1.5.2.war
-rw-r--r--. 1 root root 54505168 7月 6 15:11 pinpoint-web-1.5.2.war
-rw-r--r--. 1 root root 2899300 7月 6 14:53 zookeeper-3.4.6-10.el6.x86_64.rpm
-rw-r--r--. 1 root root 2899300 7月 6 14:56 pinpoint-agent-1.5.2.tar
Pinpoint一个分布式事务跟踪系统的平台,思路基于google Dapper,用于基于java的大规模分布式系统,通过跟踪分布式应用之间的调用来提供解决方案,以帮助分析系统的总体结构和内部模块之间如何相互联系。Pinpoint的目标就是为n(n>=1)层架构开发新的跟踪平台,为n层架构的系统提供解决方案。
0.1 Pinpoint的特点如下:
分布式事务跟踪,跟踪跨分布式应用的消息
自动检测应用拓扑,帮助你搞清楚应用的架构
水平扩展以便支持大规模服务器集群
提供代码级别的可见性以便轻松定位失败点和瓶颈
使用字节码增强技术,添加新功能而无需修改代码
安装探针不需要修改哪怕一行代码及trace server端部署简单,支持hdfs存储
具有简单的阀值触发报警功能
移植性比较强的,会比较讨人喜欢(相比cat)
插件化功能可扩展(https://github.com/naver/pinpoint/wiki/Pinpoint-Plugin-Developer-Guide)
0.2 Pinpoint 架构
[图片上传中。。。(1)]
1.0 环境准备
为了省事可以直接就到这里(https://get.k8scn.org/packages/others/pinpoint/)下载所需安装
目录默认我安装在:
[root@liujiangbu services]# pwd
/usr/local/services
[root@liujiangbu services]# ll
总用量 6492
drwxr-xr-x. 8 root root 4096 7月 6 11:46 hbase-1.1.11
drwxr-xr-x. 6 root root 4096 7月 6 14:06 maven3.5
-rw-r--r--. 1 root root 6621915 7月 6 14:55 pinpoint-agent-1.5.2.tar.gz
drwxr-xr-x. 4 root root 4096 7月 6 16:22 pp-agent
drwxr-xr-x. 3 root root 4096 7月 6 16:22 src
drwxr-xr-x. 9 root root 4096 7月 6 13:37 tomcat-collect
drwxr-xr-x. 9 root root 4096 7月 6 15:34 tomcat-ui
由于我是单机版,素有的都在一台机器上测试的
安装jdk<=1.7版本,不然报错
配置hbase:
[root@liujiangbu conf]# pwd
/usr/local/services/hbase-1.1.11/conf
[root@liujiangbu conf]# vim hbase-site.xml
<configuration> <property> <name>hbase.rootdir</name> <value>file:///data/hbase</value> # 这里我们指定Hbase本地来存储数据,生产环境将数据建议存入HDFS中。</property>
</configuration>
../bin/start-hbase.sh //启动
注意: 这里说明一下,我们是最简方式启动的Hbase,没有单独部署Hbase集群管理的zookeeper,而是直接使用Hbase自带的zk模块。另外,Hbase墙裂建议将数据存入HDFS里面,目前我们是存在Hbase本地的。
验证:
[root@liujiangbu conf]# jps
17655 HMaster
26409 Jps
初始化hbase表:
wget -c https://raw.githubusercontent.com/naver/pinpoint/master/hbase/scripts/hbase-create.hbase -P /usr/local/services/src
[root@liujiangbu hbase-1.1.11]# pwd
/usr/local/services/hbase-1.1.11
[root@liujiangbu hbase-1.1.11]# ./bin/hbase
hbase hbase-cleanup.sh hbase-common.sh hbase-config.sh hbase-daemon.sh hbase-daemons.sh hbase-jruby
[root@liujiangbu hbase-1.1.11]# ./bin/hbase /usr/local/services/src/hbase-create.hbase //初始化大概30秒
hbase(main):001:0> status 'detailed' # 我这里已经初始化pp相关表,所以数据展示比较多,这里是一部分
version 1.0.30 regionsInTransitionmaster coprocessors: []1 live servers c612:46781 1468494831781 requestsPerSecond=0.0, numberOfOnlineRegions=194, usedHeapMB=18, maxHeapMB=241, numberOfStores=322, numberOfStorefiles=3, storefileUncompressedSizeMB=0, storefileSizeMB=0, memstoreSizeMB=0, storefileIndexSizeMB=0, readRequestsCount=9272, writeRequestsCount=385, rootIndexSizeKB=2, totalStaticIndexSizeKB=1, totalStaticBloomSizeKB=0, totalCompactingKVs=0, currentCompactedKVs=0, compactionProgressPct=NaN, coprocessors=[MultiRowMutationEndpoint] "AgentEvent,,1468495003477.b13eb3203210fb9d94feb1a445e0ad1b." numberOfStores=1, numberOfStorefiles=0, storefileUncompressedSizeMB=0, storefileSizeMB=0, memstoreSizeMB=0, storefileIndexSizeMB=0, readRequestsCount=0, writeRequestsCount=0, rootIndexSizeKB=0, totalStaticIndexSizeKB=0, totalStaticBloomSizeKB=0, totalCompactingKVs=0, currentCompactedKVs=0, compactionProgressPct=NaN, completeSequenceId=-1, dataLocality=0.0 "AgentInfo,,1468494998919.fa9d36f7b52b95ee5216a1ec757ad690."...
验证hbase-web相关数据: ip:16010
[图片上传中。。。(2)]
部署和配置pp-collector和pp-web
这里我们还需要部署一个zookeeper。从pinpoint1.5.0开始,pp-web到pp-agent的request请求直接通过pp-collector来统筹管理,包括一些real-time级别的信息监测,而zookeeper在其中间协调三者之间的通信沟通。如果zookeeper部署在独立的一台设备,这里我就需要修改一下pp-colletor & pp-web的配置文件pinpoint-collector.properties,pinpoint-web.properties,不然会导致俩个模块启动失败。
[root@liujiangbu src]# rpm -ivh zookeeper-3.4.6-10.el6.x86_64.rpm
/etc/init.d/zookeeper start # 保证zookeeper的2181端口起来就可以了
pp-collector的配置
解压tomcat包,我这里重命名为:tomcat-collect,修改tomcat启动配置文件server.xml修改启动端口,.
[root@liujiangbu webapps]# pwd
/usr/local/services/tomcat-collect/webapps
将webapps下面的文件目录前部删掉,重新创建个ROOT目录
unzip pinpoint-collector-1.5.2.war -d /usr/local/services/tomcat-collect/webapps/ROOT
cd /usr/local/services/tomcat-collect/webapps/ROOT/WEB-INF/classes
[root@liujiangbu classes]# ll
总用量 44
-rw-rw-r--. 1 root root 15835 4月 7 2016 applicationContext-collector.xml
-rw-rw-r--. 1 root root 7485 4月 7 2016 applicationContext-hbase.xml
drwxrwxr-x. 3 root root 4096 4月 7 2016 com
-rw-rw-r--. 1 root root 758 7月 6 15:45 hbase.properties
-rw-rw-r--. 1 root root 1845 4月 7 2016 log4j.xml
-rw-rw-r--. 1 root root 1360 4月 7 2016 pinpoint-collector.properties
-rw-rw-r--. 1 root root 3292 4月 7 2016 servlet-context.xml
这里大概说一下: applicationContext-collector.xml, applicationContext-hbase.xml 这俩个配置文件时collector与agent和Hbase之间通信时需要设定的一些参数,在后续调优的时候需要用到,hbase.properties 主要是设定后端存储的连接配置,log4j.xml那就是log相关了。
vim hbase.propertieshbase.client.host=192.168.56.12 # 这里我们只修改这一项配置就好,能够让collector将汇报上来的数据存储到Hbasehbase.client.port=2181
这里tomcat我们就用默认的启动端口了,实际的生产环境可能需要根据实际情况修改tomcat侦听端口。OK,到此,pp-collector我们就基本上配置完成了。接下来我们开始配置pp-web,它与collector很类似。
pp-web配置:
解压tomcat重新命名为tomcat-ui,删除webapps下面的所有文件目录,创建ROOT目录,然后unzip pinpoint-web-1.5.2.war到tomcat-ui/webapps/ROOT/下,
[root@liujiangbu classes]# pwd
/usr/local/services/tomcat-ui/webapps/ROOT/WEB-INF/classes
[root@liujiangbu classes]# vim hbase.properties
hbase.client.host=10.40.6.69
hbase.client.port=2181
....
这里说明一下:
hbase.properties 配置我们pp-web从哪个数据源获取采集数据,这里我们只指定Hbase的zookeeper地址。
jdbc.properties pp-web连接自身Mysql数据库的连接认证配置。
sql目录 pp-web本身有些数据需要存放在MySQL数据库中,这里需要初始化一下表结构。
pinpoint-web.properties 这里pp-web集群的配置文件,如果你需要pp-web集群的话。
applicationContext-*.xml 这些文件在后续的调优工作中会用到。
log4j.xml 日志相关配置。
好了,pp-web终于算是配置完成了。
到这里,我们就可以启动pp-colletor和pp-web了,
安装启动文件:
pp-collector
vim /etc/init.d/pp-collect
#!/bin/bash
#
# chkconfig: 345 99 28
# description: Starts/Stops Apache Tomcat
#
# Tomcat 7 start/stop/status script
# Forked from: https://gist.github.com/valotas/1000094
# @author: Miglen Evlogiev <bash@miglen.com>
#
# Release updates:
# Updated method for gathering pid of the current proccess
# Added usage of CATALINA_BASE
# Added coloring and additional status
# Added check for existence of the tomcat user
#
#Location of JAVA_HOME (bin files)
#export JAVA_HOME=/usr/java/default/
#Add Java binary files to PATH
#export PATH=$JAVA_HOME/bin:$PATH
#CATALINA_HOME is the location of the bin files of Tomcat
export CATALINA_HOME=/usr/local/services/tomcat-collect
#CATALINA_BASE is the location of the configuration files of this instance of Tomcat
export CATALINA_BASE=/usr/local/services/tomcat-collect
#TOMCAT_USER is the default user of tomcat
export TOMCAT_USER=root
#TOMCAT_USAGE is the message if this script is called without any options
TOMCAT_USAGE="Usage: $0 {\e[00;32mstart\e[00m|\e[00;31mstop\e[00m|\e[00;32mstatus\e[00m|\e[00;31mrestart\e[00m}"
#SHUTDOWN_WAIT is wait time in seconds for java proccess to stop
SHUTDOWN_WAIT=3
tomcat_pid() {
echo `ps -fe | grep $CATALINA_BASE | grep -v grep | tr -s " "|cut -d" " -f2`
}
start() {
pid=$(tomcat_pid)
if [ -n "$pid" ]
then
echo -e "\e[00;31mTomcat is already running (pid: $pid)\e[00m"
else
# Start tomcat
echo -e "\e[00;32mStarting tomcat\e[00m"
#ulimit -n 100000
#umask 007
#/bin/su -p -s /bin/sh tomcat
if [ `user_exists $TOMCAT_USER` = "1" ]
then
su $TOMCAT_USER -c $CATALINA_HOME/bin/startup.sh
else
sh $CATALINA_HOME/bin/startup.sh
fi
status
fi
return 0
}
status(){
pid=$(tomcat_pid)
if [ -n "$pid" ]; then echo -e "\e[00;32mTomcat is running with pid: $pid\e[00m"
else echo -e "\e[00;31mTomcat is not running\e[00m"
fi
}
stop() {
pid=$(tomcat_pid)
if [ -n "$pid" ]
then
echo -e "\e[00;31mStoping Tomcat\e[00m"
#/bin/su -p -s /bin/sh tomcat
sh $CATALINA_HOME/bin/shutdown.sh
let kwait=$SHUTDOWN_WAIT
count=0;
until [ `ps -p $pid | grep -c $pid` = '0' ] || [ $count -gt $kwait ]
do
echo -n -e "\n\e[00;31mwaiting for processes to exit\e[00m";
sleep 1
let count=$count+1;
done
if [ $count -gt $kwait ]; then
echo -n -e "\n\e[00;31mkilling processes which didn't stop after $SHUTDOWN_WAIT seconds\e[00m"
kill -9 $pid
fi
else
echo -e "\e[00;31mTomcat is not running\e[00m"
fi
return 0
}
user_exists(){
if id -u $1 >/dev/null 2>&1; then
echo "1"
else
echo "0"
fi
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo -e $TOMCAT_USAGE
;;
esac
exit 0
pp-web启动文件;
vim /etc/init.d/pp-ui
[root@liujiangbu classes]# cat /etc/init.d/pp-ui
#!/bin/bash
#
# chkconfig: 345 99 28
# description: Starts/Stops Apache Tomcat
#
# Tomcat 7 start/stop/status script
# Forked from: https://gist.github.com/valotas/1000094
# @author: Miglen Evlogiev <bash@miglen.com>
#
# Release updates:
# Updated method for gathering pid of the current proccess
# Added usage of CATALINA_BASE
# Added coloring and additional status
# Added check for existence of the tomcat user
#
#Location of JAVA_HOME (bin files)
#export JAVA_HOME=/usr/java/default/
#Add Java binary files to PATH
#export PATH=$JAVA_HOME/bin:$PATH
#CATALINA_HOME is the location of the bin files of Tomcat
export CATALINA_HOME=/usr/local/services/tomcat-ui
#CATALINA_BASE is the location of the configuration files of this instance of Tomcat
export CATALINA_BASE=/usr/local/services/tomcat-ui
#TOMCAT_USER is the default user of tomcat
export TOMCAT_USER=root
#TOMCAT_USAGE is the message if this script is called without any options
TOMCAT_USAGE="Usage: $0 {\e[00;32mstart\e[00m|\e[00;31mstop\e[00m|\e[00;32mstatus\e[00m|\e[00;31mrestart\e[00m}"
#SHUTDOWN_WAIT is wait time in seconds for java proccess to stop
SHUTDOWN_WAIT=3
tomcat_pid() {
echo `ps -fe | grep $CATALINA_BASE | grep -v grep | tr -s " "|cut -d" " -f2`
}
start() {
pid=$(tomcat_pid)
if [ -n "$pid" ]
then
echo -e "\e[00;31mTomcat is already running (pid: $pid)\e[00m"
else
# Start tomcat
echo -e "\e[00;32mStarting tomcat\e[00m"
#ulimit -n 100000
#umask 007
#/bin/su -p -s /bin/sh tomcat
if [ `user_exists $TOMCAT_USER` = "1" ]
then
su $TOMCAT_USER -c $CATALINA_HOME/bin/startup.sh
else
sh $CATALINA_HOME/bin/startup.sh
fi
status
fi
return 0
}
status(){
pid=$(tomcat_pid)
if [ -n "$pid" ]; then echo -e "\e[00;32mTomcat is running with pid: $pid\e[00m"
else echo -e "\e[00;31mTomcat is not running\e[00m"
fi
}
stop() {
pid=$(tomcat_pid)
if [ -n "$pid" ]
then
echo -e "\e[00;31mStoping Tomcat\e[00m"
#/bin/su -p -s /bin/sh tomcat
sh $CATALINA_HOME/bin/shutdown.sh
let kwait=$SHUTDOWN_WAIT
count=0;
until [ `ps -p $pid | grep -c $pid` = '0' ] || [ $count -gt $kwait ]
do
echo -n -e "\n\e[00;31mwaiting for processes to exit\e[00m";
sleep 1
let count=$count+1;
done
if [ $count -gt $kwait ]; then
echo -n -e "\n\e[00;31mkilling processes which didn't stop after $SHUTDOWN_WAIT seconds\e[00m"
kill -9 $pid
fi
else
echo -e "\e[00;31mTomcat is not running\e[00m"
fi
return 0
}
user_exists(){
if id -u $1 >/dev/null 2>&1; then
echo "1"
else
echo "0"
fi
}
case $1 in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
status)
status
;;
*)
echo -e $TOMCAT_USAGE
;;
esac
exit 0
```
添加执行权限,并启动服务。
我们这个时候可以部署一个pp-agent试玩一下了,其实也就是很多APM厂商传说中的探针。这里我的探针是部署在自己的应用下面的,就只贴一下跑在tomcat下的探针配置信息了。顺带说明一下部署上的注意点。
将agent解压放到和要监控的应用的tomcat在同一级目录,然后配置agent里的配置文件;
[root@liujiangbu pinpoint-agent-1.5.2]# pwd
[root@liujiangbu pinpoint-agent-1.5.2]# vim pinpoint.config
/usr/local/services/pp-agent/pinpoint-agent-1.5.2
profiler.collector.ip=10.40.6.69
placeHolder support "${key}"
profiler.collector.span.ip=${profiler.collector.ip}
profiler.collector.span.port=9996
placeHolder support "${key}"
profiler.collector.stat.ip=${profiler.collector.ip}
profiler.collector.stat.port=9995
placeHolder support "${key}"
profiler.collector.tcp.ip=${profiler.collector.ip}
profiler.collector.tcp.port=9994
。。。
配置被监控的tomcat服务的catalina.sh:
[root@liujiangbu pinpoint-agent-1.5.2]# vim ../apache-tomcat-7.0.79/bin/catalina.sh
加入如下段,CATALINA_OPTS 放在被创建前:
AGENT_VERSION="1.5.2"
AGENT_ID="pp201606454542"
APPLICATION_NAME="app-10.40.6.69"
AGENT_PATH="/usr/local/services/pp-agent/pinpoint-agent-1.5.2"
CATALINA_OPTS="$CATALINA_OPTS -javaagent:$AGENT_PATH/pinpoint-bootstrap-$AGENT_VERSION.jar"
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.agentId=$AGENT_ID"
CATALINA_OPTS="$CATALINA_OPTS -Dpinpoint.applicationName=$APPLICATION_NAME"
然后重启被采集端的应用,使指针生效。
http://10.40.6.69:8081/#/main
[图片上传中。。。(3)]
在要被监控的tomcat服务启动完成后,会出现下面的界面pp-web
[图片上传中。。。(4)]
因为我只访问了一次 所以数字是1
问题排查
看日志,看日志,看日志。
部署成功调试完成最好把agent端log级别调高一些,少打印日志。讲真,不然在你实时查看日志定位程序问题时,你会发现打印一堆了无效信息,绝对懵B。