标签:resin;运维
III 19 resin
JAVA应用服务器resin:
企业级的java应用程序需要部署时,JAVA EE(enterprise edition)应用服务器是必不可少的工具;
商业的JAVA EE应用服务器有:BEA Weblogic Server、IBM Websphere Application Server、Oracle ApplicationServer、Sybase EA Server;
开源的有:tomcat、JBoss、resin、Geronimo,JBoss、resin也有商业版;
tomcat、JBoss、resin并非完全实现了JAVAEE5标准,但这三者占的市场份额相对较大,而Geronimo是对JAVA EE5完整的实现;
注:taobao用JBoss,baidu、renren、sougou、互动百科用resin
http://caucho.com/
resin是caucho公司的产品,是一个非常流行的支持servlets和jsp的引擎,速度非常快,它本身包含了一个支持HTTP/1.1的web server,虽然它可显示动态内容,但它显示静态内容的能力也非常强,速度与httpd、nginx相当;resin也可和web server在一起工作,如httpd、nginx、IIS等;
resin可运行在win、LinuxOS平台,可作为webserver独立启动来提供服务,也可和httpd、nginx、IIS结合工作;
resin是用JAVA开发的,它支持servlet2.3标准和JSP1.2标准,用resin来进行JSP编程很容易,它提供了最快的JSP/servlets运行平台,在JAVA和JavaScript的支持下,resin可以为任务灵活选用合适的开发语言,resin的一种先进的语言XSL(xml stylesheet language)可以使得形式和内容相分离,如果选用JSP平台作为internet商业站点的支持,那么速度、价格和稳定性等方面resin表现非常出色、更成熟,具备商业软件的要求,重要的是它开源,从site下载的就是完整版本;
resin支持LB,可增加web site的可靠性,如一台server的错误率是1%的话,那支持LB的两个resinserver可使错误率降到0.01%;
tomcat更象是一个正在研究的项目,resin支持SUN的J2EE,而tomcat不能直接支持,而J2EE是基于JAVA服务端大系统的基础;tomcat6是一个快速稳定轻巧的JSP容器,它和resin是不同的发展方向,tomcat6不支持ejb、jta等高级功能,需要自己扩展比较麻烦;resin3之后已不再是一个简单的JSP容器,且支持ejb、jta等企业功能,resin4性能更好,且支持servlet3.0标准,pro版本是商业版,支持LB和文件缓存,很多大型门户网站都采用pro版本作为app server;
caucho公司还为resin添加了php解析执行功能,可运行php程序,但相对php的原先版本有一定差距,resin分普通版和专业版professional,区别pro版支持缓存和LB,pro因为有强大的cache功能,可独立作为webserver用来处理静态内容,但普通版本独立作为web server性能要差些,可使用httpd+resin方案借助httpd的缓存功能来提高性能;
版本:3.0-->3.1-->4.0
http://caucho.com/products/resin/download/3-1/gpl
http://caucho.com/products/resin/download/gpl
JVM调优:
数据类型(JVM中数据类型分两类:基本类型(变量保存原始值,即数据本身,包括byte、short、int、long、char、float、double、boolean);引用类型(变量保存引用值,即某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置);
heap堆与stack栈是程序运行的关键:
stack是运行时的单位,而heap是存储的单位;
stack解决程序的运行问题(程序如何运行或如何处理数据),heap解决的是数据存储的问题(数据怎么放,放在哪儿);
在java中,一个线程就会相应有一个线程stack与之对应,因此里面存储的信息都是跟当前线程(或程序)相关,包括局部变量、程序运行时的状态(pc register保存程序运行状态,CS有关)、方法返回值等等,而heap只负责存储对象信息;
从软件设计的角度看,stack代表了处理逻辑,而heap代表了数据,分而治之的思想,分开使得处理逻辑更为清晰,这种隔离、模块化的思想在软件设计的方方面面都有体现;heap与stack的分离,使得堆中的内容可以被多个stack共享(多个线程访问同一个对象),这种共享的收益是很多的,一方面提供了一种有效的数据交互方式,如共享内存,会带来并发问题,另一方面heap中的共享常量和缓存可以被所有stack访问,节省了空间;
stack因为运行时的需要,如CS上下文切换,需要进行地址段的划分,由于stack只能向上增长,因此就会限制住stack存储内容的能力,而heap不同,heap中的对象是可以根据需要动态增长的,因此stack和heap的拆分,使得动态增长成为可能,相应stack中只需记录堆中的一个地址即可;
oop就是heap和stack的完美结合,object-oriented的程序与procedure-oriented面向过程结构化的程序在执行上没有任何区别,但oo的引入使得对待问题的思考方式发生了改变,更接近自然方式的思考,把对象拆开,对象的属性就是数据,存放在heap中,对象的行为(方法)就是运行逻辑,放在stack中,在编写对象的时候,既编写了数据结构,也编写了处理数据的逻辑;
heap中存的是对象,stack中存的是基本数据类型和heap中对象的引用,一个对象的大小是不可估计的(是动态变化的),但在stack中,一个对象只对应了一个4byte(32bit)的引用,为什么不把基本类型放在heap中(因为其占用的空间一般是1-8byte,所需空间很少,而且因为是基本类型,不会出现动态增长的情况,长度固定,因此stack中存储就够了,若把它放在heap中会浪费空间是没意义的);
基本类型和对象的引用存在stack中,都是几个byte一个数,因此程序运行时,它们的处理方式是统一的,但它们和对象本身就有区别了,基本类型和对象引用在stack中,对象在heap中,最常见的一个问题是java中参数传递;
java中参数传递是传值还是传引用,前提(不要与C对比,java中没有指针的概念;程序永远都是在stack中运行,因此参数传递时,只存在传递基本类型和对象引用,不会直接传对象本身),java中方法调用传递参数时,由于没有指针,所以它都是进行传值调用(可参考C的传值调用),是简化了C中的复杂性;
stack是程序运行最根本的东西,程序运行可以没有heap,但不能没有stack,heap是为stack进行数据存储服务,heap是共享的内存,不过正是因为heap和stack分离的思想,使得java的GC成为可能;
java中,stack的大小通过-Xss来设置,当stack中存储数据比较多时,需要适当调大这个值,(默认1024K已足够大,大约70万行代码占1K),否则会出现java.lang.stackOverflowError,这个异常是无法返回的递归,因为此时stack中保存的信息都是方法返回的记录点;
引用类型(对象引用类型分为强引用、软引用、弱引用、虚引用):
强引用(一般声明对象时虚拟机生成的引用,强引用环境下,GC时需要严格判断当前对象是否被强引用,如果被强引用,则不会被GC);
软引用(一般被作为缓存来使用,与强引用的区别,软引用在GC时,VM会根据当前系统的剩余内存来决定是否对软引用进行回收,如果剩余内存不多,则VM会回收软引用所引用的空间,如果剩余内存很多,则不会进行回收,VM在发生OutOfMemory时,肯定是没有软引用存在的);
弱引用(与软引用类似,都是作为缓存来使用,但弱引用在进行GC时是一定会被回收掉的,其生命周期只存在于一个GC周期内)
注:系统一般在使用时都是用的强引用;而软引用和弱引用比较少见,一般作为缓存来使用(使用在桌面应用系统的缓存),一般是在内存大小比较受限的情况下作为缓存,因为如果内存足够大的话,可直接使用强引用作为缓存,同时可控性更高;只有强引用会导致内存泄露OutOfMemory
垃圾回收算法:
按基本回收策略分(reference counting引用计数、mark sweep标记清除、copying复制、mark compact标记整理):
reference counting(最早,建立对象时有一个引用,会增加一个计数,删除一个引用则减少一个计数,在GC时只收集计数为0的对象,无法处理循环引用的问题);
mark sweep(分两个阶段,从引用根节点开始标记所有被引用的对象,再遍历整个heap,把未标记的对象清除,此算法需要暂停整个应用,同时会产生内在碎片,一般heap内存-Xmx1024m不要超过4G,否则GC时间会很长影响应用);
copying(把内存空间划分为两个相等的区域,每次只使用一个区域,GC时遍历当前使用区域,把正在使用中的对象复制到另一个区域中,此算法每次只处理正在使用中的对象,因此复制成本较小,同时复制过去后还能进行相应的内存整理,不会出现碎片,缺点需要两倍的内存空间);
mark compact(结合了mark sweep和copying的优点,分两阶段,从根节点开始标记所有被引用的对象,再遍历整个heap,把清除未标记对象和存活对象压缩到heap中的其中一块,按顺序排放,避免了mark sweep的碎片问题和copying的空间问题);
按系统线程分(串行收集、并行收集、并发收集):
串行收集(使用单线程处理所有GC工作,因为无需多线程交互,实现容易、效率高,也有局限性,无法使用多处理器的优势,此方法适合场景,用在小数据量情况(100M左右)的单处理器机器,并且对响应时间无要求的应用,缺点只能用于小型应用;使用-XX:+UseSerialGC打开);
并行收集(使用多线程处理GC工作,速度快、效率高,理论上CPU数目越多,越能体现并行收集器的优势,使用-XX:+UseParallelOldGC打开,用-XX:ParallelGCThreads=NUM设置并行GC的线程数,用-XX:MaxGCPauseMillis=NUM设置最大GC暂停时间单位ms,用-XX:GCTimeRatio=NUM设置吞量GC时间与非GC时间比值;适用场景,对吞吐量有高要求,多CPU,对应用响应时间无要求的中大型应用,如后台处理、科技计算,缺点,GC过程中应用响应时间可能加长);
并发收集(GC线程是回收内存的,而程序运行线程是分配内存的,串行、并行在GC时要暂停整个应用,使用并发收集算法,则垃圾回收线程与程序运行线程同时运行,复杂度增加,要在新生成对象的同时又要回收对象,系统的处理能力会相应降低,碎片问题难以解决,使用-XX:+UseConcMarkSweepGC打开;适用场景,多CPU,对应用响应时间有高要求的中大型应用,如web server|app server、电信交换、集成开发环境);
注:串行和并行在进行GC工作时,需暂停整个运行环境,仅GC程序在运行,因此系统有明显的暂停,时间会因为heap越大而越长,因为是对整个heap进行回收
分代的垃圾回收策略,基于不同对象的生命周期是不一样的,不同生命周期的对象可采用不同的收集方式,以便提高回收效率,java程序运行过程中会产生大量的对象,有些对象与业务相关,如http请求中的session对象、thread、socket等,与业务挂钩的生命周期比较长,而有些对象是在程序运行过程中生成的临时变量这些生命周期比较短,如string对象,由于其不变类的特性,系统会产生大量的这些对象,其中一些甚至只用一次就被回收;
JVM中分三个代(Young Generation、OldGeneration、Permanent Generation):
Young Generation(所有新生成的对象都在年轻代,年轻代的目标,尽可能快速的收集掉那些生命周期短的对象,分一个Eden区和两个Survivor区,当Eden区满时,还存活的对象将被复制到两个中的其中一个Survivor区,例如Survivor1,当Survivor1区满了的时候,从Survivor1区复制到另一个Survivor区,例如Survivor2,当Survivor2也满时从Sruvivor1区过来的此时还存活的对象将被复制到Tenured年老代区;Survivor的两个区是对称的,没有先后关系,所以同一个区可能同时存在从Eden复制过来的对象和从前一个Survivor复制过来的对象,而复制到年老区的只有从第一个Survivor区过来的对象而且Survivor区总有一个是空的);
Old Generation(Tenured,放经历了N次GC后仍然存活的对象,存放的都是生命周期较长的对象);
Permanent Generation(存放java类的类信息,例如java类、方法等,与GC要收集的java对象关系不大,但有些应用可能动态生成或调用一些class,如hibernate,这时需要设置一个比较大的持久代空间来存放这些运行过程中新增的类;使用-XX:MaxPermSize=NUM设置);
GC有两种类型(scavenge GC、full GC):
scavenge GC(一般当新对象生成,并且在Eden申请空间失败时,就触发scavengeGC,对Eden区进行GC,清除非存活对象,并把尚且存活的对象移到Survivor区,再整理整个Survivor的两个区,这种方式只对Eden区进行,不影响年老代,此处要使用速度快,效率高的算法);
full GC(对整个heap进行整理,包括young、old、permanent,full GC比scavenge GC要慢,应尽可能减少fullGC的次数,在对JVM调优的过程中,很大一部分工作就是对full GC的调节,会触发full GC的情况有:tenured年老代被写满、permanent持久代域被写满、system.gc()被显示调用、上一次GC之后heap的各域分配策略动态变化);
floating garbage活动垃圾(由于在应用运行的同时进行GC,有些垃圾可能在GC进行完成时产生,这就产生了floating garbage,这些垃圾需要在下次GC周期时才能回收掉,所以并发收集器一般需要20%的预留空间用于这些浮动垃圾);
并发收集器在应用运行时进行收集,必须保证收集完成之前有足够的内存空间供程序使用,否则GC还未完成,heap空间就满了,这种情况下将会发生ConCurrent Mode Failure,此时整个应用将会暂停,进行GC工作,通过设置-XX:CMSInitiatingOccupancyFunction=NUM指定还有多少剩余heap空间时开始执行并发收集
常用配置:
heap设置:
-Xms(初始堆大小)
-Xmx(最大堆大小,一般将-Xms和-Xmx设为一样,避免多次GC完后JVM重新分配内存,最好不要超过4G)
-XX:NewSize=NUM(年轻代大小)
-XX:NewRatio=NUM(年轻代和年老代的比值,3表示young:old=1:3,young:(young+old)=1:4);
-XX:SurvivorRatio=NUM(年轻代中Eden区与两个Survivor区的比值,3表示Eden:Survivor=3:2,一个Survivor区占整个年轻代的1/5);
-XX:MaxPermSize=NUM(持久代大小);
收集器设置:
-XX:+UseSerialGC(串行收集器)
-XX:+UseParallelGC(并行收集器,-XX:ParallelGCThreads=NUM,收集时使用的CPU数,并行收集线程数;-XX:MaxGCPauseMillis=NUM并行收集最大暂停时间;-XX:GCTimeRatio=NUM垃圾回收时间占程序运行时间的百分比,公式1/(1+n))
-XX:+UseParallelOldGC(并行年老代收集器)
-XX:+UseConcMarkSweepGC(并发收集器,-XX:+CMSIncrementalMode,增量模式,适用于单CPU情况;-XX:ParallelGCThreads=NUM,设置并发收集器年轻代收集方式为并行收集时,使用的CPU数,并行收集线程数)
垃圾回收统计信息:
-XX:+PrintGC
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-Xloggc:filename
JVM中对heap大小有三方面限制(相关OS的数据模型(如32bit一般1.5-2G,64bit无限制,winserver 2003,3.5G物理内存);系统的可用虚拟内存限制;系统的可用物理内存限制);
回收器选择(默认jdk5.0之前都是使用串行收集器,这只适用小型数据量的情况;jdk5.0之后JVM会根据当前系统配置进行判断)
典型配置:
针对分代垃圾回收算法:
-Xms3550m
-Xmx3550m
-xmn2g(年轻代大小为2g,整个heap大小=年轻代大小+年老代大小+持久代大小,持久代一般固定64m,所以增大年轻代后会减少年老代大小,此值对系统性能影响较大,sun官方推荐配置为整个heap的3/8)
-Xss128k(每个线程heap stack大小,jdk5.0以后每个线程堆栈大小为1M,之前为256K,根据应用所需内存大小进行调整,在相同物理内存下,减小这个值能生成更多的线程,但OS对一个进程内的线程数是有限制的65535(#ulimit -n,/etc/security/limits.conf),经验值在3000-5000);
-XX:NewRatio=4
-XX:SurvivorRatio=4(1个Eden:2个Survivor=4:2,一个Survivor占整个年轻代的1/6)
-XX:MaxPermSize=16m
-XX:MaxTenuringThreshold=0(垃圾最大年龄,0表示年轻代对象经过Survivor区直接进入年老代,年老代中对象多时可提高应用的效率;若将此处值设为一个最大值,则年轻代对象会在Survivor区进行多次复制,这样可增加对象在年轻代的存活时间,增加在年轻代区即会被回收的概率)
举例:吞吐量优先的并行收集器(适用于科学计算和后台处理,一般有一个很大的年轻代和一个较小的年老代,这样尽可能回收掉大部分短期对象,减少中期对象,年老代中存放长期存活对象):
JAVA_OPTS=‘……‘
(1)java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC-XX:ParallelGCThreads=20(年轻代使用并行收集,而年老代仍使用串行收集)
(2)java -Xmx3550m -Xms3550m -Xmn2g -Xss128k -XX:+UseParallelOldGC-XX:ParallelGCThreads=20(年老代为并行收集,jdk6.0支持对年老代并行收集)
(3)java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC-XX:MaxGCPauseMillis=100(指定每次年轻代GC时的最长时间,若无法满足此时间,JVM会自动调整年轻代大小)
(4)java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:+UseParallelGC-XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy(并行收集器会自动选择年轻代区大小和相应的Survivor比例,以达到目标系统规定的最低相应时间或收集频率等,建议使用此项)
举例:响应时间优先的并发收集器(适用于web server|app server等,主要保证系统的响应时间,减少GC时的停顿时间):
(1)java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:ParallelGCThreads=20 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC(有-XX:+UseConcMarkSweepGC时-XX:NewRatio=4将失效;-XX:UseParNewGC年轻代为并行收集,可与CMS同时使用,jdk5.0ch JVM会根据系统自行配置,无需此值;年轻代大小最好用-Xmn设置)
(2)java -Xmx3800m -Xms3800m -Xmn2g -Xss128k -XX:UseConcMarkSweepGC -XX:CMSFullGCBeforeCompaction=5 -XX:+UseCMSCompactAtFullCollection(-XX:CMSFullGCBeforeCompaction=5运行多少次GC后对内存空间进行压缩、整理,用以解决碎片;-XX:+UseCMSCompactAtFullCollection打开对年老代的压缩,会影响性能但可清除碎片;这两项可解决较小heap引起的碎片问题)
JVM调优工具(jconsole、jvisualvm、jprofile):
jconsole(jdk自带,功能简单,可在系统有一定负荷的情况下使用,对GC算法有很详细的跟踪);
jvisualvm(jdk自带,功能强大,类似jprofile);
jprofile(商业软件,功能强大);
jstat(#jstat -gcutil PID)
jstatd
jstack(#jstack -l PID)
jmap(#jmap[-heap|-histo|-dump|-F])
eclipse插件MAT可有效分析内存占用情况
Usage: jconsole [ -interval=n ] [ -notile ][ -pluginpath <path> ] [ -version ] [ connection ... ]
-interval Set the updateinterval to n seconds (default is 4 seconds)
-notile Do not tile windowsinitially (for two or more connections)
-pluginpath Specify the path that jconsole uses to look up the plugins
-version Print program version
connection = pid || host:port || JMX URL(service:jmx:<protocol>://...)
pid The process id of atarget process
host A remote host name orIP address
port The port number forthe remote connection
-J Specify the inputarguments to the Java virtual machine
on which jconsole is running
注:
各工具完成功能(堆信息查看、内在泄露检查)
java.lang.OutOfMemoryError:Java heapspace(年老代堆空间占满)
java.lang.OutOfMemoryError:PermGen space(持久代被占满,调大-XX:MaxPermSize=16m或换用jdk,例如JRocket)
java.lang.stackOverflowError(一般是递归没返回,或循环调用造成)
Stack size too small(线程堆栈满)
java.lang.OutOfMemoryError:unable to create new native thread(系统内存被占满,修改-Xss减少分配给单个线程的空间)
操作:
jdk-8u51-linux-x64.rpm
resin-3.1.15.tar.gz
httpd-2.2.31.tar.gz
[root@proxy-1-1 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.5(Santiago)
[root@proxy-1-1 ~]# uname -rm
2.6.32-642.3.1.el6.x86_64 x86_64
[root@proxy-1-1 ~]# rpm -ivh jdk-8u51-linux-x64.rpm
Preparing... ########################################### [100%]
1:jdk1.8.0_51 ########################################### [100%]
Unpacking JAR files...
rt.jar...
jsse.jar...
charsets.jar...
tools.jar...
localedata.jar...
jfxrt.jar...
plugin.jar...
javaws.jar...
deploy.jar...
[root@proxy-1-1 ~]# ll /usr/java
total 4
lrwxrwxrwx. 1 root root 16 Aug 15 23:57 default ->/usr/java/latest
drwxr-xr-x. 9 root root 4096 Aug 15 23:56jdk1.8.0_51
lrwxrwxrwx. 1 root root 21 Aug 15 23:57 latest ->/usr/java/jdk1.8.0_51
[root@proxy-1-1 ~]# ls /usr/java/jdk1.8.0_51/
bin db javafx-src.zip lib man release THIRDPARTYLICENSEREADME-JAVAFX.txt
COPYRIGHT include jre LICENSE README.html src.zip THIRDPARTYLICENSEREADME.txt
[root@proxy-1-1 ~]# ls/usr/java/jdk1.8.0_51/bin
appletviewer jarsigner javah jcmd jhat jmc.ini jstat orbd rmiregistry unpack200
ControlPanel java javap jconsole jinfo jps jstatd pack200 schemagen wsgen
extcheck javac javapackager jcontrol jjs jrunscript jvisualvm policytool serialver wsimport
idlj javadoc java-rmi.cgi jdb jmap jsadebugd keytool rmic servertool xjc
jar javafxpackager javaws jdeps jmc jstack native2ascii rmid tnameserv
[root@proxy-1-1 ~]# vim/etc/profile.d/java.sh
JAVA_HOME=/usr/java/jdk1.8.0_51
CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
RESIN_HOME=/usr/local/resin
export JAVA_HOMECLASSPATH PATH RESIN_HOME
[root@proxy-1-1 ~]# source !$
source /etc/profile.d/java.sh
[root@proxy-1-1 ~]# echo $JAVA_HOME
/usr/java/jdk1.8.0_51
[root@proxy-1-1 ~]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/mysql/bin:/usr/local/python3.4/bin:/root/bin:/usr/local/python3.4/bin:/usr/java/jdk1.8.0_51/bin:/usr/java/jdk1.8.0_51/jre/bin:/usr/java/jdk1.8.0_51/bin:/usr/java/jdk1.8.0_51/jre/bin
[root@proxy-1-1 ~]# echo $CLASSPATH
:/usr/java/jdk1.8.0_51/lib:/usr/java/jdk1.8.0_51/jre/lib:/usr/java/jdk1.8.0_51/lib:/usr/java/jdk1.8.0_51/jre/lib
[root@proxy-1-1 ~]#java -version
java version "1.8.0_51"
Java(TM) SE Runtime Environment (build1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build25.51-b03, mixed mode)
[root@proxy-1-1 ~]# tar xf resin-3.1.15.tar.gz -C /usr/local/ #(解压即可使用,若要与httpd或nginx结合需要编译生成相关模块)
[root@proxy-1-1 ~]# cd !$
cd /usr/local/
[root@proxy-1-1 local]# ln -sv resin-3.1.15/ resin
`resin‘ -> `resin-3.1.15/‘
[root@proxy-1-1 local]# cd resin
[root@proxy-1-1 resin]# cd conf
[root@proxy-1-1 conf]# ls
app-default.xml development.conf fine.conf minimal.conf resin.conf resin.conf.orig
[root@proxy-1-1 conf]# vim resin.conf (将<server-default>……</server-default>段删除,常用的jvm argument有:-Xmx1024M最大堆大小,-Xms1024M;生产中一般将-Xmx1024M和-Xms1024M设为相同,以减少运行期间系统在内存申请上所花的开销;-XX:NewSize=512M,-XX:MaxNewSize=512M,生产中一般将这两项设为相同,以减少运行期间系统在内存申请上所花的开销;-Xss1024k每个线程的stack大小;NewRatio=2年轻代和年老代的比值;-XX:MaxPermSize=100M最大永久区大小,永久保存区用于存放class信息和元信息;-Dsun.rmi.transport.tcp.responseTimeout=5000,client连接rmi服务端数据返回的超时时间,单位ms)
<server id="test"address=‘10.96.20.113‘ port=‘6911‘ watchdog-port=‘6600‘>
<http address="*"port="8080"/>
<jvm-arg>-Xmx256m</jvm-arg>
<jvm-arg>-Xss1m</jvm-arg>
<jvm-arg>-Xdebug</jvm-arg>
<jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>
<memory-free-min>1M</memory-free-min> <!--Configures the minimum free memoryallowed before Resin will force a restart,当jvm的内存小于此处指定的值,resin服务会gracefully重启,来释放泄露的内存空间-->
<thread-max>256</thread-max> <!--Maximum number of threads,并发数,几百到一千即可,taobao优化到1500-->
<socket-timeout>65s</socket-timeout> <!--Configures the sockettimeout,读写socket最大超时时间-->
<keepalive-max>128</keepalive-max> <!--Configures the keepalive,最多长连接数-->
<keepalive-timeout>15s</keepalive-timeout> <!--长连接超时时间-->
</server>
[root@proxy-1-1 resin]# cd webapps/ROOT/ #(默认站点目录)
[root@proxy-1-1 ROOT]# ls
index.jsp
[root@proxy-1-1 ROOT]# echo ‘1+1=<%=1+1%>‘ > test.jsp
[root@proxy-1-1 ROOT]# cd ../..
[root@proxy-1-1 resin]# ls contrib/
build.xml init.resin.in init.resin-iptables
[root@proxy-1-1 resin]# cp contrib/init.resin.in /etc/init.d/resind
[root@proxy-1-1 resin]# chmod 755 /etc/init.d/resind
[root@proxy-1-1 resin]# vim !$ #(如果脚本要在任务计划中运行,注意脚本中所有的变量和命令要重新声明,计划任务不能识别和加载所有的环境变量)
vim /etc/init.d/resind
JAVA_HOME=/usr/java/jdk1.8.0_51
RESIN_HOME=/usr/local/resin
export JAVA_HOMERESIN_HOME
SERVER="-servertest"
[root@proxy-1-1 resin]# service resind start #(如果启动时报如下错,将脚本中的log_daemon_msg和log_end_msg这两个函数加入到/lib/lsb/init-functions这个文件中)
/etc/init.d/resind: line 63:log_daemon_msg: command not found
/etc/init.d/resind: line 69: log_end_msg:command not found
[root@proxy-1-1 resin]# service resind start
Starting resin: .
[root@proxy-1-1 resin]# ps aux | grep java
root 2888 15.5 11.4 1927176 55468 pts/0 Sl 23:31 0:01 /usr/java/jdk1.8.0_51/bin/java -Djava.util.logging.manager=com.caucho.log.LogManagerImpl-Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl-Djava.awt.headless=true -Dresin.home=/usr/local/resin-Dresin.root=/usr/local/resin/ -Xrs -Xss256k -Xmx32m -d64com.caucho.boot.WatchdogManager -resin-home /usr/local/resin -server test start
root 2912 32.7 20.0 2186396 97668 pts/0 Sl 23:31 0:02 /usr/java/jdk1.8.0_51/bin/java-Djava.util.logging.manager=com.caucho.log.LogManagerImpl-Djava.system.class.loader=com.caucho.loader.SystemClassLoader-Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl-Djava.awt.headless=true -Dresin.home=/usr/local/resin -d64 -Xmx256m -Xss1m-Xdebug -Dcom.sun.management.jmxremote-Djava.util.logging.manager=com.caucho.log.LogManagerImpl-Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl-Djava.awt.headless=true -Dresin.home=/usr/local/resin-Dresin.root=/usr/local/resin/-Djava.util.logging.manager=com.caucho.log.LogManagerImpl-Djavax.management.builder.initial=com.caucho.jmx.MBeanServerBuilderImpl-Djava.awt.headless=true -Dresin.home=/usr/local/resin -Dresin.root=/usr/local/resin/com.caucho.server.resin.Resin --root-directory /usr/local/resin -conf/usr/local/resin/conf/resin.conf -socketwait 42732 -resin-home /usr/local/resin-server test start
root 2948 0.0 0.1 103264 836 pts/0 S+ 23:31 0:00 grep java
[root@proxy-1-1 resin]# chkconfig --add resind
[root@proxy-1-1 resin]# chkconfig --list resind
resind 0:off 1:off 2:off 3:on 4:on 5:on 6:off
[root@proxy-1-1 resin]# service resind stop
Stopping resin: .
[root@proxy-1-1 resin]# ps aux | grep java
root 2986 0.0 0.1 103264 832 pts/0 S+ 23:32 0:00 grep java
[root@proxy-1-1 resin]# cd bin
[root@proxy-1-1 bin]# ./httpd.sh -server test start #(也可用此种方式启动resin程序)
Resin/resin-3.1.15 started -server ‘‘ forwatchdog at 127.0.0.1:6600
[root@proxy-1-1 bin]# curl -I10.96.20.113:8080
HTTP/1.1 200 OK
Server: Resin/resin-3.1.15
Content-Type: text/html
Date: Wed, 17 Aug 2016 06:09:45 GMT
[root@proxy-1-1 bin]# curl10.96.20.113:8080/test.jsp
1+1=2
案例(httpd+resin):
[root@proxy-1-1 ~]# yum -y install zlib zlib-devel libxml libxml2-devel freetype freetype-devel libpng libpng-devel gd gd-devel curl curl-devel libjpeg libjpeg-devel libiconv
[root@proxy-1-1 ~]# tar xf apr-1.5.2.tar.gz
[root@proxy-1-1 ~]# cd apr-1.5.2
[root@proxy-1-1 apr-1.5.2]# ./configure --prefix=/usr/local/apr
[root@proxy-1-1 apr-1.5.2]# make && make install
[root@proxy-1-1 apr-1.5.2]# cd ..
[root@proxy-1-1 ~]# tar xf apr-util-1.5.4.tar.gz
[root@proxy-1-1 ~]# cd apr-util-1.5.4
[root@proxy-1-1 apr-util-1.5.4]# ./configure --prefix=/usr/local/apr-util --with-apr=/usr/local/apr
[root@proxy-1-1 apr-util-1.5.4]# make && make install
[root@proxy-1-1 ~]# tar xfhttpd-2.2.31.tar.gz
[root@proxy-1-1 ~]# cd httpd-2.2.31
[root@proxy-1-1 httpd-2.2.31]# ./configure --prefix=/usr/local/apache --enable-deflate--enable-headers --enable -modules=so --enable-so --with-mpm=worker --enable-rewrite --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util
[root@proxy-1-1 httpd-2.2.31]# make && make install
[root@proxy-1-1 httpd-2.2.31]# cd/usr/local/resin/
[root@proxy-1-1 resin]# ./configure --with-apxs=/usr/local/apache/bin/apxs
……
checking that generated files are newerthan configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creatingmodules/c/src/Makefile
config.status: creatingmodules/c/src/common/Makefile
config.status: creatingmodules/c/src/apache1/Makefile
config.status: creatingmodules/c/src/apache2/Makefile
config.status: creatingmodules/c/src/resin_os/Makefile
config.status: creating contrib/init.resin
config.status: executing depfiles commands
config.status: executing libtool commands
[root@proxy-1-1 resin]# cd modules/c/src/
[root@proxy-1-1 src]# cp /usr/local/apr/include/apr-1/* /usr/local/apache/include/
[root@proxy-1-1 src]# cp /usr/local/apr-util/include/apr-1/* /usr/local/apache/include/
[root@proxy-1-1 src]# make && make install
[root@proxy-1-1 src]# ll/usr/local/apache/modules/mod_caucho.so #(在httpd生成此模块,httpd就是通过这个模块调用resin解析java程序的)
-rwxr-xr-x. 1 root root 170963 Aug 21 22:57/usr/local/apache/modules/mod_caucho.so
[root@proxy-1-1 src]# tail/usr/local/apache/conf/httpd.conf
</IfModule>
#
# mod_caucho Resin Configuration
#
LoadModule caucho_module /usr/local/apache/modules/mod_caucho.so
ResinConfigServer localhost 6800
CauchoConfigCacheDirectory/tmp
CauchoStatus yes
[root@proxy-1-1 src]# vim !$ #(SetHandlercaucho-request实现任何请求都抛给后端resin)
vim /usr/local/apache/conf/httpd.conf
LoadModule caucho_module /usr/local/apache/modules/mod_caucho.so
#SetHandlercaucho-request
ResinConfigServer 10.96.20.113 6911
CauchoConfigCacheDirectory/tmp
CauchoStatus yes
[root@proxy-1-1 bin]# pwd
/usr/local/apache/bin
[root@proxy-1-1 bin]# cd ..
[root@proxy-1-1 apache]# bin/httpd -f ./conf/httpd.conf #(使用这种方式启动httpd)
httpd: Could not reliably determine theserver‘s fully qualified domain name, using 10.96.20.113 for ServerName
[root@proxy-1-1 apache]# lsof -i :80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 15212 root 4u IPv6 42701 0t0 TCP *:http (LISTEN)
httpd 15214 daemon 4u IPv6 42701 0t0 TCP *:http (LISTEN)
httpd 15215 daemon 4u IPv6 42701 0t0 TCP *:http (LISTEN)
httpd 15216 daemon 4u IPv6 42701 0t0 TCP *:http (LISTEN)
[root@proxy-1-1 bin]# vim/usr/local/resin/conf/resin.conf #(web server使用httpd,resin处理动态内容,实现动静分离)
<!-- <http address="*"port="8080"/> -->
[root@proxy-1-1 bin]# service resindrestart
Stopping resin: .
Starting resin: .
[root@proxy-1-1 apache]# netstat -tnulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1794/sshd
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 1661/cupsd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 2299/master
tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 2611/sshd
tcp 0 0 127.0.0.1:6011 0.0.0.0:* LISTEN 3062/sshd
tcp 0 0 :::80 :::* LISTEN 15450/bin/httpd
tcp 0 0 :::22 :::* LISTEN 1794/sshd
tcp 0 0 ::1:631 :::* LISTEN 1661/cupsd
tcp 0 0 ::1:25 :::* LISTEN 2299/master
tcp 0 0 ::1:6010 :::* LISTEN 2611/sshd
tcp 0 0 ::1:6011 :::* LISTEN 3062/sshd
tcp 0 0 ::ffff:10.96.20.113:6911 :::* LISTEN 15416/java
tcp 0 0 :::54792 :::* LISTEN 15416/java
tcp 0 0 ::ffff:127.0.0.1:6600 :::* LISTEN 15392/java
udp 0 0 0.0.0.0:631 0.0.0.0:* 1661/cupsd
配置resin支持httpd的多vhosts:
[root@proxy-1-1 apache]# pwd
/usr/local/apache
[root@proxy-1-1 apache]# vim conf/extra/httpd-vhosts.conf
NameVirtualHost *:80
<VirtualHost *:80>
DocumentRoot "/var/www"
DirectoryIndex index.html index.htm index.jsp
ServerName www.test.cc
ErrorLog "logs/www-error_log"
CustomLog "logs/www-access_log" common
<Directory "/var/www">
Options -Indexes +FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
<VirtualHost *:80>
DocumentRoot "/var/blog"
DirectoryIndex index.html index.htm index.jsp
ServerName blog.test.cc
ErrorLog "logs/blog-error_log"
CustomLog "logs/blog-access_log" common
<Directory "/var/blog">
Options -Indexes +FollowSymLinks
AllowOverride None
Order allow,deny
Allow from all
</Directory>
</VirtualHost>
[root@proxy-1-1 apache]# vim conf/httpd.conf
Include conf/extra/httpd-vhosts.conf
LoadModule caucho_module/usr/local/apache/modules/mod_caucho.so
#SetHandler caucho-request
ResinConfigServer 10.96.20.113 6911
ResinConfigServer 10.96.20.113 6912
CauchoConfigCacheDirectory /tmp
CauchoStatus yes
[root@proxy-1-1 apache]# bin/httpd -t -f ./conf/httpd.conf
httpd: Could not reliably determine theserver‘s fully qualified domain name, using 10.96.20.113 for ServerName
Syntax OK
[root@proxy-1-1 apache]# mkdir /var/{www/,blog} -p
[root@proxy-1-1 apache]# echo ‘www.test.cc‘> /var/www/index.html
[root@proxy-1-1 apache]# echo ‘1+1=<%=1+1%>‘ > /var/www/test.jsp
[root@proxy-1-1 apache]# echo ‘blog.test.cc‘ > /var/blog/index.html
[root@proxy-1-1 apache]# echo ‘99+1=<%=99+1%>‘ > /var/blog/test.jsp
[root@proxy-1-1 apache]# killall httpd
[root@proxy-1-1 apache]# bin/httpd -f ./conf/httpd.conf
httpd: Could not reliably determine theserver‘s fully qualified domain name, using 10.96.20.113 for ServerName
[root@proxy-1-1 apache]# cd
[root@proxy-1-1 ~]# vim /usr/local/resin/conf/resin.conf
……
<server id="test1" address=‘10.96.20.113‘ port=‘6911‘watchdog-port=‘6600‘>
<!-- <http address="*" port="8080"/> -->
<jvm-arg>-Xmx256m</jvm-arg>
<jvm-arg>-Xss1m</jvm-arg>
<jvm-arg>-Xdebug</jvm-arg>
<jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>
<memory-free-min>1M</memory-free-min>
<thread-max>256</thread-max>
<socket-timeout>65s</socket-timeout>
<keepalive-max>128</keepalive-max>
<keepalive-timeout>15s</keepalive-timeout>
</server>
<server id="test2" address=‘10.96.20.113‘ port=‘6912‘watchdog-port=‘6601‘>
<!-- <http address="*" port="8081"/> -->
<jvm-arg>-Xmx256m</jvm-arg>
<jvm-arg>-Xss1m</jvm-arg>
<jvm-arg>-Xdebug</jvm-arg>
<jvm-arg>-Dcom.sun.management.jmxremote</jvm-arg>
<memory-free-min>1M</memory-free-min>
<thread-max>256</thread-max>
<socket-timeout>65s</socket-timeout>
<keepalive-max>128</keepalive-max>
<keepalive-timeout>15s</keepalive-timeout>
</server>
……
[root@proxy-1-1 ~]# killall java
[root@proxy-1-1 ~]# cd /usr/local/resin/bin
[root@proxy-1-1 bin]# ./httpd.sh -server test1 start
Resin/resin-3.1.15 started -server ‘test1‘for watchdog at 127.0.0.1:6600
[root@proxy-1-1 bin]# ./httpd.sh -servertest2 start
Resin/resin-3.1.15 started -server ‘test2‘for watchdog at 127.0.0.1:6601
在win上添加HOSTS文件内容:10.96.20.113 www.test.cc blog.test.cc
未完待续
本文出自 “Linux运维重难点学习笔记” 博客,请务必保留此出处http://jowin.blog.51cto.com/10090021/1841523
标签:resin;运维
原文地址:http://jowin.blog.51cto.com/10090021/1841523