qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          從Unix到Linux的遷移部署:移植、升級和測試

           從Unix遷移到Linux,在最初階段,應該建立一個沙盤環境用于測試。也許您的整個團隊都沒有Linux方面的經驗,有這樣一個沙盤環境能幫上大忙(無需擔心任何風險)。

            有關代碼和編譯的問題。你正在使用JAVA還是C?是否有第三方應用需要遷移?這些第三方軟件能移植到Linux上嗎?

            假設您正在使用C語言。假設您將會在Linux上編譯代碼。如果使用GNU(gcc)編譯器,因為這是工業標準,而且這是Linux自己的編譯器。那么所有在其它平臺上編譯過的應用程序都需要重新編譯。

            對于編譯,有兩種方法供您使用。一個方法是在現有環境上重新編譯您的程序,這種情況下,您必須確保在這個環境下有您需要的所有工具,其中包括源代碼和生成文件。如果您想使用這個方法,請在您的測試環境中進行,永遠不要在生產環境中實施。

            另一種方法是把所有數據和代碼移植到新環境上,并且測試他們。同時,要測試一下硬件平臺。如果您計劃更新硬件平臺,一些有關硬件的代碼可能會給你制造些麻煩,最糟糕的情況是,您可能不得不重寫所有代碼。

            確保開發人員參與進來,不要假設任何事情。需要認真考慮的事情包括運行時API、系統調用、流和庫的支持。確保您完全理解所要移植的內容。這時候你需要評估和核實所有的事情,如應用程序及其庫文件和依賴性。您能快速確定產品是否能在Linux上運行和在哪里運行。

            毫無疑問,Java程序比C語言程序能更快地移植。此外,在移植過程中,您還需要核實測試環境、用戶界面需求、平臺可靠性限制、中間件產品和內部技能水平。每一個環境不仔細都可能在未來給您帶來麻煩。

            應用程序升級

            應用程序是移植過程中最重要的一塊。在某些情況下,您的應用程序可以直接被移植,但是這種情況很少發生。另一種情況是,您必須在新平臺上重新編譯它們。移植和編譯過程都不復雜,然后需要做的就是測試以確認一切OK。

            應用程序的移植過程應該包括開發和測試。在進行移植的時候,您必須有可靠的辦法來保證您的數據庫正確移植。另外,應用程序所要求的內核擴展和準備驅動,在新的平臺上并不一定能夠得到滿足,因為大多數的內核API并不嚴格遵循標準。

            應用程序是否正在使用第三方組件,如數據庫工具、應用服務器或其它中間件呢?如果是,這會增加移植的復雜性。應用程序是32位還是64位?如果是從32位移植到64為,您將不得不付出更多的時間。應用程序如何和數據庫通信呢?它們使用數據庫接口嗎,如ODBC或者編程語言,如C++?這些方面您都需要認真考慮。從人工的角度來講,盡可能的讓那些有各種移植項目經歷的人加入您的團隊。

            穩定性和性能評測

            通常在最初的幾周內,各種應用程序問題會陸續出現,工程師們會第一時間想辦法來解決它們。這時候您可能想重新審視您的項目計劃并調整交貨時間。

            測試應用的穩定、功能和性能非常關鍵。與其花費200萬美元開發新系統,還不如花費2000美元測試。測試的順序通常如下:

            遷移工程師對于需要移植的應用程序進行模塊測試。

            應用工程師執行功能性測試。

            用戶驗收測試(UAT)。該階段實際的商業用戶進行測試。

            性能工程師進行性能測試

            在測試過程中,對要遷移的應用程序進行壓力測試不可缺少,這樣能確保新系統能夠應付各種負載。此時,您應該已經完成了基本的測試,并且對于舊環境和新環下的應用程序性能,您該心中有數。

            對于穩定性和性能,也需要進行類似的測試。嘗試擊敗你的系統。使用諸如惠普LoadRunner等工具來模擬正常量5倍的負載。

            現在是時候來發現Bug了,當然這不是在生產環境上。在進入生產環境之前,您就有機會調試問題。利用測試,不要讓使用系統的人來核實是否有問題。業務內容也必須涉及,而且應該有獨立的UAT計劃。如果您的系統在舊環境上有很高的可用性,那么在新環境下,必須測試高可用性是否繼續有效。

          posted @ 2011-12-23 14:42 順其自然EVO 閱讀(147) | 評論 (0)編輯 收藏

          開發效率與系統穩定性雜談

          互聯網系統中,開發效率與系統穩定性與產品成敗非常相關。開發效率在一定程度反映了團隊的執行力,快速開發能力帶來了產品的競爭優勢。系統穩定性(包括安全及性能等)則是產品的后防線,稍有失誤則會給產品帶來很大傷害。因此開發效率與系統穩定性是衡量互聯網系統開發成熟度最重要的兩個指標。

            在軟件開發周期不同階段,這兩者如何控制?

            在需求階段,對開發效率的影響常見的是溝通理解偏差帶來的技術風險,之外最常見的還有需求變更的風險。后者大多是來自市場環境的變化作出調整,技術主管更多的是積極心態去應對。但對前者溝通理解偏差導致效率問題也不罕見,更值得警惕。

            在技術設計階段最大的風險是技術方案,找個無需多講,考驗團隊的架構能力以及對當前系統的駕馭程度。

            開發階段最大的風險是單元測試不到位或缺失。很多號稱“敏捷”型項目依賴在線上測試及修改,當模塊增多后,這樣代碼健壯性就會變得比較脆弱,不少團隊也會越走越慢。

            Review階段風險是簡潔性及性能。除了壓力測試能達標之外,警惕那些不易懂的代碼,這些代碼將來會成為事故多發地帶。

            部署階段最大的風險是上線計劃把控,上線過程中操作錯誤的情況并不罕見,如去年Amazon EC2的故障就是由于操作失誤造成。

            從宏觀看來,技術方案的風險最大,由于模塊很多,具有豐富經驗的高手不可能參與每一個環節,這就會出現木桶的短板效應,架構師認為不重要的地方總是會出問題。給用戶體驗造成極大傷害。

            另外還有團隊文化的風險。大部分團隊很難形成書面交流的習慣。口頭溝通需求、討論方案對創業團隊非常適合。在團隊變大之后,這樣的習慣會造成信息流動障礙,可能會給工作效率帶來更多負面問題。同時大部分團隊也對流程、模板、規范缺乏了解與重視,過多依賴參與人的內部驅動力及能力,無法依靠制度與流程來取勝。

          posted @ 2011-12-23 14:37 順其自然EVO 閱讀(166) | 評論 (0)編輯 收藏

          從武俠門派的角度去解釋域、域樹、林的含義

          從武俠門派的角度去解釋域、域樹、林的含義

            一直以來都想寫一些關于活動目錄技術的文章,但是一直沒有一個好的切入點。有一天在博客專題中亂轉,發現了宋楊的一篇老博文《省錢之道--圖解域域樹域林根域的含義》看了以后覺得不錯。但是也有點想法。我不敢妄自評判文章的好壞,只是想有沒有更通俗的解法來描述這些抽象、專業的概念呢?于是想到了我從小很喜歡的武俠小說,突然發現,原來這些東西就溶于我們的生活之中呀。廢話少說,開始正文。

            自從WINDOWS 98系統出現之后,WINDOWS操作系統就不是孤立存在的,可以通過網絡聯機相互聯系。當然,除非你只有一臺計算機。默認安裝的WINDOWS操作系統是以工作組模式運行。當然WINDOWS聯機的模式只有兩種:域模式和工作組模式。

            一、工作組

            很多專業的描述是工作組模式是由相互獨立的計算機組成。他們再網絡中的地位平等,各自獨立、分散的維護和管理著自身。這個較抽象的描述是可以宏觀表述的,看。在武俠世界里就體現著。就是金庸武俠小說中《笑傲江湖》里面五岳劍派。

          (圖1)

            五岳劍派最初是由上圖的五個門派組成的。最初的目的是為了團結起來對抗少林,武當,日月神教等大派。五岳劍派由嵩山左冷禪提議組建,最后華山岳不群當上所謂的盟主。實際上這五個門派就組成了一個工作組。

            由5臺計算機(五個門派)組成的一個工作組

            工作組(workgroup)=五岳劍派

            為什么是工作組呢?原來雖然這五個門派組成了所謂的五岳劍派,也有了所謂的盟主。但是五岳劍派實際上仍然是各自為政。比如恒山派掌門令狐沖(相當于華山這臺機器的本地管理員)恒山派弟子(本地用戶)的創建(招弟子)刪除(逐出弟子)等問題仍然由令狐沖說的算,根本就不理睬盟主號令。另外恒山弟子(本地用戶)也聽令狐沖的號令。頂多是由嵩山派弟子來訪(相當于來共享一個資源給他們訪問)或者華山派被人揍了,請求恒山支援(可以想象成另一種資源的共享方式)。

            二、域

            什么是域?就是把我們企業IT環境中的所有資源在邏輯上進行統一集中管理的一種手段。還有什么邏輯組織最小單元呀,什么安全邊界了,有點抽象了。好吧,我告訴你,域就是一個門派:就是少林,就是武當,就是明教。(以下所有以明教舉例)明教就是宏觀存在的邏輯組織,明教教眾在明教教主的帶領下進行轟轟烈烈的革命。

            關于域名和DNS命令等問題在這里不介紹了,估計比較容易明白。


          (圖2)

          看圖2當看到mingjiao.com這個表示一個單域的時候,你就可以想到明教。

          (圖3)

            請大家認真看圖3,我來解釋一下這張圖。域的實體是由計算機和人員組成的。我們先看幾個轉化公式

            明教教主=域管理員

            明教弟子=域用戶

            加入域的成員計算機=丁家大院

            加入域的成員服務器=明教錢莊

            域控制器(DC)=光明頂

            在域中要添加用戶賬戶,就是域賬戶。而這里普通域用戶賬戶就相當于明教弟子。

            在域中計算機分別擔任三種角色。

            第一種,是安裝WINDOWS操作系統的計算機。比如WIN XP和WIN 7。加入域后這種計算機叫成員計算機。在這里我們可以想象明教是一個大派,全國各地都有人有地盤。由于我們是人去操作計算機,所以這里的計算機就可以想象成一個地盤(一個具體的實物,比如房屋)我這里叫做丁家大院。等于丁家大院就是明教的產業了。默認情況下,任何明教弟子(普通域用戶)在登錄驗證后都可以進入丁家大院了。可以在里面休息,下棋等。(訪問資源)不過名教弟子畢竟不是丁家大院的所有者.所以不可以拆墻,建樓等行為(相對修改計算機系統) 那么誰是丁家大院的所有者呢? 有兩個.一個就是原丁家大院的主人(本地管理員),一個就是明教教主(域管理員)想想都是明教的產業了,當然是所有者了。當然假如有一天丁家大院不再是明教的產業了. 被變賣了.這個行為就相當于WINDOWS計算機退出域.只有上面的2個所有者有這個能力.當然明教教主(域管理員)可以委派一個明教弟子(域用戶)成為丁家大院主人(本地管理員)

            第二種,是安裝WINDOWS SERVER操作系統的計算機.比如WIN 2003 SERVER 、WIN2008 SERVER。加入域的這類計算機叫成員服務器。同樣,這種機器也相當于明教的一個地盤或者叫產業。與上面相同的是,這個產業也有主人(本地管理員)。明教弟子(域普通用戶)也可以進入這個產業(登錄到該機器上)但是也有不同的,服務器一般都是提供共享資源應用的服務器。比如做一個文件服務器,一個WEB服務器。所以這個產業中存放的是域用戶的共用資源,在這里相當于明教的一個錢莊(明教弟子把錢都放在這里,可以存取)

            第三種,是安裝WINDOWS SERVER操作系統的計算機安裝了AD(活動目錄)這時候這臺計算機就成了域控制器。活動目錄是什么?活動目錄就相當于一個數據庫,一個明教的賬本。這個賬本記錄了哪些是明教的產業(加入域的計算機)誰是明教弟子(域用戶賬戶)甚至還有 明教錢莊的錢(共享資源)等。所以域控制器就相當于明教之圣地-光明頂。每一個加入明教的弟子(新建用戶)每一個歸入明教的產業(加入成員計算機)都要到光明頂的賬本中登記(記錄到活動目錄中)不過,光明頂與上面的丁家大院與明教錢莊不同。光明頂不歸入明教的產業,也就沒有主人(本地賬戶)其次光明頂是神圣的地方,一般明教弟子是不準進入的(默認域用戶無法登陸到域控中)當然,明教教主(域管理員)是可以進去,管理這個賬本(活動目錄)。也可以修改這個條例(修改默認域控策略)允許指定的明教弟子進入(登陸域控)。

            好了,上面的圖解釋完了,下面解釋一個比較重要的問題。域用戶登陸域的問題。

            其實就好比明教弟子要進入自己的地盤一樣。首先你是明教弟子(擁有域用戶賬號),其次你進入的是明教的地盤或叫產業(加入域的計算機)。否則,一個明教弟子跑到少林寺去非要進人家的藏經閣(非明教的產業)不被打出來才怪呢。再者你說你是明教弟子,你就是明教弟子了?別著急,明教有驗證的辦法。比如明教弟子王小五,要進入丁家大院。(用戶王小五,要利用成員計算機登陸到域)首先報告給大院管家(計算機系統)大院管家收到信息后無法驗證,這個時候把這個信息飛鴿傳書到光明頂(域控制器)光明頂管家(DC計算機系統)查看賬本(活動目錄)驗證是否存在此人,確認后飛鴿傳書一個腰牌給王小五。從此王小五就可以進入到丁家大院了。這個腰牌上面有一個特殊的信息,就是標明了王小五的身份,王小五在丁家大院能干什么不能干什么就靠這個了。當然王小五拿這個腰牌也可以直接在去明教錢莊。拿屬于自己的錢(授權訪問的資源)如果王小五出了明教的地盤(退出登錄,注銷等)腰牌自動收回。

            當然這個過程有一個關鍵,就是如果丁家大院與光明頂在飛鴿傳書的過程中不順利,比如鴿子沒找到路,(相當于成員計算機無法找到域控)要么王小五就不能進丁家大院了。不過俗話說,一回生,二回熟。當王小五第二次進丁家大院的時候,會發生一點點變化。假如還是上面的過程,飛鴿傳書換腰牌,但是沒成功,但是王小五因為上次進了丁家大院,在六角亭擺了一牌棋自己和自己下,沒下完就走了。這次王小五告訴丁家大院管家(計算機系統)他上面在哪牌棋,多少子,棋局如何。。管家一看,對呀。他是明教弟子,進來吧。(這就是利用當域控無法聯系,但是用戶之前登陸過,利用緩存憑證來登陸)有一個叫王小六的弟子是第一次進丁家大院,那么因為沒有留下什么東西,誰也不知道他這鳥是不是明教弟子,自然無法進丁家大院(無法登陸)

          posted @ 2011-12-22 11:14 順其自然EVO 閱讀(167) | 評論 (0)編輯 收藏

          Java精確截取字符串

           Java精確截取字符串,取得字符串前面指定長度字符函數

            用java取得字符串的前面部分內容的函數contentStr = contenttemp.substring(0, 150);其中要保證最大長度不能超過字符串的長度。下面是我的實現部分代碼,以及網上搜索的相關代碼:

        1. /* 
        2. * content內容過長可能會導致xml文件過大,加載太慢。 
        3. * 但從seo的角度考慮全部輸出有利于搜索引擎,但一般情況下內容也不會太多 
        4. * 為防止空格換行css無法控制撐大頁面,用正則表達式替換掉空格,所以截取前面100個字符,頁面顯示的內容多少用css控制 
        5.  *zdz的作品,流風的作品 
        6. */ 
        7. //str.trim().replaceAll("\\s+"," ");  
        8. String contenttemp = rs.getString(contentName).trim().replaceAll("\\s+","");  
        9. //NpfDebug.print(contenttemp.length()); 
        10. if(contenttemp.length()>100){//如果長度大于100則截取 
        11.  contenttemp = contenttemp.substring(0100);  
        12.  //NpfDebug.print("contenttemp.length()>100 ? "+contenttemp.length()+"\n"+contentStr); 
        13. }  
        14. rsbody.append(beforCONTENT);  
        15. rsbody.append(contenttemp);  
        16. rsbody.append(endCONTENT);
        17.   開發中經常遇到,字符串過長,無法完全顯示的問題

            這時候就需要截取我們所需要的長度,后面顯示省略號或其他字符。

            由于中文字符占兩個字節,而英文字符占用一個字節,所以,單純地判斷字符數,效果往往不盡如人意

            下面的方法通過判斷字符的類型來進行截取,效果還算可以:)

            如果大家有其他的解決方法歡迎貼出來,共同學習:)

        18. private String str;  
        19. private int counterOfDoubleByte;  
        20. private byte b[];  
        21. /** 
        22. * 設置需要被限制長度的字符串 
        23. * @param str 需要被限制長度的字符串 
        24. */ 
        25. public void setLimitLengthString(String str){  
        26.    this.str = str;  
        27. }  
        28. /** 
        29. * @param len 需要顯示的長度(<font color="red">注意:長度是以byte為單位的,一個漢字是2個byte</font>) 
        30. * @param symbol 用于表示省略的信息的字符,如“...”,“>>>”等。 
        31. * @return 返回處理后的字符串 
        32. */ 
        33. public String getLimitLengthString(int len, String symbol) throws UnsupportedEncodingException {  
        34.    counterOfDoubleByte = 0;  
        35.    b = str.getBytes("GBK");  
        36.    if(b.length <= len)  
        37.      return str;  
        38.    for(int i = 0; i < len; i++){  
        39.      if(b[i] < 0)  
        40.        counterOfDoubleByte++;  
        41.    }  
        42.    if(counterOfDoubleByte % 2 == 0)  
        43.      return new String(b, 0, len, "GBK") + symbol;  
        44.    else 
        45.      return new String(b, 0, len - 1"GBK") + symbol;  
        46. }  
        47.    
        48.    
        49.    
        50. -------------------  
        51.    
        52. /** *//** 
        53.     * 按字節長度截取字符串 
        54.     * @param str 將要截取的字符串參數 
        55.     * @param toCount 截取的字節長度 
        56.     * @param more 字符串末尾補上的字符串 
        57.     * @return 返回截取后的字符串 
        58.     */ 
        59.    public String substring(String str, int toCount, String more) ...{  
        60.      int reInt = 0;  
        61.      String reStr = "";  
        62.      if (str == null)  
        63.        return "";  
        64.      char[] tempChar = str.toCharArray();  
        65.      for (int kk = 0; (kk < tempChar.length && toCount > reInt); kk++) ...{  
        66.        String s1 = str.valueOf(tempChar[kk]);  
        67.        byte[] b = s1.getBytes();  
        68.        reInt += b.length;  
        69.        reStr += tempChar[kk];  
        70.      }  
        71.      if (toCount == reInt || (toCount == reInt - 1))  
        72.        reStr += more;  
        73.      return reStr;  
        74.    }  
        75.    
        76. =================  
        77.    
        78. /** 
        79.      * 取字符串的前toCount個字符 
        80.      * 
        81.      * @param str 被處理字符串 
        82.      * @param toCount 截取長度 
        83.      * @param more 后綴字符串 
        84.      * @version 2004.11.24 
        85.      * @author zhulx 
        86.      * @return String 
        87.      */ 
        88.     public static String substring(String str, int toCount,String more)  
        89.     {  
        90.       int reInt = 0;  
        91.       String reStr = "";  
        92.       if (str == null)  
        93.         return "";  
        94.       char[] tempChar = str.toCharArray();  
        95.       for (int kk = 0; (kk < tempChar.length && toCount > reInt); kk++) {  
        96.         String s1 = str.valueOf(tempChar[kk]);  
        97.         byte[] b = s1.getBytes();  
        98.         reInt += b.length;  
        99.         reStr += tempChar[kk];  
        100.       }  
        101.       if (toCount == reInt || (toCount == reInt - 1))  
        102.         reStr += more;  
        103.       return reStr;  
        104.     }
        105.   得到字符串真實長度和取固定長度的字符串函數

        106. // 截取固定長度子字符串 sSource為字符串iLen為長度  
        107. function getInterceptedStr(sSource, iLen)   
        108. {   
        109.     if(sSource.replace(/[^\x00-\xff]/g,"xx").length <= iLen)   
        110.     {   
        111.         return sSource;   
        112.     }   
        113.     var ELIDED = "";   
        114.        
        115.     var str = "";   
        116.     var l = 0;   
        117.     var schar;   
        118.     for(var i=0; schar=sSource.charAt(i); i++)   
        119.     {   
        120.         str += schar;   
        121.         l += (schar.match(/[^\x00-\xff]/) != null ? 2 : 1);   
        122.         if(l >= iLen - ELIDED.length)   
        123.         {   
        124.             break;   
        125.         }   
        126.     }   
        127.     str += ELIDED;   
        128.        
        129.     return str;   
        130. }
        131. posted @ 2011-12-22 11:12 順其自然EVO 閱讀(308) | 評論 (0)編輯 收藏

          MySQL支撐百萬級流量高并發的網站部署詳解

           MySQL支撐百萬級流量高并發的網站的部署方法是本文我們主要要介紹的內容,了解了這部分內容我們自己就能用MySQL來支撐百萬級流量高并發的網站了,接下來我們就開始介紹這部分內容。

            1、MySQL服務器集群

            由于是小公司在資金和成本上都有所限制,而且在技術上也沒有幾個技術員接觸過,所以這個方法自然就讓大伙否決了。

            這里說說我個人的理解!做集群不但添加資費的開銷,而且在技術上也有很大的挑戰,對于我們公司目前的情況是不大現實的。集群無非就是把一臺服務器的壓力轉接到兩臺或是多臺服務器上,我是這么理解的,也許我理解有誤,還請大家指教。

            2、分而治之

            這個方法和集群差不多,不過是把統計的代碼放在不同的服務器上跑,由于公司有不少配置低的服務器跑幾萬到幾十萬IP還是沒有問題的,我們可以把幾百萬流量分成十來個幾十萬的量分而統計。

            優點:充分的利用了現在的資源,解決了目前的問題。

            缺點:這樣的方法不是長久之計,遲早還是會出問題的。而且在統計數據的時候比較麻煩。

            3、統計代碼的修改

            由于之前采用的是在插入數據之前加以判斷,這個IP是否存在,來路等的處理,無形中增加了服務器的壓力,所以大伙把統計代碼改成來一個就插入數據庫,不管三七二十一等以后在處理。

            這個方法基本上把當天的數據保留下來了,可是在處理的時候由于數據量的龐大,來來回回還是把服務器跑死了,而且在插入的時候由于當時設計數據結構的時候留有的索引,也大大的消耗了不少的服務器資源。

            那么把索引去掉到最后處理的時候又是老慢的,得不償失。

            4、統計方式的修改

            最后這一個方法,效果非常的明顯。那是什么方法呢!

            這里就主要介紹這個方法:

            A、保留原用的數據結構不變,并把所有的數據按一定的結構存入文件

            結構:可以是xml,json,也可以是你自己想的任何有規律的數據排放。

            例如:

            1)221.2.70.52,http://www.baidu.com,windowxp\r\n

            2)221.2.70.52,http://www.baidu.com,windowxp\r\n

            寫入文件:fopen,fwrite??no 這里介紹一個非常好用的技巧,也許大家都知道,但是像我這樣的菜鳥大概都不知道,那就是用error_log,這不是寫錯誤日志的嗎?對就是他,非常方便。

            格式:

            1 error_log("內容", 3, "/date.dat");

            這里我就不說他的具體用了,不明白的朋友可以查一下手冊。

           B、數據文件的命名

            為什么這里要講文件的命名呢?如果就一味的把數據的寫入文件不作任何的處理那么他和直接插入數據庫有多大的區別呢?那么我們所作的一切都是無用功了。

            首先是在時間的利用上:date(‘YmdH’)得到的值是如:2008121112這有什么好入,這樣一來這個數據就是一個小時一個文件必免了文件過大,而且不用去判斷自動生成。

            IP的應用:由于在很多數據上都是一個IP操作的,所以把相同IP的數據放在一個文件里在后面的處理就非常方便處理。請看后面的介紹,這里我們取IP成三位為文件名字的一部分。

            C、數據的導入處理

            通過以上兩位的操作當天的數據會一個不少的保留下來,接下來怎么處理其實并不是很重要了。但是這里還是講講我的想法。

            入庫前處理:

            前面講到把IP三位相同的放一個文件就是為了入庫前到它們進行處理,首先可以用最笨的方法把數據拆成N個數據。在進行重復數據的刪除。

            如果一個IP瀏覽多頁那么PV在這里就可以得到統計,并把訪問的頁面進行處理,組成新的數據。

            導入方法:

            這里要介紹一下數據的導入方法:1 $sql="LOAD DATA INFILE '".$file."' INTO TABLE `test` FIELDS TERMINATED BY ', ' LINES TERMINATED BY '\r\n'(2 3 `time` , `md5`4 5 )";就這一個語句,在導入幾十萬數據的時候可以說是十分快速的,用法我這里也不過多介紹了,大家有不明白的可以查手冊,所以說解決數據庫的瓶頸的辦法不定要加設備,也不一定要換數據庫,只要換一個思路就能解決不少問題。

            以上就是MySQL支撐百萬級流量高并發的網站的部署方法,本文就介紹到這里了,希望本次的介紹能夠對您有所收獲!

          posted @ 2011-12-21 12:01 順其自然EVO 閱讀(261) | 評論 (0)編輯 收藏

          如何檢查MySQL數據庫的主從延時?

           MySQL數據庫主從延時如何去判斷呢?本文我們介紹了兩種判斷方法:1. Seconds_Behind_Master vs 2. mk-heartbeat,接下來我們就分別介紹這些內容。

            日常工作中,對于MySQL主從復制檢查,一方面我們要保證復制的整體結構是否正常,另一方面需要檢查主從數據是否保持一致。對于前者我們可以通過監控復制線程是否工作正常以及主從延時是否在容忍范圍內,對于后者則可以通過分別校驗主從表中數據的md5碼是否一致,來保證數據一致,可以使用Maatkit工具包中的mk-table- checksum工具去檢查。

            方法1:

            通過監控show slave status\G命令輸出的Seconds_Behind_Master參數的值來判斷,是否有發生主從延時。其值有這么幾種:

            NULL — 表示io_thread或是sql_thread有任何一個發生故障,也就是該線程的Running狀態是No,而非Yes。

            0 — 該值為零,是我們極為渴望看到的情況,表示主從復制良好,可以認為lag不存在。

            正值 — 表示主從已經出現延時,數字越大表示從庫落后主庫越多。

            負值 — 幾乎很少見,我只是聽一些資深的DBA說見過,其實,這是一個BUG值,該參數是不支持負值的,也就是不應該出現。

            show slave status\G,該命令的輸出結果非常豐厚,給我們的監控提供了很多有意義的參數,比如:Slave_IO_Running該參數可作為 io_thread的監控項,Yes表示io_thread的和主庫連接正常并能實施復制工作,No則說明與主庫通訊異常,多數情況是由主從間網絡引起的問題;Slave_SQL_Running該參數代表sql_thread是否正常,具體就是語句是否執行通過,常會遇到主鍵重復或是某個表不存在。下面就說到今天的重點Seconds_Behind_Master,該值作為判斷主從延時的指標,那么它又是怎么得到這個值的呢,同時,它為什么又受到很多人的質疑?

            Seconds_Behind_Master是通過比較sql_thread執行的event的timestamp和 io_thread復制好的event的timestamp(簡寫為ts)進行比較,而得到的這么一個差值。我們都知道的relay-log和主庫的 bin-log里面的內容完全一樣,在記錄sql語句的同時會被記錄上當時的ts,所以比較參考的值來自于binlog,其實主從沒有必要與NTP進行同步,也就是說無需保證主從時鐘的一致。

            你也會發現,其實比較真正是發生在io_thread與sql_thread之間,而io_thread才真正與主庫有關聯,于是,問題就出來了,當主庫I/O負載很大或是網絡阻塞,io_thread不能及時復制binlog(沒有中斷,也在復制),而 sql_thread一直都能跟上io_thread的腳本,這時Seconds_Behind_Master的值是0,也就是我們認為的無延時,但是,實際上不是,你懂得。這也就是為什么大家要批判用這個參數來監控數據庫是否發生延時不準的原因,但是這個值并不是總是不準,如果當io_thread與 master網絡很好的情況下,那么該值也是很有價值的。

            之前,提到Seconds_Behind_Master這個參數會有負值出現,我們已經知道該值是io_thread的最近跟新的ts與sql_thread執行到的ts差值,前者始終是大于后者的,唯一的肯能就是某個event的ts發生了錯誤,比之前的小了,那么當這種情況發生時,負值出現就成為可能。

            方法2:

            mk-heartbeat,Maatkit萬能工具包中的一個工具,被認為可以準確判斷復制延時的方法。

            mk-heartbeat的實現也是借助timestmp的比較實現的,它首先需要保證主從服務器必須要保持一致,通過與相同的一個NTP server同步時鐘。它需要在主庫上創建一個heartbeat的表,里面至少有id與ts兩個字段,id為server_id,ts就是當前的時間戳 now(),該結構也會被復制到從庫上。

            表建好以后,會在主庫上以后臺進程的模式去執行一行更新操作的命令,定期去向表中的插入數據,這個周期默認為1 秒,同時從庫也會在后臺執行一個監控命令,與主庫保持一致的周期去比較,復制過來記錄的ts值與主庫上的同一條ts值,差值為0表示無延時,差值越大表示延時的秒數越多。

            我們都知道復制是異步的ts不肯完全一致,所以該工具允許半秒的差距,在這之內的差異都可忽略認為無延時。這個工具就是通過實打實的復制,巧妙的借用timestamp來檢查延時,非常好用!

            關于檢查MySQL數據庫的主從延時的兩種方法就介紹到這里了,希望本次的介紹能夠對您有所收獲!

          posted @ 2011-12-20 14:29 順其自然EVO 閱讀(335) | 評論 (0)編輯 收藏

          Java字符編碼根本原理

           Java開發中,常常會遇到亂碼的問題,一旦遇到這種問題,常常就很扯蛋,每個人都不愿意承認是自己的代碼有問題。其實編碼問題并沒有那么神秘,那么不可捉摸,搞清Java的編碼本質過程就真相大白了。

            先看個圖:

            其實,編碼問題存在兩個方面:JVM之內和JVM之外。

            1、Java文件編譯后形成class

            這里Java文件的編碼可能有多種多樣,但Java編譯器會自動將這些編碼按照Java文件的編碼格式正確讀取后產生class文件,這里的class文件編碼是Unicode編碼(具體說是UTF-16編碼)。

            因此,在Java代碼中定義一個字符串:

            String s="漢字";

            不管在編譯前java文件使用何種編碼,在編譯后成class后,他們都是一樣的----Unicode編碼表示。

            2、JVM中的編碼

            JVM加載class文件讀取時候使用Unicode編碼方式正確讀取class文件,那么原來定義的String s="漢字";在內存中的表現形式是Unicode編碼。

            當調用String.getBytes()的時候,其實已經為亂碼買下了禍根。因為此方法使用平臺默認的字符集來獲取字符串對應的字節數組。在WindowsXP中文版中,使用的默認編碼是GBK,不信運行下:

        132. public class Test {   
        133. public static void main(String[] args) {   
        134. System.out.println("當前JRE:" + System.getProperty("java.version"));   
        135. System.out.println("當前JVM的默認字符集:" + Charset.defaultCharset());   
        136. }   
        137. }
        138.   當前JRE:1.6.0_16

            當前JVM的默認字符集:GBK

            當不同的系統、數據庫經過多次編碼后,如果對其中的原理不理解,就容易導致亂碼。因此,在一個系統中,有必要對字符串的編碼做一個統一,這個統一模糊點說,就是對外統一。比如方法字符串參數,IO流,在中文系統中,可以統一使用GBK、GB13080、UTF-8、UTF-16等等都可以,只是要選擇有些更大字符集,以保證任何可能用到的字符都可以正常顯示,避免亂碼的問題。(假設對所有的文件都用ASCII碼)那么就無法實現雙向轉換了。

           要特別注意的是,UTF-8并非能容納了所有的中文字符集編碼,因此,在特殊情況下,UTF-8轉GB18030可能會出現亂碼,然而一群傻B常常在做中文系統喜歡用UTF-8編碼而不說不出個所以然出來!最傻B的是,一個系統多個人做,源代碼文件有的人用GBK編碼,有人用UTF-8,還有人用GB18030。FK,都是中國人,也不是外包項目,用什么UTF-8啊,神經!源代碼統統都用GBK18030就OK了,免得ANT腳本編譯時候提示不可認的字符編碼。

            因此,對于中文系統來說,最好選擇GBK或GB18030編碼(其實GBK是GB18030的子集),以便最大限度的避免亂碼現象。

            3、內存中字符串的編碼

            內存中的字符串不僅僅局限于從class代碼中直接加載而來的字符串,還有一些字符串是從文本文件中讀取的,還有的是通過數據庫讀取的,還有可能是從字節數組構建的,然而他們基本上都不是Unicode編碼的,原因很簡單,存儲優化。

            因此就需要處理各種各樣的編碼問題,在處理之前,必須明確“源”的編碼,然后用指定的編碼方式正確讀取到內存中。如果是一個方法的參數,實際上必須明確該字符串參數的編碼,因為這個參數可能是另外一個日文系統傳遞過來的。當明確了字符串編碼時候,就可以按照要求正確處理字符串,以避免亂碼。

            在對字符串進行解碼編碼的時候,應該調用下面的方法:

        139. getBytes(String charsetName)   
        140. String(byte[] bytes, String charsetName)
        141.   而不要使用那些不帶字符集名稱的方法簽名,通過上面兩個方法,可以對內存中的字符進行重新編碼。

          posted @ 2011-12-20 14:26 順其自然EVO 閱讀(225) | 評論 (0)編輯 收藏

          Tomcat運行Java Web內存溢出總結

           如果JVM里運行的程序, 它的內存堆和持久存儲區域的都滿了,這個時候程序還想創建對象實例的話,垃圾收集器就會啟動,試圖釋放足夠的內存來創建這個對象。這個時候如果垃圾收集器 沒有能力釋放出足夠的內存,它就會拋出OutOfMemoryError內存溢出錯誤。

            SUN JVM的內存管理方式:

            SUN的JVM是類似人類家族,也就是在一個地方創建對象,在它長期占據空間之前給它多次死亡的機會,SUN JVM會劃分為:

            1、年輕的一代(Young generation),包括EDEN和2個幸存者空間(出發地和目的地the From space and the To space)

            2、老一代(Old generation)

            3、永久的一代(Permanent generation)

            Java虛擬機的運行時數據區一般分類如下(不一定是物理劃分):

            1、堆:主要存放對象實例,線程共享

            2、棧:主要存儲特定線程的方法調用狀態,線程獨占

            3、本地方法棧:存儲本地方法的調用狀態,線程獨占

            4、PC寄存器:學過操作系統課程的都知道,線程獨占

            5、方法區:主要存儲了類型信息,線程共享

            因此,在拋出內存溢出錯誤的時候,一般都會提示內存泄露的種類,一般也都是按照區域進行劃分:

            1、堆(heap)內存泄漏java.lang.OutOfMemoryError: Javaheap space:大家都比較熟悉 ,通過設置-Xms2048m -Xmx4096m可以解決

            2、棧(stack)內存泄漏:當前線程運行期間維護的中間變量等信息過多,例如常見的死循環引起stack over flow

            3、方法區(permanent heap)內存泄漏,即java.lang.OutOfMemoryError: PermGen space:發生的原因和類型裝載、類型卸載有直接的關系,通過設置-XX:MaxNewSize=256m -XX:MaxPermSize=256m可以解決。

            一般情況下,當服務器內存過小,而提供了大量的訪問服務時,可能會緩存過多的數據對象造成堆內存溢出,當web應用不斷擴大,加載的lib庫達到一定大小(4M)后,就容易報PermGen OOM,也就是方法區溢出。

            在Linux服務器中將參數寫入環境變量:

        142. export CATALINA_OPTS="-Xms2048m -Xmx4096m" 
        143. export JAVA_OPTS="-XX:MaxNewSize=256m -XX:MaxPermSize=256m"
        144.   Xmx 最大不要超過服務器物理內存的80%

          posted @ 2011-12-19 17:15 順其自然EVO 閱讀(166) | 評論 (0)編輯 收藏

          Linux中crontab-定時任務命令

            有些東西很久不用就會忘記,所以為了不至于總是找資料,干脆就做一次深刻的筆記,這樣既能加深記憶,又能深入理解。

            linux服務器很久沒接觸了,出了一些新的版本,Ubuntu已經出了11.10了,之前對于Ubuntu的了解只是出于對桌面版的好奇,可以跟win7一樣炫,現在的Ubuntu已正式進入了Liunx愛好者的視線,應用用于后臺大型服務器,選擇它的主要原因還是出于對穩定性的考慮。用習慣了Centos,突然轉移到Ubuntu上還是有些不習慣,畢竟Centos與傳統的Redhat沒什么區別。不過,總歸命令還是一樣的,多用用就熟悉了。

            關于任務定時的命令crontab,在Linux中應用還算常見,這次為了配合開發完成一些輔助功能,以及一些備份更新等腳本,就需要crontab來完成,在windows下也就是一個批處理,linux只是多了一些命令而已。先來看看crontab的介紹:

            crontab命令常見于Unix和類Unix的操作系統之中,用于設置周期性被執行的指令。該命令從標準輸入設備讀取指令,并將其存放于“crontab”文件中,以供之后讀取和執行。通常,crontab儲存的指令被守護進程激活, crond常常在后臺運行,每一分鐘檢查是否有預定的作業需要執行。這類作業一般稱為cron jobs。crontab文件包含送交cron守護進程的一系列作業和指令。每個用戶可以擁有自己的crontab文件;同時,操作系統保存一個針對整個系統的crontab文件,該文件通常存放于/etc或者/etc之下的子目錄中,而這個文件只能由系統管理員來修改。crontab文件的每一行均遵守特定的格式,由空格或tab分隔為數個領域,每個領域可以放置單一或多個數值。

            在Ubuntu中,crontab的命令如下:

            -e 表示編輯當前的crontab

            -l  表示列表顯示當前的crontab任務

            -r  表示刪除當前用戶的crontab

            -i  表示刪除crontab時給予提示信息

            注意,user's crontab這個表示是每個用戶都有自己的crontab,所以如果需要全局執行,必須定制root用戶的crontab,非全局的,就根據各個用戶自己的crontab來執行,在執行編輯crontab操作時,我們需要設置編輯工具,否則默認是crontab的編輯,對于習慣vi編輯的用戶,我們需要在用戶目錄下設置.profile配置文件,如root的配置文件.prifile,就如下目錄:

            帶.的文件都是隱藏文件,所以需要ls -a才能列出來,vi .profile在文件中加入如下配置:

            EDITOR=vi; export EDITOR

            表示,當前root用戶以vi作為默認編輯器,此時直接使用crontab -e,可以進行編輯任務列表,如下所示:

            上面以#號開頭的表示是注釋說明的信息,紅色標記的是任務列表。

            對于crontab的任務配置說明;

            分鐘 小時 日 月 星期 命令

            *    *    *  *  *    *

            這樣就一目了然了,我們紅色標記的表示的意義是每天3點鐘執行腳本run.sh,并將執行日志自動輸出到log.log文件中。

            */1 * * * * root  /opt/bin/test-cron.sh //表示每隔一分鐘執行一次腳本

            注:crontab任務是被定制在系統后臺運行的cron進程,所以用戶書無法查看到cron的進程狀態的。設置開機啟動cron進程,命令如下:

            chkconfig --add crond,把它加入到系統的服務列表中。

            當然,crontab命令用多了,會越來越喜歡它的,因為它能簡化我們日常的很多工作,特別是數據庫備份、檢測服務器運行狀態等一些經常做的工作,都可以根據你的需求來定制,在合理的時間運行執行合適的工作任務,既不影響服務器的性能,又可以節約平時的工作時間,大大提高功能效率。

          posted @ 2011-12-19 17:12 順其自然EVO 閱讀(276) | 評論 (0)編輯 收藏

          注意那些容易被忽略的SQL注入技巧

          注意那些容易被忽略的SQL注入技巧

           下面我要談到一些Sqlserver新的Bug(注入),這些都是從長期的工作中總結出來的經驗,現在拿出來與大家一起分享,希望能夠對大家有所幫助。

            1、關于Openrowset和Opendatasource

            可能這個技巧早有人已經會了,就是利用openrowset發送本地命令。通常我們的用法是(包括MSDN的列子)如下:

          以下是代碼片段:
          select * from openrowset('sqloledb','myserver';'sa';'','select * from table')

            可見(即使從字面意義上看)openrowset只是作為一個快捷的遠程數據庫訪問,它必須跟在select后面,也就是說需要返回一個recordset 。

            那么我們能不能利用它調用XP_cmdshell呢?答案是肯定的!

          以下是代碼片段:
              select * from openrowset('sqloledb','server';'sa';'','set fmtonly off
            exec master.dbo.XP_cmdshel l ''dir c:\''')

            必須加上setfmtonlyoff用來屏蔽默認的只返回列信息的設置,這樣XP_cmdshell返回的output集合就會提交給前面的select顯示,如果采用默認設置,會返回空集合導致select出錯,命令也就無法執行了。

            那么如果我們要調用sp_addlogin呢,他不會像XP_cmdshell返回任何集合的,我們就不能再依靠fmtonly設置了,可以如下操作:

          以下是代碼片段:
              select * from openrowset('sqloledb','server';'sa';'','select ''OK!''
            exec master.dbo.sp_addlogin Hectic')

            這樣,命令至少會返回select OK!'的集合,你的機器商會顯示OK!,同時對方的數據庫內也會增加一個Hectic的賬號,也就是說,我們利用select 'OK!'的返回集合欺騙了本地的select請求,是命令能夠正常執行,通理sp_addsrvrolemember和opendatasource也可以如此操作!至于這個方法真正的用處,大家慢慢想吧。

            2、關于Msdasql兩次請求的問題

            不知道大家有沒有試過用msdasql連接遠程數據庫,當然這個api必須是sqlserver的管理員才可以調用,那么如下:

          以下是代碼片段:
              select * from openrowset('msdasql','driver={sql server};server=server;address=server,1433;uid=sa;pwd=;database=master;network=dbmssocn','s
            elect * from table1 select * from table2')

            當table1和table2的字段數目不相同時,你會發現對方的sqlserver崩潰了,連本地連接都會失敗,而系統資源占用一切正常,用pskill殺死 sqlserver進程后,如果不重啟機器,sqlserver要么無法正常啟動,要么時常出現非法操作,我也只是碰巧找到這個bug的,具體原因我還沒有摸透,而且很奇怪的是這個現象只出現在msdasql上,sqloledb就沒有這個問題,看來問題不是在于請求集合數目和返回集合數目不匹配上,應該還是msdasql本身的問題,具體原因,大家一起慢慢研究吧。

            3、可怕的后門

            以前在網上看到有人說在 sqlserver上留后門可以通過添加triger、jobs或改寫sp_addlogin和sp_addsrvrolemember做到,這些方法當然可行,但是很容易會被發現。不知道大家有沒有想過sqloledb的本地連接映射。呵呵,比如你在對方的sqlserver上用sqlserver的管理員賬號執行如下的命令:

          以下是代碼片段:
          select * from openrowset('sqloledb','trusted_connection=yes;data source=Hectic','set fmtonly off exec master..XP_cmdshell ''dir c:\''')

            這樣在對方的sqlserver上建立了一個名為Hectic的本地連接映射,只要sqlserver不重啟,這個映射會一直存在下去,至少我現在還不知道如何發現別人放置的連接映射,好了,以上的命令運行過后,你會發現哪怕是sqlserver沒有任何權限的guest用戶,運行以上這條命令也一樣能通過!而且權限是 localsystem!(默認安裝)呵呵!這個方法可以用來在以被入侵過獲得管理員權限的sqlserver上留下一個后門了。以上的方法在 sqlserver2000 sqlserver2000SP1上通過!

            另外還有一個猜測,不知道大家有沒有注意過windows默認附帶的兩個dsn,一個是localserver一個是msqi,這兩個在建立的時候是本地管理員賬號連接sqlserver的,如果對方的 sqlserver是通過自定義的power user啟動,那么sa的權限就和power user一樣,很難有所大作為,但是我們通過如下的命令:

          以下是代碼片段:
              select * from openrowset
            ('msdasql','dsn=locaserver;trusted_connection=yes','set fmtonly off execmaster..XP_cmdshell ''dir c:\''')

            應該可以利用localserver的管理員賬號連接本地sqlserver然后再以這個賬號的權限執行本地命令了,這是后我想應該能突破sa那個power user權限了。現在的問題是sqloledb無法調用dsn連接,而msdasql非管理員不讓調用,所以我現在正在尋找guest調用msdasql 的方法。

            上文中我給大家介紹的可能只是SQL注入技巧的一部分,如果大家有更好的有關SQL注入的技巧,也要拿出來和我們分享哦,好東西大家要一起分享。

          posted @ 2011-12-19 17:11 順其自然EVO 閱讀(160) | 評論 (0)編輯 收藏

          僅列出標題
          共394頁: First 上一頁 346 347 348 349 350 351 352 353 354 下一頁 Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 清徐县| 忻城县| 常熟市| 米泉市| 呈贡县| 冕宁县| 信阳市| 阳高县| 景东| 沅江市| 扎鲁特旗| 汉阴县| 廊坊市| 漳州市| 辰溪县| 武功县| 永清县| 夹江县| 商都县| 宝坻区| 全州县| 若羌县| 四子王旗| 高密市| 桦川县| 鄂伦春自治旗| 阜康市| 田林县| 清丰县| 高密市| 万荣县| 阿坝| 信丰县| 新竹市| 新宾| 岳西县| 会泽县| 邢台县| 凤凰县| 靖州| 南昌县|