应用场景:在linux系统上进行项目开发,在部署java项目时,常用方法就是写一个shell脚本,但当服务器重启了,经常会忘了启动shell脚本了。所以我们需要把自己的应用变成linux的服务,当服务器启动的时候就自行启动自己的应用。使用JSVC就能够实现上面的功能。

在linux上以服务的方式启动java程序步骤:

注:其实bin目录下并没有jsvc.tar.gz这个文件,需要自己下载。解压完之后呢,执行sh support/buildconf.sh 命令,提示autoconf:not found,如下图所示:

若不存在jsvc.tar.gz包,还可以尝试如下方法:

1、在/home/shq/apache-tomcat-6.0.28/bin中有commons-daemon-native.tar.gz 压缩包

2、解压commons-daemon-native.tar.gz

tar -zxvf commons-daemon-native.tar.gz

3、解压完成,出现commons-daemon-1.0.2-native-src文件夹(目录)

1、  进入commons-daemon-1.0.2-native-src 下的unix目录

ls

cd commons-daemon-1.0.2-native-src/unix

2、  发现configure 配置文件,执行如下修改属性的命令

sudo chmod 777 configure

4、执行configure配置文件,运行效果如下图所示:

上面这个这个图是因为没有加后面的参数sudo ./configure --with -java=/usr/lib/java,添加后面的参数后,效果图如下图所示:

其实真正的命令应该是sudo ./configure --with -java=/usr/lib/java/jdk1.6.0_45也就是说后面的参数应该是jdk的所在目录,因为里面有相应的编译工具。结果如下图所示:

make时若出现以下错误,也可以通过上面的方法解决:

5、编译

[root@localhost ~]# sudo make

运行结果如下图所示:

#若报错

[root@localhost ~]# make clean

[root@localhost ~]# make    #重新编译成功

6、编译完成后出现jsvc文件夹,复制jsvc到/usr/lib/tomcat/apache-tomcat-6.0.28/bin目录下面

[root@localhost ~]# cp jsvc /usr/lib/tomcat/apache-tomcat-6.0.28/bin

7、在/etc/init.d/(注意不是init文件夹)目录下编写tomcat6启动服务配置文件。

[root@localhost ~]#cd /etc/init.d/

[root@localhost ~]# vi tomcat6.0.28

#!/bin/sh

# tomcat: Start/Stop/Restart tomcat

#

# chkconfig: 2345 85 15

# description: Apache tomcat6

# Small shell script to show how to start/stop Tomcat using jsvc

JAVA_HOME=/usr/lib/java/jdk1.6.0_45   #根据自己的实际jdk位置来修改

CATALINA_HOME=/usr/lib/tomcat//apache-tomcat-6.0.28  #根据自己实际tomcat位置来修改

DAEMON_HOME=$CATALINA_HOME/bin

# I did not use the user.

TOMCAT_USER=tomcat

# for multi instances adapt those lines.

TMP_DIR=$CATALINA_HOME/tmp

PID_FILE=$DAEMON_HOME/jsvc.pid

CATALINA_BASE=$CATALINA_HOME

. /etc/rc.d/init.d/functions

CATALINA_OPTS=

CLASSPATH=\

$JAVA_HOME/lib/tools.jar:\

$CATALINA_HOME/bin/commons-daemon.jar:\

$CATALINA_HOME/bin/bootstrap.jar

start() {

echo -n $"Starting Tomcat6.0.28: "

# If you want to specify a user to run Tomcat.

#increase the 'user $ TOMCAT_USER \' to the parameter list.

$DAEMON_HOME/jsvc \

-home $JAVA_HOME \

-Dcatalina.home=$CATALINA_HOME \

-Dcatalina.base=$CATALINA_BASE \

-Djava.io.tmpdir=$TMP_DIR \

-wait 10 \

-pidfile $PID_FILE \

-outfile $CATALINA_HOME/logs/catalina.out \

-errfile '&1' \

$CATALINA_OPTS \

-cp $CLASSPATH \

org.apache.catalina.startup.Bootstrap

echo "*****************************[ok]"

}

stop() {

echo -n $"Stopping Tomcat6: "

#

$DAEMON_HOME/jsvc \

-stop \

-pidfile $PID_FILE \

org.apache.catalina.startup.Bootstrap

echo "*****************************[ok]"

}

status() {

ps ax --width=1000 | grep "[o]rg.apache.catalina.startup.Bootstrap" | awk '{printf $1 " "}' | wc | awk '{print $2}' >/tmp/tomcat_process_count.txt

read line < /tmp/tomcat_process_count.txt

if [ $line -gt 0 ]; then

echo -n "tomcat6 ( pid "

ps ax --width=1000 | grep "[o]rg.apache.catalina.startup.Bootstrap" | awk '{printf $1 " "}'

echo ") is running "

else

echo "Tomcat6.0.28 is stopped"

fi

}

case "$1" in

start)

# Start Tomcat

start

exit $?

;;

stop)

# Stop Tomcat

stop

exit $?

;;

restart)

# Restart Tomcat

stop

sleep 3

start

exit $?

;;

status)

status

exit $?

;;

*)

echo "Usage: tomcat6 {start|stop|restart|status}"

exit 1;;

esac

#####

####

8、录入完成,按Esc键。输入: wq(vi下输入:x)保存退出并赋予/etc/init.d/tomcat6文件可执行权限

[root@localhost~]# chmod +x /etc/init.d/tomcat6.0.28

------------------添加服务-----------------------------------------

9、[root@localhost~] #chkconfig --add tomcat6.0.28           ##添加tomcat服务

若提示chkconfig命令未找到,则需要执行sudo apt-get install chkconfig

参考网址:http://blog.sina.com.cn/s/blog_66fb0c830100xm5y.html

PS:chkconfig是redhat公司遵循gpl规则所开发的程序在ubuntu上默认是不支持chkconfig命令的,但可以自己安装。Ubuntu下是使用sysv-rc-conf来代替chkconfig。

sudo apt-get install sysv-rc-conf

安装完成后,直接运行sudo sysv-rc-conf命令即可打开该管理软件,如下图所示:

操作界面十分简洁,你可以用鼠标点击,也可以用键盘方向键定位,用空格键选择, “X”表示开启该服务。 用Ctrl+N翻下一页,用Ctrl+P翻上一页,用Q退出。

Ubuntu 的系统运行级别:

0 系统停机状态

1 单用户或系统维护状态

2~5 多用户状态

6 重新启动

Ubuntu下可以直接加入启动程序,例如把 /etc/init/tomcat6.0.28 加入到系统自动 启动列表中:

#sudo sysv-rc-conf tomcat6.0.28 on

想关闭tomcat6.0.28的开机自动启动,只需#sudo mv /etc/init.d/tomcat6.0.28(注意将配置脚本备份,否则删除后就跪了。)就可以了。

参考网址:http://www.linuxidc.com/Linux/2012-10/73123p2.htm

10、[root@localhost~] #chkconfig –list |grep tomcat6.0.28    ##查看tomcat服务是否被添加

--------------------启动服务---------------------------------------------

11、[root@localhost~] # service tomcat6.0.28  start            ##启动tomcat服务

执行以上命令后,出现如下错误提示:

按照网上的说法,添加软连接ln -s /lib/lsb/init-functions /etc/rc.d/init.d/functions,继续提示错误,原因很明显:软连接的文件夹压根就不存在!

继续搜索,发现以下说法:

在Linux中,/etc/init.d 和 /etc/rc.d/init.d这两个目录,都是用来放服务脚本的,当Linux启动时,会寻找这些目录中的服务脚本,并根据脚本的run level确定不同的启动级别。

在制作服务脚本的过程中,使用了Linux的两个版本,CentOS和Ubuntu,需要在两个版本中都可以开机启动服务。但Ubuntu没有 /etc/rc.d/init.d这个目录,所以,为了保持同一种服务在CentOS和Ubuntu使用的统一性,将服务脚本(注:服务脚本在两个不同版本中是不同的)都放在 /etc/init.d 目录下,最终达到的效果是相同的。

需要说明的是:在CentOS和Ubuntu两个版本中,除了服务脚本放置的目录是相同的,服务脚本的编写及服务配置都是不同的。比如CentOS使用Chkconfig进行配置,而Ubuntu使用sysv-rc-conf进行配置。

查看/etc/rc2.d/里面的apache和mysql启动脚本,通常都是两个阿拉伯数字后再接一个英文字母,再加脚本名称,例如S20tomcat6.0.28。英文字母是S的都是会自动启动的,K则相反。所以只要找到apache和mysql的启动脚本,把S改成K就可以了。

以下命令实现开机启动或不启动某服务(真的太像chkconfig了)

sudo sysv-rc-conf 服务名 on(off)

12、[root@localhost~] # sudo sysv-rc-conf  off            ##停止tomcat服务

13、[root@localhost~] #sudo sysv-rc-conf --list tomcat6.0.28  ##查看tomcat服务启动状态

命令执行效果如下:

Linux 系统主要启动步骤:

1. 读取MBR 的信息,启动Boot Manager Windows使用NTLDR作为Boot Manager,如果您的系统中安装多个版本的 Windows,您就需要在NTLDR 中选择您要进入的系统。Linux 通常使用功能强大,配置灵活的GRUB作为Boot Manager。

2. 加载系统内核,启动init 进程.init 进程是Linux 的根进程,所有的系统进程都是它的子进程。

3. init 进程读取 /etc/inittab 文件中的信息,并进入预设的运行级别,按顺序运行该运行级别对应文件夹下的脚本。脚本通常以 start 参数启动,并指向一个系统中的程序。

通常情况下, /etc/rcS.d/ 目录下的启动脚本首先被执行,然后是/etc/rcN.d/ 目录。例如您设定的运行级别为3,那么它对应的启动目录为/etc/rc3.d/ 。

4. 根据 /etc/rcS.d/ 文件夹中对应的脚本启动Xwindow 服务器xorgXwindow 为Linux 下的图形用户界面系统。

5. 启动登录管理器,等待用户登录Ubuntu 系统默认使用GDM 作为登录管理器,您在登录管理器界面中输入用户名和密码后,便可以登录系统。(您可以在 /etc/rc3.d/文件夹中找到一个名为S13gdm 的链接)

2.编写服务启动类

package com.sohu.jsvc.test;

public class TestJsvc {

public static void main(String args[]) {

System.out.println("execute main method!");

}

public void init() throws Exception {

System.out.println("execute init method!");

}

public void init(String[] args) throws Exception{

System.out.println("execute init(args) method");

}

public void start() throws Exception {

System.out.println("execute start method!");

}

public void stop() throws Exception {

System.out.println("execute stop method!");

}

public void destroy() throws Exception{

System.out.println("execute destroy method!");

}

}

main方法可以去掉,但是init(String[] args),start(),stop(),destroy()方法不能少,服务在启动时会先调用init(String[] args)方法,然后调用start()方法,在服务停止时会首先调用stop()方法,然后调用destroy() 方法.

3.把这个类打包成webservice_engine.jar放到/usr/lib目录下

4.编写启动服务的脚本 webservice_engineJSVC

#!/bin/sh

# myjsvc This shell script takes care of starting and stopping

#

# chkconfig: - 60 50

# description: tlstat stat is a stat data daemon.

# processname: webservice_engineJSVC

# Source function library.

. /etc/rc.d/init.d/functions

RETVAL=0

prog="webservice_engineJSVC"

# jdk的安装目录

JAVA_HOME=/usr/lib/java/jdk1.6.0_45

#应用程序的目录

MYJSVC_HOME=/test

#jsvc所在的目录

DAEMON_HOME=/usr/lib/tomcat//apache-tomcat-6.0.28/bin

#用户

MYJSVC_USER=root

# for multi instances adapt those lines.

TMP_DIR=/var/tmp

PID_FILE=/var/run/tlstat.pid

#程序运行是所需的jar包,commons-daemon.jar是不能少的

CLASSPATH=/usr/lib/webservice_engine.jar:/usr/lib/tomcat/apache-tomcat-6.0.28/bin/commons-daemon.jar:

case "$1" in

start)

#

# Start TlStat Data Serivce

#

$DAEMON_HOME/jsvc -user $MYJSVC_USER -home $JAVA_HOME -Djava.io.tmpdir=$TMP_DIR -wait 10 -pidfile $PID_FILE #控制台的输出会写到tlstat.out文件里

-outfile $MYJSVC_HOME/log/myjsvc.out -errfile '&1' -cp $CLASSPATH #服务启动类

test.main.WebServiceEngine

#

# To get a verbose JVM

#-verbose # To get a debug of jsvc.

#-debug exit $?

;;

stop)

#

# Stop TlStat Data Serivce

#

$DAEMON_HOME/jsvc -stop -pidfile $PID_FILE test.main.WebServiceEngine

exit $?

;;

*)

echo "Usage Webjsvc start/stop"

exit 1;;

esac

5. 把myjsvc文件拷贝到/etc/init.d/目录下

6. #chmod -c +x /etc/init.d

7. 添加,启动服务

#sudo sysv-rc-conf webservice_engineJSVC on

你可以从/test/log/myjsvc.out文件里看到如下信息:

execute init(args) method

execute start method

#service myjsvc stop

你会发现/test/log/myjsvc.out文件里会增加如下信息

execute stop method

execute destroy method

并且在系统重启时会自动启动myjsvc服务

好了,一个简单的 liunx服务就写好了,你可以在TestJsvc的init(),start(),stop(),destroy()方法里添加你的业务,做你想做的事。

下面讲解jsvc 启动Java 在Linux下的实现原理。

jsvc 是在apache的daemon项目下的开源项目,主要功能可以使一些运行在普通用户下的java进程获取一些root权限下的权利,比如端口在1024下等。

如何运行?

在自己的java代码中,实现start, init , stop,destroy的方法,将自己的编译打成jar文件,  通过调用jsvc 来启动

./jsvc -java-home  /usr/java/jdk1.7.0_09/ -user nobody  -pidfile /opt/apache-tomcat_1/logs/catalina-daemon1.pid -wait 10 -errfile "/tmp/error" -outfile "/tmp/output" -debug -classpath /root/test.jar:/root/commons-daemon.jar test

几个注意点:

commons_daemon.jar文件是用于调用你的class文件,

关于-java-home, 在这里有一个bug(https://issues.apache.org/jira/browse/DAEMON-268),哪怕指定,也会指定为默认的/usr/java

实现原理?

jsvc 是一个源码是c的程序,通过fork出子进程去启动java,而进程成为控制进程,可以实现监视java子进程的目地。

改变启动虚拟机的进程用户id和用户组

通过调用setgid,setuid来改变当前进程的用户id和组,这里要注意的是当改变用户id和组的时候,当前进程会改变进程的capability, 所以需要reset 进程的capability。

查看进程的capability可以通过内核调用 __NR_capget / __NR_capset 的方式

static int get_legacy_caps(){

struct __user_cap_header_struct caphead;

struct __user_cap_data_struct  cap;

memset(&caphead, 0, sizeof caphead);

caphead.version = LEGACY_CAP_VERSION;

if (syscall(__NR_capget, &caphead, &cap) < 0)

log_error("capget failed: %m");

log_debug("PID is %d print the cap  0x%x, 0x%x, 0x%x\n", getpid(), cap.effective, cap.permitted, cap.inheritable);

return 0;

}

启动java

通过调用JNI_CreateJavaVM 启动虚拟机器,同时调用包common-daemon里的DaemonLoader class, 调用你所写的类中的start,...这些方法。

碰到的问题

在jsvc 里启动java以后就将jvm的虚拟机的进程的capability 设置成了0,  导致在虚拟机里的创建线程受到max process 的控制, ulimit -u

已经创建issue: https://issues.apache.org/jira/browse/DAEMON-270, 短期解决办法可以设置ulimit 到比较大的值。

分布式进阶(五)之JSVC配置的更多相关文章

  1. 分布式进阶(十二)Docker固定Container IP

    使用pipework工具. 前提:每个Container所做的工作现在还很少,可以不用save.commit. 为了便于通信,自定义一个网桥(192.168.1.180/24),使之IP与宿主主机IP ...

  2. J2EE进阶(五)Spring在web.xml中的配置

     J2EE进阶(五)Spring在web.xml中的配置 前言 在实际项目中spring的配置文件applicationcontext.xml是通过spring提供的加载机制自动加载到容器中.在web ...

  3. Java进阶(五十二)利用LOG4J生成服务日志

    Java进阶(五十二)利用LOG4J生成服务日志 前言 由于论文写作需求,需要进行流程挖掘.前提是需要有真实的事件日志数据.真实的事件日志数据可以用来发现.监控和提升业务流程. 为了获得真实的事件日志 ...

  4. 阿里云服务器Linux CentOS安装配置(五)jetty配置、部署

    阿里云服务器Linux CentOS安装配置(五)jetty配置.部署 1.官网下载jetty:wget http://repo1.maven.org/maven2/org/eclipse/jetty ...

  5. hbase单机环境的搭建和完全分布式Hbase集群安装配置

    HBase 是一个开源的非关系(NoSQL)的可伸缩性分布式数据库.它是面向列的,并适合于存储超大型松散数据.HBase适合于实时,随机对Big数据进行读写操作的业务环境. @hbase单机环境的搭建 ...

  6. EHCache分布式缓存集群环境配置

    EHCache分布式缓存集群环境配置 ehcache提供三种网络连接策略来实现集群,rmi,jgroup还有jms.同时ehcache可以可以实现多播的方式实现集群,也可以手动指定集群主机序列实现集群 ...

  7. jmeter 环境部署、数据库设置、分布式设置、多网卡配置等随笔

    <!-- linux系统修改系统环境变量  系统语言-->[root@web-249 ~]# env|grep LANGLANG=zh_CN.UTF-8[root@web-249 ~]# ...

  8. Web Service进阶(五)SOAPBinding方式讲解

    Web Service进阶(五)SOAPBinding方式讲解 Java API for XML Web Services (JAX-WS) 2.0 (JSR 224) Standard Implem ...

  9. 分布式进阶(二)Ubuntu 14.04下安装Dockr图文教程(一)

    当前,完全硬件虚拟化技术(KVM.Xen.Hyper-V 等)能在一个物理主机上很好地运行多个互相独立的操作系统,但这也带来一些问题:性能不佳,资源浪费,系统反应迟缓等.有时候对用户来说,完全的硬件虚 ...

随机推荐

  1. easyui datagrid editor combobox添加空选则清空combobox框

    <script type='text/javascript'> var editIndex = undefined; $(function() { $('#tb1').datagrid({ ...

  2. webservice服务器端获取request对象的三种方式

    有的时候在webservice里我们需要获取request对象和response对象,比如想要获得客户端的访问ip的时候就需要这么做,下面说三种方式,当然三种方式可能是针对不同方式部署webservi ...

  3. 电子凭证 : Java 生成 Pdf

    来源:蛙牛, my.oschina.net/lujianing/blog/894365 如有好文章投稿,请点击 → 这里了解详情 1.背景 在某些业务场景中,需要提供相关的电子凭证,比如网银/支付宝中 ...

  4. 项目实战15.2—企业级堡垒机 jumpserver快速入门

    必备条件 硬件条件 ① 一台安装好 Jumpserver 系统的可用主机(堡垒机) ② 一台或多台可用的 Linux.Windows资产设备(被管理的资产) 服务条件 (1)coco服务 ① 鉴于心态 ...

  5. 推荐算法之用户推荐(UserCF)和物品推荐(ItemCF)对比

    一.定义 UserCF:推荐那些和他有共同兴趣爱好的用户喜欢的物品 ItemCF:推荐那些和他之前喜欢的物品类似的物品 根据用户推荐重点是反应和用户兴趣相似的小群体的热点,根据物品推荐着重与用户过去的 ...

  6. [BBS]搭建开源论坛之JForum安装使用札记

    本文作者:sushengmiyan 本文地址:http://blog.csdn.net/sushengmiyan/article/details/47761303 目录 目录 BBS搭建开源论坛之JF ...

  7. PHP学习(4)——数据类型

    PHP 支持 8 种原始数据类型. 四种标量类型:(标量类型即为基本类型) boolean(布尔型) integer(整型) float(浮点型,也称作 double) (由于历史原因,float也叫 ...

  8. Dynamics CRM 产品视图列上自带按钮的隐藏

    CRM中对command bar的处理都是使用ribbon workbench,但是很多系统自带的按钮你是没法在ribbon workbench看到的,咱们以产品为例,比如我要隐藏form上的保存按钮 ...

  9. Xcode 中的断言

    转自:http://weibo.com/p/100808885591f113cdedc3301794e5e7d7e9f0/home?from=page_100808&mod=TAB#_rnd1 ...

  10. iOS学习笔记--触摸事件

    最近空闲时间在学习iOS相关知识,几周没有更新文章了,今天总结下这些天的学习内容,也整理下iOS的学习笔记,以便以后查阅翻看- iOS中的事件可以分为3大类型: 触摸事件 加速计事件 远程控制事件 响 ...