sudo的環(huán)境變量獲取
問題描述:
yuyu用戶設(shè)置了自定義的環(huán)境變量,提升到sudo執(zhí)行,無法獲取該環(huán)境變量
解決方法:
在/etc/sudoers.d目錄下添加任意文件,前提是不包括~結(jié)尾和.字符,權(quán)限要設(shè)置成440,具體要求看改目錄下的README文件
文件內(nèi)容Defaults env_keep += "CONFIG_DIR"
以上在yuyu中設(shè)置的變量CONFIG_DIR 就能在sudo中使用
Tomcat6 源碼學(xué)習(xí)
2010-3-29
【tomcat啟動類Bootstrap】
t1.tomcat的人口函數(shù),啟動類
org.apache.catalina.startup. Bootstrap.java Main函數(shù)
t2.Bootstrap類
初始化 ClassLoader, 然后利用 Java Reflection 調(diào)用 Catalina 類來啟動 tomcat server
【tomcat擴展-日志】
a1.private static Log log = LogFactory.getLog(Bootstrap.class);
日志可以定義為private 和static
a2.只在本類中使用的方法,使用private,降低訪問權(quán)限,需要的時候,再考慮重構(gòu)或者提高訪問權(quán)限public
a.日志打印前加if(log.isInfoEnabled())
如果代碼中含有l(wèi)ogger.debug(“string”);此類語句,盡管在log4j.xml配置文件中對該類logger的level為
ERROR,但是仍然會產(chǎn)生較大的內(nèi)存開銷,通常是所要輸出的string的幾十倍甚至上百倍大小,對內(nèi)存開銷非常大。優(yōu)化方法為:使用logger進(jìn)行
判斷。
2010-3-30
【tomcat擴展-classloader】
a3.如果兩個類屬于同一個包下,但是由不同的classloader加載,那么他們也不能互訪default類型方法,屬性
a4.classloader:與C或C++編寫的程序不同,Java程序并不是一個可執(zhí)行文件,而是由許多獨立的類文件組成,每一個文件基本上
對應(yīng)于一個類。此外,這些類文件并非立即全部都裝入內(nèi)存,而是根據(jù)程序需要裝入內(nèi)存。ClassLoader是JVM中將類裝入內(nèi)存的那部分
a5.定制的ClassLoader應(yīng)用:
1.在執(zhí)行非置信代碼之前,自動驗證數(shù)字簽名
2.使用用戶提供的密碼透明地解密代碼
3.動態(tài)地創(chuàng)建符合用戶特定需要的定制化構(gòu)建類
4.任何您認(rèn)為可以生成Java字節(jié)碼的內(nèi)容都可以集成到應(yīng)用程序中
a6.findClass方法是創(chuàng)建定制的ClassLoader時唯一需要覆蓋的方法。
ClassLoader loadClass方法
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
a7.ClassLoader(CCL)的任務(wù)是確保代碼被編譯和更新。
下面描述了它的工作方式:1、當(dāng)請求一個類時,先查看它是否在磁盤的當(dāng)前目錄或相應(yīng)的子目錄。
2、如果該類不存在,但源碼中有,那么調(diào)用Java編譯器來生成類文件。
3、如果該類已存在,檢查它是否比源碼舊。如果是,調(diào)用Java編譯器來重新生成類文件。
4、如果編譯失敗,或者由于其它原因不能從現(xiàn)有的源碼中生成類文件,返回ClassNotFoundException。
5、如果仍然沒有該類,也許它在其它庫中,所以調(diào)用findSystemClass來尋找該類。
6、如果還是沒有,則返回ClassNotFoundException。
7、否則,返回該類。
8、調(diào)用findLoadedClass來查看是否存在已裝入的類。
9、如果沒有,那么采用那種特殊的神奇方式來獲取原始字節(jié)。
10、如果已有原始字節(jié),調(diào)用defineClass將它們轉(zhuǎn)換成Class對象。
11、如果沒有原始字節(jié),然后調(diào)用findSystemClass查看是否從本地文件系統(tǒng)獲取類。
12、如果resolve參數(shù)是true,那么調(diào)用resolveClass解析Class對象。
13、如果還沒有類,返回ClassNotFoundException。
14、否則,將類返回給調(diào)用程序。
【tomcat啟動類classloader】
t3.tomcat自定義了三個類,catalinaLoader commonLoader,sharedLoader
Common - 載入$CATALINA_HOME/common/...它們對TOMCAT和所有的WEB APP都可見
Catalina - 載入$CATALINA_HOME/server/..它們僅對TOMCAT可見,對所有的WEB APP都不可見
Shared-載入$CATALINA_HOME/shared/它們僅對所有WEB APP可見,對TOMCAT不可見(也不必見)
t4.Bootstrap通過反射初始化Catalina類,
反射調(diào)用Catalina方法setParentClassLoader,傳遞SharedClassloader
反射call Catalina方法load 利用server.xml中的配置初始化Service,Server,Engine,Host
反射call Catalina方法start Start the new server 該server是通過
解析xml文件生成的org.apache.catalina.core.StandardServer類
【tomcat-xml解析】
1.Tomcat取了Digester中的interface和幾個Rule,并且自己實現(xiàn)了一些 Rule 來解析xml.
2.tomcat解析xml創(chuàng)建以下幾個類
Server:
org.apache.catalina.core.StandardServer
Resources:
org.apache.catalina.deploy.NamingResources
Server's Listener:( 監(jiān)聽server事件)
org.apache.catalina.core.AprLifecycleListener
org.apache.catalina.core.JasperListener
org.apache.catalina.mbeans.ServerLifecycleListener
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener
Service:
org.apache.catalina.core.StandardService
Executor:
org.apache.catalina.core.StandardThreadExecutor
Engine:
org.apache.catalina.core.StandardEngine
Connector:
org.apache.catalina.connector.Connector
【tomcat-流程】
3.StandardServer啟動StandardService,StandardService啟動Connector,
Connector啟動Http11Protocol,Http11Protocol啟動JIoEndpoint,
JioEndpoint啟動server Socket,listern 8080端口,處理http請求
4.Http11Processor
Processes HTTP requests.
由http11ConnectionHandler調(diào)用,Http11ConnectionHandler由JioEndpoint中的Work
調(diào)用
5.A connector passes the request and reponse objects to the
Container by calling the Container interface's invoke method
public void invoke(Request request, Response response)
throws IOException, ServletException;
inside the invoke method ,the container loads the servlet class,call
its sevice method ,manage sessions,etc.
6.Connector 方法initialize中
// Initializa adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
adapter通過protocolHandler(Http11Protocol)傳給Http11Processor,
Http11Processor解析,create request和response,通過adapter傳送給Container
7.Tomcat使用Pipeline模式在各層容器間傳遞請求,將請求通過管道依次通過Engine,Host,Context和
Wrapper。另外,每一個容器
都可以設(shè)置一系列的Valve去對請求進(jìn)行攔 截,就像管道中的閥一樣對請求的行為進(jìn)行一些干涉。
2010-3-31
【tomcat-流程】
1.tomcat的pipeline/valve是標(biāo)準(zhǔn)的責(zé)任鏈模式,每個級別的容器中pipeline所有的valve都完成動作后會將
request/response傳到下一個容器的pipeline中的valve,
這樣一直傳遞下去直到Wrapper的BaseValve.
Ps:每個容器的BaseValve會調(diào)用下個容器的起始valve
2.StandardEngine
屬性Pipeline pipeline = new StandardPipeline(this);
構(gòu)造函數(shù)里會設(shè)置最底層的閥門
pipeline.setBasic(new StandardEngineValve());
如果需要設(shè)置新閥門處理需求,只需要調(diào)用 pipeline.addValve(Valve valve);
3.CoyoteAdapter中會執(zhí)行
connector.getContainer().getPipeline().getFirst().invoke(request,
response);
該行代碼會一層一層調(diào)用添加的閥門,處理下去.
2010-4-1
【tomcat-流程】
1.jk插件負(fù)責(zé)tomcat和其它http容器進(jìn)行通信
2.連接器協(xié)議AJP/1.3是tomcat用來與其它http容器進(jìn)行連接的協(xié)議
3.把指定Context的classloader付給當(dāng)前線程。
Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());
這樣request就只看見指定的context下面的classes和jar包,而看不見tomcat本身的類。
2010-4-7
【tomcat-socke與worker線程】
/**
* Process an incoming TCP/IP connection on the specified socket.
Any
* exception that occurs during processing must be logged and
swallowed.
* <b>NOTE</b>: This method is called from our
Connector's thread. We
* must assign it to our own thread so that multiple simultaneous
* requests can be handled.
* @param socket TCP socket to process
*/
synchronized void assign(Socket socket) {
// Wait for the Processor to get the previous Socket
while (available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Store the newly available Socket and notify our thread
this.socket = socket;
available = true;
notifyAll();
}
/**
* Await a newly assigned Socket from our Connector, or
<code>null</code
* if we are supposed to shut down.
*/
private synchronized Socket await() {
// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
// Notify the Connector that we have received this Socket
Socket socket = this.socket;
available = false;
notifyAll();
return (socket);
}
連接器線程調(diào)用worker類的assign類,worker類的執(zhí)行線程run方法會調(diào)用await方法獲取socket,通過
available變量的設(shè)置和wait/notify方法來協(xié)調(diào)彼此的操作。當(dāng)連接器線程未傳輸socket,worker類線程就執(zhí)行wait等待,
當(dāng)worker類執(zhí)行線程在處理忙的時候,連接器線程wait。
svn命令行操作
1.svn update 更新 (簡寫up)
svn update -r 500 test.java(將版本庫中的文件test.java還原到版本500)
2.svn commit -m"u" (簡寫ci)
提交變更的文件
3.查看文件信息svn info path
查看文件內(nèi)容svn cat path
4.svn status path
會目錄下的文件和子目錄的狀態(tài),正常狀態(tài)的則不顯示,很正常,不然在項目根目錄執(zhí)行,將會羅列出一大堆文件了
顯示的狀態(tài)信息中?:表示不在svn的控制中 M:表示本地文件被修改過
C:表示本地文件與服務(wù)器文件發(fā)生沖突(如果不帶-u選項,即時沖突也不會顯示) A:表示預(yù)定要加入到版本庫 K:表示被鎖定
'!' 表示丟失,一般是將受控文件直接刪除導(dǎo)致
svn st -u path -u選項表示不僅僅本地,服務(wù)器上的變更也將會顯示
5.刪除文件
svn delete test.java 然后再svn ci -m 'delete‘,將在本地和服務(wù)器上都刪除該文件
6. 添加新文件
svn add test.java(添加test.java) 然后再svn ci -m"add",將再服務(wù)器上添加該文件
如果不執(zhí)行commit操作,服務(wù)器上將不會添加
7.svn: Commit failed (details follow):
svn: Directory '/home/yuyu/f/workspace/ouyu/WebRoot/WEB-INF/classes'
is missing
解決方法:svn update /home/yuyu/f/workspace/ouyu/WebRoot/WEB-INF/classes
8. 服務(wù)器覆蓋本地文件
執(zhí)行svn revert test.java命令撤銷自己的修改,再執(zhí)行update,
則服務(wù)器的文件會覆蓋自己修改的文件。
9.svn list path(or url)
顯示目標(biāo)下的文件和目錄列表。
10.svn diff
svn diff path 查看文件的不同處(本地版本的變更比較)
svn diff -r n1:n2 path n1和n2版本的同一文件比較
11. 發(fā)生沖突
執(zhí)行svn update后會緊跟選擇性操作,一種直接選擇解決,修改文件;
一種選擇推遲解決,則之后需要執(zhí)行svn resolved test.java,才能最終commit