個人專題目錄
11. 數據庫/Tomcat優化
Tomcat本身的參數你一般會怎么調整
一、Tomcat 本身優化
Tomcat 的自身參數的優化,這塊很像 ApacheHttp Server。修改一下 xml 配置文件中的參數,調整最大連接數,超時等。此外,我們安裝 Tomcat 時,優化就已經開始了
1、工作方式選擇
為了提升性能,首先就要對代碼進行動靜分離,讓 Tomcat 只負責 jsp 文件的解析工作。如采用 Apache 和 Tomcat 的整合方式,他們之間的連接方案有三種選擇,JK、http_proxy 和 ajp_proxy。相對于 JK 的連接方式,后兩種在配置上比較簡單的,靈活性方面也一點都不遜色。但就穩定性而言不像JK 這樣久經考驗,所以建議采用 JK 的連接方式。
2、Connector 連接器的配置
之前文件介紹過的 Tomcat 連接器的三種方式: bio、nio 和 apr,三種方式性能差別很大,apr 的性能最優, bio 的性能最差。而 Tomcat 7 使用的 Connector 默認就啟用的 Apr 協議,但需要系統安裝 Apr 庫,否則就會使用 bio 方式。
3、配置文件優化
配置文件優化其實就是對 server.xml 優化,可以提大大提高 Tomcat 的處理請求的能力,下面我們來看 Tomcat 容器內的優化。
默認配置下,Tomcat 會為每個連接器創建一個綁定的線程池(最大線程數 200),服務啟動時,默認創建了 5 個空閑線程隨時等待用戶請求。
maxThreads :Tomcat 使用線程來處理接收的每個請求,這個值表示 Tomcat 可創建的最大的線程數,默認值是 200
minSpareThreads:最小空閑線程數,Tomcat 啟動時的初始化的線程數,表示即使沒有人使用也開這么多空線程等待,默認值是 10。
maxSpareThreads:最大備用線程數,一旦創建的線程超過這個值,Tomcat 就會關閉不再需要的 socket 線程。
URIEncoding:指定 Tomcat 容器的 URL 編碼格式,語言編碼格式這塊倒不如其它 WEB 服務器軟件配置方便,需要分別指定。
connnectionTimeout: 網絡連接超時,單位:毫秒,設置為 0 表示永不超時,這樣設置有隱患的。通常可設置為 30000 毫秒,可根據檢測實際情況,適當修改。
enableLookups: 是否反查域名,以返回遠程主機的主機名,取值為:true 或 false,如果設置為false,則直接返回IP地址,為了提高處理能力,應設置為 false。
disableUploadTimeout:上傳時是否使用超時機制。
connectionUploadTimeout:上傳超時時間,畢竟文件上傳可能需要消耗更多的時間,這個根據你自己的業務需要自己調,以使Servlet有較長的時間來完成它的執行,需要與上一個參數一起配合使用才會生效。
acceptCount:指定當所有可以使用的處理請求的線程數都被使用時,可傳入連接請求的最大隊列長度,超過這個數的請求將不予處理,默認為100個。
keepAliveTimeout:長連接最大保持時間(毫秒),表示在下次請求過來之前,Tomcat 保持該連接多久,默認是使用 connectionTimeout 時間,-1 為不限制超時。
maxKeepAliveRequests:表示在服務器關閉之前,該連接最大支持的請求數。超過該請求數的連接也將被關閉,1表示禁用,-1表示不限制個數,默認100個,一般設置在100~200之間。
compression:是否對響應的數據進行 GZIP 壓縮,off:表示禁止壓縮;on:表示允許壓縮(文本將被壓縮)、force:表示所有情況下都進行壓縮,默認值為off,壓縮數據后可以有效的減少頁面的大小,一般可以減小1/3左右,節省帶寬。
compressionMinSize:表示壓縮響應的最小值,只有當響應報文大小大于這個值的時候才會對報文進行壓縮,如果開啟了壓縮功能,默認值就是2048。
compressableMimeType:壓縮類型,指定對哪些類型的文件進行數據壓縮。
二、JVM 優化
Tomcat 啟動命令行中的優化參數,就是 JVM 的優化 。Tomcat 首先跑在 JVM 之上的,因為它的啟動其實也只是一個 java 命令行,首先我們需要對這個 JAVA 的啟動命令行進行調優。不管是 YGC 還是 Full GC,GC 過程中都會對導致程序運行中中斷,正確的選擇不同的 GC 策略,調整 JVM、GC 的參數,可以極大的減少由于 GC 工作,而導致的程序運行中斷方面的問題,進而適當的提高 Java 程序的工作效率。但是調整 GC 是以個極為復雜的過程,由于各個程序具備不同的特點,如:web 和 GUI 程序就有很大區別(Web可以適當的停頓,但GUI停頓是客戶無法接受的),而且由于跑在各個機器上的配置不同(主要 cup 個數,內存不同),所以使用的 GC 種類也會不同。
如果查詢很慢,你會想到的第一個方式是什么?索引是干嘛的?
參考:https://www.cnblogs.com/boothsun/p/8970952.html
MySQL官方對索引的定義為:索引(Index)是幫助MySQL高效獲取數據的數據結構。
B樹的加強版,B+樹與B樹的差異在于
有n棵子樹的節點含有n個關鍵字(也有認為是n-1個關鍵字)。
所有的關鍵字全部存儲在葉子節點上,且葉子節點本身根據關鍵字自小而大順序連接。
非葉子節點可以看成索引部分,節點中僅含有其子樹(根節點)中的最大(或最小)關鍵字。
B+樹的特性如下:
所有關鍵字都存儲在葉子節上,且鏈表中的關鍵字恰好是有序的。
不可能非葉子節點命中返回。
非葉子節點相當于葉子節點的索引,葉子節點相當于是存儲(關鍵字)數據的數據層。
更適合文件索引系統。
在B+Tree的每個葉子節點增加一個指向相鄰葉子節點的指針,就形成了帶有順序訪問指針的B+Tree。做這個優化的目的是為了提高區間訪問的性能
分布式事務
消息中間件的分布式事務:http://www.lxweimin.com/p/66b7f60492a0
分布式事務:https://blog.csdn.net/qq_27384769/article/details/79303942
分庫分表有沒有做過?線上的遷移過程是怎么樣的?如何確定數據是正確的?
分庫分表:https://www.cnblogs.com/butterfly100/p/9034281.html
線上的數據遷移:https://blog.csdn.net/bjweimengshu/article/details/79984090
講一下怎么使用分布式鎖
分布式鎖的三種實現方式:
基于數據庫:1)利用唯一索引約束;2)利用數據庫自帶排他鎖
-
基于緩存:利用setnx()返回值
- SETNX
SETNX key val:當且僅當key不存在時,set一個key為val的字符串,返回1;若key存在,則什么都不做,返回0。 - expire
expire key timeout:為key設置一個超時時間,單位為second,超過這個時間鎖會自動釋放,避免死鎖。 - delete
delete key:刪除key
- SETNX
-
基于ZooKeeper:1)利用ZooKeeper同一個目錄下只能有一個唯一文件名;2)利用ZooKeeper分布式鎖客戶端Curator
- 創建一個目錄mylock;
- 線程A想獲取鎖就在mylock目錄下創建臨時順序節點;
- 獲取mylock目錄下所有的子節點,然后獲取比自己小的兄弟節點,如果不存在,則說明當前線程順序號最小,獲得鎖;
- 線程B獲取所有節點,判斷自己不是最小節點,設置監聽比自己次小的節點;
- 線程A處理完,刪除自己的節點,線程B監聽到變更事件,判斷自己是不是最小的節點,如果是則獲得鎖。
注:需要考慮的因素:單點、可重入、阻塞、失效時間
推薦一個Apache的開源庫Curator,它是一個ZooKeeper客戶端,Curator提供的InterProcessMutex是分布式鎖的實現,acquire方法用于獲取鎖,release方法用于釋放鎖。
優點:具備高可用、可重入、阻塞鎖特性,可解決失效死鎖問題。
缺點:因為需要頻繁的創建和刪除節點,性能上不如Redis方式。
Mysql索引的分類(Btree, hash),各自使用什么情況
B-Tree 索引的特點(Btree的查找原理:https://blog.csdn.net/u013967628/article/details/84305511)
B-tree 索引可以用于使用 =, >, >=, <, <= 或者 BETWEEN 運算符的列比較。如果 LIKE 的參數是一個沒有以通配符起始的常量字符串的話也可以使用這種索引。
Hash 索引的特點
Hash 索引只能夠用于使用 = 或者 <=> 運算符的相等比較(但是速度更快)。Hash 索引不能夠用于諸如 < 等用于查找一個范圍值的比較運算符。依賴于這種單值查找的系統被稱為 "鍵-值存儲";對于這種系統,盡可能地使用 hash 索引。
說說Myisam, Innodb區別
- MyISAM存儲引擎:不支持事務、也不支持外鍵,優勢是訪問速度快,對事務完整性沒有 要求或者以select,insert為主的應用基本上可以用這個引擎來創建表
- InnoDB存儲引擎:該存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM引擎,寫的處理效率會差一些,并且會占用更多的磁盤空間以保留數據和索引。
InnoDB存儲引擎的特點:支持自動增長列,支持外鍵約束
如果并發很大,你對數據的正確性怎么保證
樂觀鎖的方案,在數據庫記錄行上加上version字段,讀取的時候取出version,更新的時候帶上version為條件,同時version+1,如果更新失敗,說明別人修改過了,需要重新讀取數據,再讓用戶重新操作后更新
第二種:分布式鎖,redis、zookeeper等
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關系型數據庫里邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用于多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似于write_condition機制的其實都是提供的樂觀鎖。
共享鎖和排他鎖
共享鎖:共享鎖又稱讀鎖,是讀取操作創建的鎖。如果事務T對數據A加上共享鎖后,則其他事務只能對A再加共享鎖,不能加排他鎖。獲準共享鎖的事務只能讀數據,不能修改數據。
使用:SELECT ... LOCK IN SHARE MODE;
排他鎖:排他鎖又稱寫鎖,如果事務T對數據A加上排他鎖后,則其他事務不能再對A加任任何類型的封鎖。獲準排他鎖的事務既能讀數據,又能修改數據。
使用:SELECT ... FOR UPDATE;