天天看點

III 19 resin(1)

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設定);

<a href="http://s2.51cto.com/wyfs02/M00/86/53/wKiom1e78cqggkP_AACGjj17DqQ008.jpg" target="_blank"></a>

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 &lt;path&gt; ] [ -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:&lt;protocol&gt;://...)

 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 -&gt;/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 -&gt;/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' -&gt; `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   (将&lt;server-default&gt;……&lt;/server-default&gt;段删除,常用的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)

    &lt;server id="test"address='10.96.20.113' port='6911' watchdog-port='6600'&gt;

      &lt;http address="*"port="8080"/&gt; 

      &lt;jvm-arg&gt;-Xmx256m&lt;/jvm-arg&gt;

      &lt;jvm-arg&gt;-Xss1m&lt;/jvm-arg&gt;  

      &lt;jvm-arg&gt;-Xdebug&lt;/jvm-arg&gt;  

     &lt;jvm-arg&gt;-Dcom.sun.management.jmxremote&lt;/jvm-arg&gt;

     &lt;memory-free-min&gt;1M&lt;/memory-free-min&gt;   &lt;!--Configures the minimum free memoryallowed before Resin will force a restart,當jvm的記憶體小于此處指定的值,resin服務會gracefully重新開機,來釋放洩露的記憶體空間--&gt;

      &lt;thread-max&gt;256&lt;/thread-max&gt;   &lt;!--Maximum number of threads,并發數,幾百到一千即可,taobao優化到1500--&gt;

      &lt;socket-timeout&gt;65s&lt;/socket-timeout&gt;  &lt;!--Configures the sockettimeout,讀寫socket最大逾時時間--&gt;

      &lt;keepalive-max&gt;128&lt;/keepalive-max&gt;  &lt;!--Configures the keepalive,最多長連接配接數--&gt;

      &lt;keepalive-timeout&gt;15s&lt;/keepalive-timeout&gt;   &lt;!--長連接配接逾時時間--&gt;

    &lt;/server&gt;

[root@proxy-1-1 resin]# cd webapps/ROOT/   #(預設站點目錄)

[root@proxy-1-1 ROOT]# ls

index.jsp

[root@proxy-1-1 ROOT]# echo '1+1=&lt;%=1+1%&gt;' &gt; 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

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      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

<a href="http://s3.51cto.com/wyfs02/M00/86/52/wKioL1e78iuSMWqQAACAuE3epnY571.jpg" target="_blank"></a>

<a href="http://s5.51cto.com/wyfs02/M01/86/52/wKioL1e78jeB7tJfAAA-XoJwxDE904.jpg" target="_blank"></a>

案例(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 &amp;&amp; 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 &amp;&amp; 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 &amp;&amp; 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 &amp;&amp; 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

&lt;/IfModule&gt;

#

# 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

#SetHandlercaucho-request

ResinConfigServer 10.96.20.113 6911

[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處理動态内容,實作動靜分離)

      &lt;!-- &lt;http address="*"port="8080"/&gt; --&gt;

[root@proxy-1-1 bin]# service resindrestart

[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    

<a href="http://s3.51cto.com/wyfs02/M01/86/53/wKiom1e78qDTDn2nAAA7cdOzs_8854.jpg" target="_blank"></a>

配置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

&lt;VirtualHost *:80&gt;

   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

   &lt;Directory "/var/www"&gt;

       Options -Indexes +FollowSymLinks

       AllowOverride None

       Order   allow,deny

       Allow from all

   &lt;/Directory&gt;

&lt;/VirtualHost&gt;

   DocumentRoot "/var/blog"

   ServerName blog.test.cc

   ErrorLog "logs/blog-error_log"

   CustomLog "logs/blog-access_log" common

   &lt;Directory "/var/blog"&gt;

[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 6912

CauchoConfigCacheDirectory /tmp

[root@proxy-1-1 apache]# bin/httpd -t -f ./conf/httpd.conf

Syntax OK

[root@proxy-1-1 apache]# mkdir /var/{www/,blog} -p

[root@proxy-1-1 apache]# echo 'www.test.cc'&gt; /var/www/index.html

[root@proxy-1-1 apache]# echo '1+1=&lt;%=1+1%&gt;' &gt; /var/www/test.jsp

[root@proxy-1-1 apache]# echo 'blog.test.cc' &gt; /var/blog/index.html

[root@proxy-1-1 apache]# echo '99+1=&lt;%=99+1%&gt;' &gt; /var/blog/test.jsp

[root@proxy-1-1 apache]# killall httpd

[root@proxy-1-1 apache]# bin/httpd -f ./conf/httpd.conf

[root@proxy-1-1 apache]# cd

[root@proxy-1-1 ~]# vim /usr/local/resin/conf/resin.conf

   &lt;server id="test1" address='10.96.20.113' port='6911'watchdog-port='6600'&gt;

     &lt;!-- &lt;http address="*" port="8080"/&gt; --&gt;

     &lt;jvm-arg&gt;-Xmx256m&lt;/jvm-arg&gt;

     &lt;jvm-arg&gt;-Xss1m&lt;/jvm-arg&gt;

     &lt;jvm-arg&gt;-Xdebug&lt;/jvm-arg&gt;

     &lt;memory-free-min&gt;1M&lt;/memory-free-min&gt;

     &lt;thread-max&gt;256&lt;/thread-max&gt;

     &lt;socket-timeout&gt;65s&lt;/socket-timeout&gt;

     &lt;keepalive-max&gt;128&lt;/keepalive-max&gt;

     &lt;keepalive-timeout&gt;15s&lt;/keepalive-timeout&gt;

   &lt;/server&gt;

   &lt;server id="test2" address='10.96.20.113' port='6912'watchdog-port='6601'&gt;

     &lt;!-- &lt;http address="*" port="8081"/&gt; --&gt;

[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

<a href="http://s2.51cto.com/wyfs02/M01/86/53/wKioL1e78yXjeUkaAAA9FFmrPWk382.jpg" target="_blank"></a>

<a href="http://s4.51cto.com/wyfs02/M02/86/53/wKioL1e78zSCLDUaAAA_GXAaxNs317.jpg" target="_blank"></a>

<a href="http://s5.51cto.com/wyfs02/M01/86/53/wKiom1e780SgDCaIAABvANe-JIo264.jpg" target="_blank"></a>

本文轉自 chaijowin 51CTO部落格,原文連結:http://blog.51cto.com/jowin/1841523,如需轉載請自行聯系原作者