概敘
Java web應用性能分析之服務端慢和優化概敘_cpu飆高java-CSDN博客
Java web應用性能分析之【CPU飆升分析概述】_web頁面性能分析cpu占滿是因為死循環,還是循環過多-CSDN博客
? ? ? ?在我們的軟件服務中,軟件部署的服務器,一般都是linux服務器,也就是裝了linux操作系統的服務器,linux服務器是一個統稱,其實在我們springboot應用中根據功能不同,還分成:堡壘機服務器、Nginx路由服務器、web服務器/java應用服務器、文件服務器、圖片服務器、數據庫服務器、redis緩存服務器、KFK消息隊列服務器、ES檢索服務器、多媒體處理服務器等等,不同功能的服務器性能優化的重點可能不一樣,前面的文章都是也是在這些角度去整理的。
????????除了這些之外,今天再加一個linux內核調優,其實它和linux服務器性能調優是分不開的,因為linux服務器上系統內核是橋梁、是連接服務器硬件和軟件的橋梁,linux服務器性能調優、繞不開內核調優。
? ? ? ? 所以就有這個公式:? ?linux服務器調優? = 監控 + 調優( 內核調優 + 硬件服務器調優 + 軟件調優)
? ? ? ? linux服務器性能優化都是根據監控情況,從內核調優、硬件服務器調優(CPU、內存、存儲、網絡)、軟件調優(操作系統、中間件、應用軟件)等方面入手,去做具體分析和論證,然后給出解決方案。
????????切記不要粗略的將這些獨立分開去優化,整體分析和調優,效果會更好。優化的目標是提高系統的整體性能,在同等條件下降低資源消耗,提升系統的穩定性、可用性。
? ? ? ? 常用的linux內核參數整理:科普文:linux服務器性能調優之內核參數-CSDN博客
單獨
1.CPU調度優化
????????CPU調度是Linux系統內核的核心功能之一,它負責將CPU資源分配給不同的進程。合理的CPU調度策略能夠顯著提高系統的響應速度和吞吐量。在優化CPU調度時,我們可以考慮以下幾個方面:
(1)調整進程優先級:通過調整進程的優先級,可以讓重要的進程獲得更多的CPU資源,從而提高系統的整體性能。
? ? ? ? 通過nice和chrt命令修改進程優先級,調度策略,參考如下:
科普文:Linux服務器性能調優之CPU調度策略和可調參數-CSDN博客
(2)使用多核CPU:充分利用多核CPU的并行處理能力,可以提高系統的并發性能。
? ? ? ? Nginx服務器上,可以將Nginx的work進程和cup內核綁定,減少切換,提升性能。
# 修改Apache配置文件
vi /etc/httpd/conf/httpd.conf# 找到以下兩行,修改為合適的值
StartServers 8 # 初始啟動的進程數
MaxRequestWorkers 150 # 最大的并發請求處理數user nginx nginx; # 啟動Nginx?作進程的??和組
worker_processes [number | auto]; # 啟動Nginx?作進程的數量
worker_cpu_affinity 00000001 00000010 00000100 00001000;
# 將Nginx?作進程綁定到指定的CPU核?,默認Nginx是不進?進程綁定的,
# 綁定并不是意味著當前nginx進程獨 占以?核?CPU,但是可以保證此進程不會運?在其他核?上,
# 這就極?減少了nginx的?作進程在不同的cpu核 ?上的來回跳轉,減少了CPU對進程的資源分配與回收以及內存管理等,
#因此可以有效的提升nginx服務器的性 能。 此處CPU有四顆核心。也可寫成:
#worker_cpu_affinity 0001 0010 0100 1000;#cpu的親和能偶使nginx對于不同的work工作進程綁定到不同的cpu上面去。就能夠減少在work間不#斷切換cpu,把進程通常不會在處理器之間頻繁遷移,進程遷移的頻率小,來減少性能損耗。
#每個 worker 的線程可以把一個 cpu 的性能發揮到極致。所以 worker 數和服務器的 cpu 數相#等是最為適宜的。設少了會浪費 cpu,設多了會造成 cpu 頻繁切換上下文帶來的損耗
???(3)調整調度器策略:內核通過調度器(Scheduler)來控制進程的執行順序和資源分配,從而實現進程的多任務處理能力。Linux系統提供了多種調度器策略,如CFS(Completely Fair Scheduler)、Deadline等。
????????使用任務調度器來優化CPU負載。Linux系統提供了多個任務調度器,如cron、at和anacron等。可以使用這些調度器來安排任務在系統閑時運行,避免在高負載期間執行計算密集型任務。通過合理安排任務的執行時間,可以減少系統的CPU負載,提高性能。
參考:科普文:Linux服務器性能調優之CPU調度策略和可調參數-CSDN博客
??????(4)啟用CPU緩存:? ? ? ? 啟用CPU緩存可以提高CPU的性能,減少內存的訪問次數。在CentOS上,我們可以通過調整一些參數來啟用或優化CPU緩存。
# 查看CPU緩存策略
cat /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cache_policy# 設置CPU緩存策略為Write Back
for i in /sys/devices/system/cpu/cpu*/cpufreq/cpuinfo_cache_policy; do echo writeback > $i; done# 設置緩存內存調度策略為負載均衡
echo 1 > /proc/sys/vm/page-cluster
????
????(5)NUMA優化: CPU盡可能訪問本地內存
? ? ? ????????? java服務器:jdk15之后可以選擇ZGC垃圾回收器
ZGC是支持NUMA的(UMA即Uniform Memory Access Architecture,NUMA就是Non Uniform Memory Access Architecture),
在進行小頁面分配時會優先從本地內存分配,當不能分配時才會從遠端的內存分配。
對于中頁面和大頁面的分配,ZGC并沒有要求從本地內存分配,而是直接交給操作系統,由操作系統找到一塊能滿足ZGC頁面的空間。
ZGC這樣設計的目的在于,對于小頁面,存放的都是小對象,從本地內存分配速度很快,
且不會造成內存使用的不平衡,而中頁面和大頁面因為需要的空間大,如果也優先從本地內存分配,極易造成內存使用不均衡,反而影響性能。
? ? ? ? ?數據庫服務器:禁用numa
1)Oracle數據庫層面關閉:
_enable_NUMA_optimization=false (11g中參數為_enable_NUMA_support)2)啟動MySQL的時候,關閉NUMA特性:
numactl --interleave=all mysqld指定numa也就其弊端,當服務器還有內存的時候,發現它已經在開始使用swap了,甚至已經導致機器出現停滯的現象。這個就有可能是由于numa的限制,如果一個進程限制它只能使用自己的numa節點的內存,那么當自身numa node內存使用光之后,就不會去使用其他numa node的內存了,會開始使用swap,甚至更糟的情況,機器沒有設置swap的時候,可能會直接死機。所以數據庫服務器不適合開啟numa。操作系統層面關閉NUMA
有如下方法:
1)BIOS中關閉NUMA設置
2)在操作系統中關閉,在RHEL 4, RHEL 5, RHEL 6 中,在/boot/grub/grub.conf文件中添加numa=off,如下所示:title Red Hat Enterprise Linux AS (2.6.9-55.EL)root (hd0,0)kernel /vmlinuz-2.6.9-55.EL ro root=/dev/VolGroup00/LogVol00 rhgb quiet numa=offinitrd /initrd-2.6.9-55.EL.img
在RHEL 7 中,需要修改/etc/default/grub文件,添加numa=off,并且需要重建grub,然后重啟OS:[root@18cRac1 software]# cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="rhgb quiet transparent_hugepage=never numa=off"
GRUB_DISABLE_RECOVERY="true"
[root@18cRac1 software]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.10.0-862.el7.x86_64
Found initrd image: /boot/initramfs-3.10.0-862.el7.x86_64.img
Found linux image: /boot/vmlinuz-0-rescue-4c7b16d0887748f883ee1a722ec96352
Found initrd image: /boot/initramfs-0-rescue-4c7b16d0887748f883ee1a722ec96352.img
done
[root@18cRac1 software]#
????????編輯/etc/default/grub,在 GRUB_CMDLINE_LINUX里添加 numa=off,然后重啟服務器。
????????(6)中斷負載均衡: irpbalance,將中斷處理過程自動負載均衡到各個CPU上
????????(7)cpu調速器:服務器先不考慮節能,性能最大化優先。
# 查看當前的CPU調度策略
cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor# 將CPU調度策略設置為performance
for i in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > $i; donePerformance:性能優先的governor,直接將cpu頻率設置為policy->{min,max}中的最大值。
Powersave:功耗優先的governor,直接將cpu頻率設置為policy->{min,max}中的最小值。
Userspace:由用戶空間程序通過scaling_setspeed文件節點修改頻率。
Ondemand:根據CPU的當前使用率,動態的調節CPU頻率。scheduler通過調用ondemand注冊進來的鉤子函數來觸發系統負載的估算(異步的)。它以一定的時間間隔對系統負載情況進行采樣。按需動態調整CPU頻率, 如果的CPU當前使用率超過設定閾值,就會立即達到最大頻率運行,等執行完畢就立即回到最低頻率。好處是調頻速度快,但問題是調的不夠精確。
Conservative:類似Ondemand,不過頻率調節的會平滑一下,不會有忽然調整為最大值又忽然調整為最小值的現象。區別在于:當系統CPU 負載超過一定閾值時,Conservative的目標頻率會以某個步長步伐遞增;當系統CPU 負載低于一定閾值時,目標頻率會以某個步長步伐遞減。同時也需要周期性地去計算系統負載。
Interactive:由Android提出的機制,未被linux kernel社區接納,在AOSP的linux分支上存在了較長時間。它針對CPU密集的任務的調頻策略會比較激進。因為它在每一個 CPU 上都注冊了一個 idle notifier。當 CPU 退出 idle 時,去檢查然后決策是否需要調整頻率,非idle時仍然需要依賴timer去定時采樣,才能知道系統負載信息。
schedutil:本文要討論的重點,后續章節展開。
????????(8)僵尸進程:進程狀態Z Zombie,僵尸進程,表示進程實際上已經結束,但是父進程還沒有回收它的資源;
2.內存管理優化
????????內存管理是Linux系統內核的另一個重要功能。合理的內存管理策略能夠降低系統的內存消耗,提高系統的穩定性和性能。在優化內存管理時,我們可以考慮以下幾個方面:
可參考:科普文:linux服務器性能調優之內核參數-CSDN博客
????????(1)調整內存分配策略:通過調整內存分配策略,可以減少內存碎片的產生,提高內存的使用效率。比如,可以使用內存池、大頁(HugePage)等。盡量使用緩存和緩沖區來。
????????(2)使用內存壓縮技術:內存壓縮技術可以將內存中的數據進行壓縮,從而釋放更多的內存空間。這對于內存資源緊張的系統來說尤為重要。
????????(3)優化Swap空間:最好禁止 Swap。如果必須開啟 Swap,降低 swappiness 的值,減少內存回收時 Swap 的使用傾向。
????????(4)限制OOMKIller:通過 /proc/pid/oom_adj ,調整核心應用的 oom_score。這樣,可以保證即使內存緊張,核心應用也不會被 OOM殺死。
????????(5)訪問數據。比如,可以使用堆棧明確聲明內存空間,來存儲需要緩存的數據;或者用Redis 這類的外部緩存組件,優化數據的訪問。
????????(6)使用 cgroups 等方式限制進程的內存使用情況。這樣,可以確保系統內存不會被異常進程耗盡。
????????查看系統緩存命中情況的工具:
- cachestat 提供了整個操作系統緩存的讀寫命中情況。
- cachetop 提供了每個進程的緩存命中情況。
cachestat 的運行界面,以 1 秒的時間間隔,輸出了 3 組緩存統計數據:$ cachestat 1 3
TOTAL MISSES HITS DIRTIES BUFFERS_MB CACHED_MB
2 0 2 1 17 279
2 0 2 1 17 279
2 0 2 1 17 279
可以看到,cachestat 的輸出其實是一個表格。每行代表一組數據,而每一列代表不同的緩存統計指標。這些指標從左到右依次表示:TOTAL ,表示總的 I/O 次數;
MISSES ,表示緩存未命中的次數;
HITS ,表示緩存命中的次數;
DIRTIES, 表示新增到緩存中的臟頁數;
BUFFERS_MB 表示 Buwers 的大小,以 MB 為單位;
CACHED_MB 表示 Cache 的大小,以 MB 為單位。
cachetop 的運行界面:$ cachetop
11:58:50 Buffers MB: 258 / Cached MB: 347 / Sort: HITS / Order: ascending
PID UID CMD HITS MISSES DIRTIES READ_HIT% WRITE_HIT%
13029 root python 1 0 0 100.0% 0.0%
它的輸出跟 top 類似,默認按照緩存的命中次數(HITS)排序,展示了每個進程的緩存命中情況。具體到每一個指標,這里的 HITS、MISSES 和 DIRTIES ,跟 cachestat 里的含義一樣,分別代表間隔時間內的緩存命中次數、未命中次數以及新增到緩存中的臟頁數。而 READ_HIT 和 WRITE_HIT ,分別表示 讀 和 寫 的緩存命中率。
3.文件系統優化
????????文件系統是Linux系統中用于存儲和管理數據的重要組件。優化文件系統可以提高數據的讀寫速度和系統的整體性能。
? ? ? ? 可參考:科普文:linux I/O原理、監控、和調優思路-CSDN博客
????????在優化文件系統時,我們可以考慮以下幾個方面:
(1)選擇合適的文件系統類型:Linux系統支持多種文件系統類型,如Ext4、XFS、Btrfs等。根據實際應用場景選擇合適的文件系統類型,可以充分發揮系統的性能優勢。
文件系統為 XFS,Ext4 依然是可以使用的文件系統方案。
XFS:支持1PB的文件系統,單個文件大小限制為8EB。
Ext4:支持50TB的文件系統,單個文件大小限制為16TB。XFS 適用場景:
沒有特定業務場景
大型服務器
大存儲設備
大文件
多線程 I/Oext4 適用場景:
小文件
單線程 I/O
受限制的 I/O 能力(under 1000 IOPS)
受限制的帶寬(under 200MB/s)
綁定 CPU 的業務
支持離線縮減
(2)調整文件系統掛載選項:通過調整文件系統掛載選項,可以優化數據的讀寫性能和系統的穩定性。例如,可以啟用寫緩存、調整I/O調度算法等。
文件系統掛載屬性
通用掛載屬性:
atime:授權內核更新文件訪問時間
relatime:如果文件或目錄被修改,則更新文件的訪問時間,否則,系統每天更新一次訪問時間,而不是實時更新,默認該選項在XFS和ext4文件系統上是啟用的。
noatime:不更新文件訪問時間
nodiratime:不更新目錄的訪問時間XFS 掛載選項默認RHEL中已經預定義了一些掛載參數,但是還有一些參數需要根據具體的應用場景決定是否開啟。
inode64: 將inodes放在離數據近的地方,以減少磁盤尋道時間。
logbsize=32K:log buffer size,默認值為32KB,可以修改為64K,128K,256K,logbsize=64Kext4 掛載選項:
i_version:開啟64位inode支持功能,對于擴展元數據屬性很有用,默認該屬性是禁用的。
journal_ioprio=: 定義journal(日志) I/O的優先級,范圍0-7,0的優先級最高
(3)使用SSD硬盤:SSD硬盤具有讀寫速度快、耐久性高等優點,使用SSD硬盤可以顯著提高文件系統的性能。
(4)文件系統內核參數調優:對于磁盤I/O,Linux提供了cfq, deadline和noop三種調度策略;
? ? ? ?虛擬機上的磁盤服務器:建議采用比較簡單的noop,畢竟數據實際上怎么落盤取決于虛擬化那一層。
?????????數據庫服務器:這類數據存儲系統不要使用cfq(時序數據庫可能會有所不同。不過也有說從來沒見過deadline比cfq差的情況)
cat /sys/block/sda/queue/schedulerecho deadline > /sys/block/sda/queue/scheduler# cat /sys/block/sda/queue/scheduler
[noop] deadline cfq
(方括號里面的是當前選定的調度策略)對于磁盤I/O,Linux提供了cfq, deadline和noop三種調度策略cfq: 這個名字是Complete Fairness Queueing的縮寫,它是一個復雜的調度策略,
按進程創建多個隊列,試圖保持對多個進程的公平(這就沒考慮讀操作和寫操作的不同耗時)deadline: 這個策略比較簡單,只分了讀和寫兩個隊列
(這顯然會加速讀取量比較大的系統),叫這個名字是內核為每個I/O操作都給出了一個超時時間noop: 這個策略最簡單,只有單個隊列,只有一些簡單合并操作
(5)管理文件系統日志,同時將數據和日志分離:有日志的文件系統,可以加速數據恢復的效率。任何時候文件系統發生數據變化時,就會記錄日志,當完成I/O操作后,再將日志記錄刪除。
????????因此,當計算機突然斷電,需要進行數據恢復時,我們僅需要檢查日志(必要時可以使用日志對數據進行恢復)和受日志影響的那部分文件系統,而不需要檢查整個文件系統。
XFS文件系統提供了一個norecovery 掛載選項,當使用此選項掛載文件系統時,日志會被禁用,掛載XFS文件系統時禁用自動恢復(recovery)過程。如果文件系統的數據不干凈(not cleanly),會出現數據一致性問題,有些文件或目錄可能無法訪問。使用norecovery選項掛載文件系統僅可以以只讀方式掛載。mount -o norecovery,ro /dev/<device> <mountpoint>
1
Ext3/Ext4文件系統的日志,可以分為三種工作模式,可以在mount掛載時,使用data=模式選項進行定義。文件在ext4文件系統中分兩部分存儲:metadata和data,metadata和data的日志是分開管理的。默認模式為 orderedordered:在這種模式下,只記錄元數據的日志,而不記錄數據的日志。當進行文件系統操作時,文件系統會先將需要修改的數據寫入磁盤,然后再寫入相應的元數據的日志。這樣可以確保在寫入元數據的日志之前,對應的數據已經持久化到磁盤上。這種模式提供了較好的數據一致性和良好的性能。
writeback:在這種模式下,只記錄元數據的日志,而不記錄數據的日志。與ordered模式不同,文件系統在進行文件系統操作時,會先將修改的數據寫入內存緩存(而不是直接寫入磁盤),然后再寫入相應的元數據的日志。這種模式具有較高的性能,因為數據寫入到內存緩存速度更快,但它也帶來了較低的數據一致性,因為數據可能尚未刷新到磁盤上。
journal:在這種模式下,會提供完整的數據和元數據的日志記錄。所有新的數據首先會被寫入日志,然后再寫入其最終位置。這種模式下的數據一致性最好,因為在發生崩潰或系統故障時,可以回放日志以恢復數據和元數據的一致性。然而,相對于前兩種模式,journal模式的性能較差,因為每個寫操作都需要先寫入日志。日志和數據分離
默認XFS和ext4文件系統被創建時,日志會被放置在與文件系統相關的設備上,當出現大量隨機寫操作時,磁盤的IO壓力比較大,我們可以通過將日志與數據分離的方式,來降低磁盤的IO壓力,提高數據讀寫性能。格式化掛載時分離
創建XFS文件系統時,可以使用logdev選項指定日志設備:使用-l(小寫L)指定日志選項,通過logdev設置日志磁盤為sdd1, sdc1為主文件系統磁盤mkfs -t xfs -l logdev=/dev/sdd1 /dev/sdc1
1
在mount掛載時,也必須指定日志磁盤的位置:mount -o logdev=/dev/sdd1 /dev/sdc1 /mnt
1
Ext4文件系統指定獨立日志磁盤的方式:和XFS不一樣,ext4文件系統不能在mount掛載的時候指定獨立的日志設備創建日志磁盤,block size為4KiBmkfs -t ext4 -O journal_dev -b 4096 /dev/sdd1
1
創建主文件系統sdc1,并指定日志設備為sdd1mkfs -t ext4 -J device=/dev/sdd1 -b 4096 /dev/sdc1
1
注意:ext4擴展日志文件系統要求,日志文件系統的 block 大小必須與主文件系統的block大小一致!最佳實踐是推薦在做主文件系統時同時創建日志文件系統。已存在日志的ext4系統做日志數據分離
假設sdc1是4G數據盤,sdd1是128M日志設備將一個已經存在的ext4系統中的日志轉換為獨立的日志設備,首先需要查看現有文件系統的block大小:tune2fs 是一個用于調整和修改 Ext2、Ext3 和 Ext4 文件系統參數的命令行工具。通過使用 tune2fs,您可以更改文件系統的各種屬性和選項,以滿足特定的需求。┌──[root@liruilongs.github.io]-[/var/lib/libvirt/images]
└─$tune2fs -l /dev/sdc1
Block size: 4096
1
2
3
創建相同大小的日志文件系統,在 /dev/sdd1 上創建一個 Ext4 文件系統,并啟用日志功能[root@serverX ~]# mkfs -t ext4 -O journal_dev /dev/sdd1
1
卸載文件系統:這將卸載 /dev/sdc1 文件系統,以便進行后續的文件系統調整。[root@serverX ~]# umount /dev/sdc1
1
修改文件系統特性:從 /dev/sdc1 文件系統中移除現有的日志特性,以便為其添加新的日志設備。[root@serverX ~]# tune2fs -O '^has_journal' /dev/sdc1
1
添加日志設備:為 /dev/sdc1 文件系統添加一個日志設備,并使用 /dev/sdd1 作為日志設備。[root@serverX ~]# tune2fs -j -J device=/dev/sdd1 /dev/sdc1
#-j 添加日志設備,-J 指定日志設備的參數
4.網絡性能優化
????????網絡性能是Linux系統的重要指標之一。優化網絡性能可以提高系統的吞吐量和響應速度,從而滿足日益增長的業務需求。
? ? ? ? 內核調整可參考:科普文:linux服務器性能調優之內核參數-CSDN博客
????????在優化網絡性能時,我們可以考慮以下幾個方面:
(1)調整TCP/IP參數:TCP/IP協議棧是Linux系統網絡性能的關鍵因素。通過調整TCP/IP參數,可以優化網絡的傳輸效率和穩定性。例如,可以調整TCP窗口大小、擁塞控制算法等。
(2)使用網絡壓縮技術:網絡壓縮技術可以將網絡中的數據進行壓縮,從而減少網絡帶寬的占用。這對于帶寬資源緊張的系統來說尤為重要。
(3)優化網絡硬件:選擇高性能的網絡硬件可以提高系統的網絡性能。例如,可以使用千兆網卡、萬兆網卡等高性能網絡設備。
5.性能調優工具說明
????????先運行幾個支持指標較多的工具, 如top/vmstat/pidstat,根據它們的輸出可以得出是哪種類型的性能問題. 定位到進程后再用strace/perf分析調用情況進一步分析. 如果是軟中斷導致用/proc/softirqs
????????根據不同的性能指標來找合適的工具:
????????在生產環境中往往開發者沒有權限安裝新的工具包,只能最大化利用好系統中已經安裝好的工具. 因此要了解一些主流工具能夠提供哪些指標分析.