JBOSS配置排错

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JBOSS配置排错相关的知识,希望对你有一定的参考价值。

jboss提供了二种运行模式:standalone(独立运行模式)、domain(域模式),日常开发中,使用standalone模式足已;但生产部署时,一个app,往往是部署在jboss集群环境中的,如果所有jboss server均采用standalone模式,会给运维带来极大的工作量,需要每台jboss server上逐一部署/更新,显然不适合。

domain模式正是为了解决这一问题,该模式下,所有jbossserver可以划分成不同的group(注:这里的jbossserver并不一定要对应某台物理机或虚拟机,一个os上,可以同时run多个jboss server实例,所以本文中的jboss server均指某个运行中的jboss server instance),每个group中可以包含多个jboss server,所有这些jboss server中,可以指定一台做为域控制器(domaincontroller),俗称master server,其它jbossserver均为Home Controller(俗称slaveserver)。

master上可以控制所有jboss server,并监控其运行情况,部署应用时,一个war包,只需要部署到group上,该group中的所有jboss server即会同步自动部署。

 

 

操作系统:CentOS 7
JDK版本:1.8
JBoss版本:JBoss EAP 6.2
jboss各版本下载地址:https://teddysun.com/260.html

下载jboss-eap-6.2.0.zip

下载jdk包:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

下载jdk-8u131-linux-x64.rpm

 

 

 

 

Centos7无法使用ssh登陆及解决方案

yum instatll net-tools -y    ----安装netstat工具

systemctl start sshd ---启动sshd服务

netstat -nalt

 

 

 

JBoss运行需要依赖于JDK

安装JDK

检查系统是否自带jdk,如果系统自带jdk,需要先将它卸载掉.然后安装我们需要的jdk.

检查是否安装jdk命令:

rpm -qa | grep jdk

删除自带jdk的命令:

rpm -e --nodeps java-1.6.0-openjdk-1.6.0.0-1.41.1.10.4.el6.x86_64

或者用 yum -y remove 命令删除:

yum -y remove java-1.6.0-openjdk-1.6.0.0-1.41.1.10.4.el6.x86_64

 

执行完后,检查是否删除成功:

[[email protected] vmware-tools-distrib]# rpm-qa | grep jdk

[[email protected] vmware-tools-distrib]# java-version

-bash: java: command not found

 

 

将安装包jdk-8u131-linux-x64上传至服务器 /home/oldboy/tools目录下

 

 

chmod -R 777/home/oldboy/tools/jdk-8u131-linux-x64.rpm

rpm -ivh/home/oldboy/tools/jdk-8u131-linux-x64.rpm

该命令将jdk默认安装到了/usr/Java目录下

mv /usr/java/jdk1.8.0_131  /usr/local/jdk1.8

 

 

配置环境变量

vi /etc/profile

在文件最后配置如下变量

JAVA_HOME=/usr/local/jdk1.8

PATH=$JAVA_HOME/bin:$PATH

CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export JAVA_HOME

export PATH

export CLASSPATH

 

然后输入source /etc/profile命令,使配置文件生效。

 

出现如下版本信息,则说明一切安装配置成功。

[[email protected] vmware-tools-distrib]# java-version

java version "1.8.0_131"

Java(TM) SE Runtime Environment (build1.8.0_131-b11)

Java HotSpot(TM) 64-Bit Server VM (build25.131-b11, mixed mode)

 

 

 

 

 

JBoss安装

将JBoss安装文件(先解压成目录)上传到服务器,目录:/usr/local/software

mkdir -pv /usr/local/software

不需要安装,解压即可使用,和Tomcat一样,下面将JBoss目录移动到usr/local 下,该目录为所有软件安装目录。

mv /usr/local/software/jboss-eap-6.2/usr/local/jboss6.2

vi /etc/profile

增加

JBOSS_HOME=/usr/local/jboss6.2

 

启动JBoss服务

启动之前最好现获取jboss文件的权限:

chmod -R 777 /usr/local/jboss6.2

 

cd /usr/local/jboss6.2/bin

输入命令 ./standalone.sh 以a single server instance的模式启动Jboss

能看到类似22:37:31,306INFO  [org.jboss.as] (Controller BootThread) JBAS015874: JBoss EAP 6.2.0.GA (AS 7.3.0.Final-redhat-14) started in10490ms - Started 129 of 186 services (56 services are passive or on-demand),说明启动成功。

/usr/local/jboss6.2/standalone/configuration目录中有***.xml,是用于jboss启动类型。比如:./standalone.sh--server-config=standalone-full.xml,

而 ./standalone.sh 相当于./standalone.sh --server-config=standalone.xml

cd /usr/local/jboss6.2/bin

输入命令 ./domain.sh 以allowing control andmanagement of multiple instances的domain模式启动JBoss

测试:

master: 192.168.1.58;

slave: 192.168.1.181;

配置master(master: 192.168.1.58):

192.168.1.58上添加用户:

cd /usr/local/jboss6.2/bin

./add-user.sh

创建的用户名为slave,这样slave才可以登陆到master。密码:@we4%7Jt,经过Base64加密后为:QHdlNCU3SnQ=

修改管理接口地址:

vi /usr/local/jboss6.2/domain/configuration/host.xml

       <interface name="management">

           <inet-address value="${jboss.bind.address.management:192.168.1.58}"/>

       </interface>

配置slave(slave: 192.168.1.181)

vi /usr/local/jboss6.2/domain/configuration/host.xml

设置名字:

<host name="slave"xmlns="urn:jboss:domain:1.5">

设置密码:

secret value中配置的值是master上配置的slave用户的密码的base64。

 <secret value=" QHdlNCU3SnQ="/>

配置master地址:

   <domain-controller>

      <remote host="${jboss.domain.master.address:192.168.1.58}"port="${jboss.domain.master.port:9999}"security-realm="ManagementRealm"/>

   </domain-controller>

配置本地接口地址:

将127.0.0.1都替换成0.0.0.0或实际的IP地址:

   <interfaces>

       <interface name="management">

           <inet-addressvalue="${jboss.bind.address.management:0.0.0.0}"/>

       </interface>

       <interface name="public">

          <inet-address value="${jboss.bind.address:0.0.0.0}"/>

       </interface>

       <interface name="unsecure">

           <!-- Used for IIOP sockets in the standard configuration.

                 To secure JacORB you need tosetup SSL -->

           <inet-address value="${jboss.bind.address.unsecure:0.0.0.0}"/>

       </interface>

</interfaces>

配置端口:

       <management-interfaces>

           <native-interface security-realm="ManagementRealm">

                <socketinterface="management"port="${jboss.management.native.port:9099}"/>

           </native-interface>

       </management-interfaces>

这里的9999端口,改成其它不使用的端口(比如:9099),否则slave server上的9999端口,与master server上的管理端口冲突,最后启动时,会报错

配置servers:

group必须是master主机(master: 192.168.1.58)上host.xml中配置的group。

<servers>

       <server name="server-one"group="main-server-group"/>

       <server name="server-two"group="main-server-group">

           <!-- server-two avoids port conflicts by incrementing the ports in

                 the default socket-groupdeclared in the server-group -->

           <socket-bindings port-offset="150"/>

       </server>

   </servers>

 

 

启动

master(master: 192.168.1.58):

cd /usr/local/jboss6.2/bin

./domain.sh

 

slave(slave: 192.168.1.181):

cd /usr/local/jboss6.2/bin

./domain.sh

 

局域网访问管理接口:(用户名:为slave密码:@we4%7Jt)

http://192.168.1.58:9990

 

Deploying an Application in Standalone Mode

将应用程序test.war(是随便找的测试文件)放到 /usr/local/jboss6.2/standalone/deployments

The standalone/deployments directory in the JBoss Application Server

distribution is the location end users can place their deploymentcontent

(e.g. war, ear, jar, sar files) to have it automatically deployed intothe server

runtime.

 

cd /usr/local/jboss6.2/bin

./standalone.sh

可以看到JBAS018559: Deployed"test.war" (runtime-name : "test.war")就是说明已经运用了,/usr/local/jboss6.2/standalone/deployments下删除test.war可以看到JBAS018558: Undeployed"test.war" (runtime-name: "test.war")

 

 

Deploying an Application in Domain Mode

登陆 http://192.168.1.58:9990

Manage Deployments

技术分享

Add


技术分享

技术分享

技术分享

Assign


技术分享

 

 

Gathering Java Virtual Machine Diagnostics(GC日志分析,用于排错)

standalone模式

vi /usr/local/jboss6.2/bin/standalone.conf

#Enable garbage collection logging

JAVA_OPTS="$JAVA_OPTS -verbose:gc-XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:gc.log"

#Create a java heap dump on outofmerryerror

JAVA_OPTS="$JAVA_OPTS-XX:-HeapDumpOnOutOfMemoryError"

 

/usr/local/jboss6.2/bin/standalone.sh

生成文件/root/gc.log,可以用来查看。

domain模式

vi /usr/local/jboss6.2/domain/configuration/host.xml

   <jvms>

          <jvm name="default">

           <heap size="64m" max-size="256m"/>

           <permgen size="256m" max-size="256m"/>

              <jvm-options>

                  <optionvalue="-server"/>

                <optionvalue="-verbose:gc -XX:+PrintGCTimeStamps -XX:+PrintGCDetails-Xloggc:gc.log"/>

                <optionvalue="-XX:-HeapDumpOnOutOfMemoryError"/>

              </jvm-options>

        </jvm>

       </jvms>

 

/usr/local/jboss6.2/bin/domain.sh

生成文件/root/gc.log,可以用来查看。

ps -ef |grep java   

可以看到修改已经启用



如何阅读和理解GC日志

GC日志开头的“[GC”和“[Full GC”说明了这次垃圾收集的停顿类型,而不是用来区分新生代GC还是老年代GC的。如果有“Full”,说明这次GC是发生了Stop-The-World的,例如下面这段新生代收集器ParNew的日志也会出现“[FullGC”(这一般是因为出现了分配担保失败之类的问题,所以才导致STW)。如果是调用System.gc()方法所触发的收集,那么在这里将显示“[Full GC (System)”。

[Full GC 283.736: [ParNew:261599K->261599K(261952K), 0.0000288 secs] 

接下来的“[DefNew”、“[Tenured”、“[Perm”表示GC发生的区域,这里显示的区域名称与使用的GC收集器是密切相关的,例如上面样例所使用的Serial收集器中的新生代名为“Default New Generation”,所以显示的是“[DefNew”。如果是ParNew收集器,新生代名称就会变为“[ParNew”,意为“ParallelNew Generation”。如果采用Parallel Scavenge收集器,那它配套的新生代称为“PSYoungGen”,老年代和永久代同理,名称也是由收集器决定的。

后面方括号内部的“3324K->152K(3712K)”含义是“GC前该内存区域已使用容量-> GC后该内存区域已使用容量 (该内存区域总容量)”。而在方括号之外的“3324K->152K(11904K)”表示“GC前Java堆已使用容量 -> GC后Java堆已使用容量 (Java堆总容量)”。

再往后,“0.0025925 secs”表示该内存区域GC所占用的时间,单位是秒。有的收集器会给出更具体的时间数据,如“[Times: user=0.01 sys=0.00, real=0.02 secs]”,这里面的user、sys和real与Linux的time命令所输出的时间含义一致,分别代表用户态消耗的CPU时间、内核态消耗的CPU事件和操作从开始到结束所经过的墙钟时间(Wall Clock Time)。CPU时间与墙钟时间的区别是,墙钟时间包括各种非运算的等待耗时,例如等待磁盘I/O、等待线程阻塞,而CPU时间不包括这些耗时,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以读者看到user或sys时间超过real时间是完全正常的。

 

GCViewer(图形化工具)

 

 

 

How and When to Capture a Java Thread Dump

vi ~/.bashrc                                                                               

# user specific aliases and functions

export PATH=$PATH:/usr/local/jdk1.8/bin

 

先运行./standalone.sh,才能得到jboss-modules.jar

cd /usr/local/jboss6.2/bin

./standalone.sh

[[email protected] ~]# jps

3013 Jps

2919 jboss-modules.jar

[[email protected] ~]# jstack -l 2919 >jstack.out

[[email protected] ~]# less jstack.out          (查看线程状态)

 

samurai.jar可实现实时监控TheadDump和GC图表显示.(但是需要图形化界面)

官方网站及说明文档:http://yusuke.homeip.net/samurai/en/index.html

下载:http://yusuke.homeip.net/samurai/en/samurai.jar

运行: java -jar ./samurai.jar


 

 

http://www.eclipse.org/mat/

The Eclipse MemoryAnalyzer is a fast and feature-rich Java heap analyzer that helps you findmemory leaks and reduce memory consumption.

 

 

 

找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息

vi ~/.bashrc                                                                               

# user specific aliases and functions

export PATH=$PATH:/usr/local/jdk1.8/bin

jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。

第一步先找出Java进程ID,服务器上的Java应用名称为mrf-center:

[email protected]:/# ps -ef | grep mrf-center |grep -v grep

root    21711     1  1 14:47 pts/3    00:02:10 java -jar mrf-center.jar

得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,可以使用

1)ps -Lfp pid

2)ps -mp pid -oTHREAD, tid, time

3)top -Hp pid

用第三个,输出如下:      

技术分享


TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用

printf "%x\n" 21742

得到21742的十六进制值为54ee,下面会用到。

OK,下一步终于轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep,如下:

[email protected]:/# jstack 21711 | grep 54ee

"PollIntervalRetrySchedulerThread"prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait()

可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),我找了下我的代码,定位到下面的代码:

// Idle wait

getLog().info("Thread [" +getName() + "] is idle waiting...");

schedulerThreadState =PollTaskSchedulerThreadState.IdleWaiting;

long now = System.currentTimeMillis();

long waitTime = now + getIdleWaitTime();

long timeUntilContinue = waitTime - now;

synchronized(sigLock) {

  try{

   if(!halted.get()) {

     sigLock.wait(timeUntilContinue);

    }

  }

 catch (InterruptedException ignore) {

  }

}

它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。

 

 

 

局域网访问

直接输入http://xxx.xx.xx.xxx:8080是不能访问的,如果想让局域网内的其他机器访问,需要做如下配置:

关闭服务器的防火墙

systemctl stop firewall

Failed to stop firewall.service: Unitfirewall.service not loaded.

centos从7开始默认用的是firewall,这个是基于iptables的,虽然有iptables的核心,但是iptables的服务是没安装的。所以你只要停止firewalld服务即可:sudo systemctl stopfirewalld.service && sudo systemctl disable firewalld.service

 

必须要修改JBoss配置文件,方法如下:

vi/usr/local/jboss6.2/standalone/configuration/standalone.xml

找到

<interface name="public">

   <inet-address value="${jboss.bind.address:127.0.0.1}"/>

</interface>

将127.0.0.1修改为JBoss所在机器的IP地址或者修改为0.0.0.0即可,保存退出即可。

 

访问测试:

在浏览器地址栏中输入:http://192.168.1.58:8080,出现欢迎界面,证明启动成功!

技术分享

 

 

以后台运行方式启动

直接以./standalone.sh方式开启JBoss会有个缺点,当命令窗口关闭后,JBoss服务也会down掉。这种方式在远程服务器操作JBoss时,非常蛋疼。关掉远程终端窗口,JBoss也会down掉。

所以我们需要让JBoss开启后在后台运行:进入到bin目录下,输入nohup ./standalone.sh 命令。这样服务就会在后台运行,即使关闭命令窗口,服务依然运行。

查看Jboss启动日志信息输入:tail-f nohup.out 即可。

停止服务

以直接启动方式启动JBoss,关闭时可以在启动终端窗口按键 CTRL + C,即可完全停止JBoss服务

如果使用后台运行的方式,关闭服务器就比较麻烦,找了半天才找到关闭Jboss EAP6.2 的方法:

进入到JBoss的bin目录下,输入:

[[email protected] bin]# ./jboss-cli.sh -c  :shutdown

{"outcome" =>"success"}

或者暴力解决:kill -9 PID



以上是关于JBOSS配置排错的主要内容,如果未能解决你的问题,请参考以下文章

虚拟主机Xshell连接排错

linux网络配置及排错的一般流程

排错积累

报错解决与排错思路

Cisco 的基本配置实例之六----常排错命令

精品openstack部署排错一点通