99久久精品免费观看国产_久久无码人妻一区二区三区_50岁熟妇的呻吟声对白_毛很浓密超多黑毛的少妇

網站建設中的代碼優化

分類: 瀏覽次數:30420 2018-11-06 00:00:00
滿意回答
2018-11-06 00:00:00

代碼優化:山東網站建設的業務邏輯實現代碼主要部署在應用服務器上,需要處理復雜的并發事務.合理優化業務代碼,可以很好地改善網站性能.不同編程語言的代碼優化手段有很多,這里我們概要地關注比較重要的幾個方面.

QQ截圖20180913101329

1.多線程

多用戶并發訪問是網站的基本需求,大型網站的并發用戶數會達到數萬,單臺服務器的并發用戶也會達到數百。CGI編程時代,每個用戶請求都會創建一個獨立的系統進程去處理。由于線程比進程更輕量,更少占有系統資源,切換代價更小,所以目前主要的Web應用服務器都采用多線程的方式響應并發用戶請求,因此網站開發天然就是多線程編程。從資源利用的角度看,使用多線程的原因主要有兩個:IO阻塞與多CPU。當前線程進行IO處理的時候,會被阻塞釋放CPU以等待IO操作完成,由于IO操作(不管是磁盤IO還是網絡IO)通常都需要較長的時間,這時CPU可以調度其他的線程進行處理。前面我們提到,理想的系統Load是既沒有進程(線程)等待也沒有CPU空閑,利用多線程IO阻塞與執行交替進行,可最大限度地利用CPU資源。使用多線程的另一個原因是服務器有多個CPU,在這個連手機都有四核CPU的時代,除了最低配置的虛擬機,一般數據中心的服務器至少16核CPU,要想最大限度地使用這些CPU,必須啟動多線程。網站的應用程序一般都被Web服務器容器管理,用戶請求的多線程也通常被Web服務器容器管理,但不管是Web容器管理的線程,還是應用程序自己創建的線程,一臺服務器上啟動多少線程合適呢?假設服務器上執行的都是相同類型任務,針對該類任務啟動的線程數有個簡化的估算公式可供參考:啟動線程數=[任務執行時間/(任務執行時間(IO等待時間)]]CPU內核數最佳啟動線程數和CPU內核數量成正比,和IO阻塞時間成反比。如果任務都是CPU計算型任務,那么線程數最多不超過CPU內核數,因為啟動再多線程,CPU也來不及調度;相反如果是任務需要等待磁盤操作,網絡響應,那么多啟動線程有助于提高任務并發度,提高系統吞吐能力,改善系統性能。多線程編程一個需要注意的問題是線程安全問題,即多線程并發對某個資源進行修改,導致數據混亂。這也是缺乏經驗的網站工程師最容易犯錯的地方,而線程安全Bug又難以測試和重現,網站故障中,許多所謂偶然發生的“靈異事件”都和多線程并發問題有關。對網站而言,不管有沒有進行多線程編程,工程師寫的每一行代碼都會被多線程執行,因為用戶請求是并發提交的,也就是說,所有的資源——對象、內存、文件、數據庫,乃至另一個線程都可能被多線程并發訪問。編程上,解決線程安全的主要手段有如下幾點。將對象設計為無狀態對象:所謂無狀態對象是指對象本身不存儲狀態信息(對象無成員變量,或者成員變量也是無狀態對象),這樣多線程并發訪問的時候就不會出現狀態不一致,Java Web開發中常用的Servlet對象就設計為無狀態對象,可以被應用服務器多線程并發調用處理用戶請求。而Web開發中常用的貧血模型對象都是些無狀態對象。不過從面向對象設計的角度看,無狀態對象是一種不良設計。使用局部對象:即在方法內部創建對象,這些對象會被每個進入該方法的線程創建,除非程序有意識地將這些對象傳遞給其他線程,否則不會出現對象被多線程并發訪問的情形。并發訪問資源時使用鎖:即多線程訪問資源的時候,通過鎖的方式使多線程并發操作轉化為順序操作,從而避免資源被并發修改。隨著操作系統和編程語言的進步,出現各種輕量級鎖,使得運行期線程獲取鎖和釋放鎖的代價都變得更小,但是鎖導致線程同步順序執行,可能會對系統性能產生嚴重影響。

2.資源復用系統運行時,要盡量減少那些開銷很大的系統資源的創建和銷毀,比如數據庫連接、網絡通信連接、線程、復雜對象等。從編程角度,資源復用主要有兩種模式:單例(Singleton)和對象池(Object Pool)。單例雖然是GoF經典設計模式中較多被詬病的一個模式,但由于目前Web開發中主要使用貧血模式,從Service到Dao都是些無狀態對象,無需重復創建,使用單例模式也就自然而然了。事實上,Java開發常用的對象容器Spring默認構造的對象都是單例(需要注意的是Spring的單例是Spring容器管理的單例,而不是用單例模式構造的單例)。對象池模式通過復用對象實例,減少對象創建和資源消耗。對于數據庫連接對象,每次創建連接,數據庫服務端都需要創建專門的資源以應對,因此頻繁創建關閉數據庫連接,對數據庫服務器而言是災難性的,同時頻繁創建關閉連接也需要花費較長的時間。因此在實踐中,應用程序的數據庫連接基本都使用連接池(Connection Pool)的方式。數據庫連接對象創建好以后,將連接對象放入對象池容器中,應用程序要連接的時候,就從對象池中獲取一個空閑的連接使用,使用完畢再將該對象歸還到對象池中即可,不需要創建新的連接。前面說過,對于每個Web請求(HTTP Request),Web應用服務器都需要創建網站一個獨立的線程去處理,這方面,應用服務器也采用線程池(Thread Pool)的方式。這些所謂的連接池、線程池,本質上都是對象池,即連接、線程都是對象,池管理方式也基本相同。

3.數據結構早期關于程序的一個定義是,程序就是數據結構早算法,數據結構對于編程的重要性不言而喻。在不同場景中合理使用恰當的數據結構,靈活組合各種數據結構改善數據讀寫和計算特性可極大優化程序的性能。前面緩存部分已經描述過Hash表的基本原理,Hash表的讀寫性能在很大程度上依賴HashCode的隨機性,即HashCode越隨機散列,Hash表的沖突就越少,讀寫性能也就越高,目前比較好的字符串Hash散列算法有Time33算法,即對字符串逐字符迭代乘以33,求得Hash值,算法原型為:hash(i)= hash(i 1)* 33 + str[i]Time33雖然可以較好地解決沖突,但是有可能相似字符串的HashCode也比較接近,如字符串“AA”的HashCode是2210,字符串“AB”的HashCode是2211。這在某些應用場景是不能接受的,這種情況下,一個可行的方案是對字符串取信息指紋,再對信息指紋求HashCode,由于字符串微小的變化就可以引起信息指紋的巨大不同,因此可以獲得較好的隨機散列.通過MD5計算HashCode4.垃圾回收如果Web應用運行在JVM等具有垃圾回收功能的環境中,那么垃圾回收可能會對系統的性能特性產生巨大影響。理解垃圾回收機制有助于程序優化和參數調優,以及編寫內存安全的代碼。以JVM為例,其內存主要可劃分為堆(heap)和堆棧(stack)。堆棧用于存儲線程上下文信息,如方法參數、局部變量等。

堆則是存儲對象的內存空間,對象的創建和釋放、垃圾回收就在這里進行。通過對對象生命周期的觀察,發現大部分對象的生命周期都極其短暫,這部分對象產生的垃圾應該被更快地收集,以釋放內存,這就是JVM分代垃圾回收.JVM分代垃圾回收機制在JVM分代垃圾回收機制中,將應用程序可用的堆空間分為年輕代(Young Generation)和年老代(Old Generation),又將年輕代分為Eden區(Eden Space)、From區和To區,新建對象總是在Eden區中被創建,當Eden區空間已滿,就觸發一次Young GC(Garbage Collection,垃圾回收),將還被使用的對象復制到From區,這樣整個Eden區都是未被使用的空間,可供繼續創建對象,當Eden區再次用完,再觸發一次Young GC,將Eden區和From區還在被使用的對象復制到To區,下一次Young GC則是將Eden區和To區還被使用的對象復制到From區。因此,經過多次Young GC,某些對象會在From區和To區多次復制


標簽:
青島企業郵箱哪家做?多少錢的相關問題

Copyright All Rights GreatGoal Design co.,ltd. 魯ICP備16002128號-3