1 คะแนน โดย GN⁺ 5 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เริ่มจาก หน้าจอ htop ของ Ubuntu Server 16.04 x64 แล้วไล่ตรวจสอบด้วย /proc และเอาต์พุตคำสั่งว่า uptime, load average, Tasks, PID, process tree, สถานะ, เวลา CPU, priority และตัวชี้วัดหน่วยความจำ หมายถึงอะไรจริง ๆ
  • ค่าจำนวนมากบนหน้าจอมาจากไฟล์ระบบอย่าง procfs และ /etc/passwd, /etc/group, /etc/shadow, /etc/nsswitch.conf และสามารถใช้ strace ตรวจสอบได้ว่าโปรแกรมอ่านไฟล์ใดบ้าง
  • Load average ไม่ใช่ค่าเดียวกับอัตราการใช้ CPU แต่เป็นค่าเฉลี่ยเคลื่อนที่แบบลดทอนเชิงเลขชี้กำลังที่รวมโปรเซสที่กำลังรัน·รอรัน และโปรเซสในสถานะ uninterruptible
  • รหัสสถานะอย่าง R, S, D, Z, T, t เชื่อมโยงกับการทำงานของ signal, kill, fork/exec/wait จึงเป็นเบาะแสในการตัดสินว่าโปรเซสหยุดหรือค้างอยู่เพราะอะไร
  • VIRT, RES, SHR, MEM% แสดง หน่วยความจำเสมือน, หน่วยความจำจริง และหน่วยความจำที่แชร์ได้จากมุมมองต่างกัน จึงยากที่จะสรุปการใช้หน่วยความจำจริงจากตัวเลขเดียว

ค่าใน htop มาจากไหน

  • uptime แสดงว่าระบบทำงานมานานแค่ไหนแล้ว และสามารถดูข้อมูลเดียวกันได้ด้วยคำสั่ง uptime
  • โปรแกรม uptime อ่าน /proc/uptime
    • ตัวเลขแรกคือเวลารวมเป็นวินาทีที่ระบบเปิดอยู่
    • ตัวเลขที่สองคือเวลารวมเป็นวินาทีที่ระบบอยู่ในสถานะ idle
    • ในระบบแบบหลายคอร์ เวลา idle อาจถูกนำมารวมตามแต่ละคอร์ จึงอาจมากกว่า uptime รวมได้
  • ใช้ strace uptime 2>&1 | grep open หรือ strace -e open uptime เพื่อดูไฟล์ที่ uptime เปิด
    • เอาต์พุตตัวอย่างจะมี /proc/uptime, /var/run/utmp, /proc/loadavg
  • ตัวเลขใน /proc/uptime เหมาะสำหรับใช้ในโปรแกรมหรือสคริปต์ ส่วนเอาต์พุตของ uptime ถูกจัดรูปแบบให้อ่านง่ายสำหรับมนุษย์

Load average และอัตราการใช้ CPU

  • ค่าสามตัวแรกของ /proc/loadavg แสดง load average ของระบบในช่วง 1 นาที, 5 นาที, 15 นาที ล่าสุด
  • ค่าที่สี่แสดงจำนวนโปรเซสที่กำลังรันและจำนวนโปรเซสทั้งหมดในรูปแบบอย่าง 1/120 และค่าสุดท้ายคือ PID ที่ถูกใช้ล่าสุด
  • เมื่อรันโปรเซสใหม่ จะมีการจัดสรร PID โดยปกติ PID จะเพิ่มขึ้นเรื่อย ๆ และเมื่อหมดจึงถูกนำกลับมาใช้ใหม่
    • PID 1 เป็นของ /sbin/init ที่เริ่มทำงานตอนบูต
  • หากใน htop เห็นโปรเซสที่กำลังรันเพียงตัวเดียว ตัวนั้นอาจเป็น htop เอง
  • sleep 30 ไม่ได้อยู่ในสถานะกำลังรัน แต่เป็นสถานะ sleep จึงไม่เพิ่มจำนวน running process
  • งานที่ใช้ CPU ต่อเนื่องอย่าง cat /dev/urandom > /dev/null จะเพิ่มจำนวน running process และ load average
  • Load number คือค่าที่นับโปรเซสที่กำลังรันหรือรอรัน และโปรเซสในสถานะ uninterruptible
  • load average ไม่ใช่ค่าเฉลี่ยธรรมดา แต่เป็น ค่าเฉลี่ยเคลื่อนที่แบบลดทอนเชิงเลขชี้กำลัง
    • แม้แต่ load average แบบ 1 นาทีก็ไม่ได้สะท้อนเฉพาะ 60 วินาทีล่าสุดเท่านั้น แต่ให้น้ำหนักกับ 1 นาทีล่าสุดมากกว่า พร้อมรวมกิจกรรมก่อนหน้านั้นบางส่วนด้วย
  • ในระบบ CPU เดียว หากมีโปรเซส CPU-bound หนึ่งตัว สามารถมองแบบง่าย ๆ ได้ว่า load average 1.00 เท่ากับใช้ CPU 100%
    • ในระบบ 2 คอร์ สถานการณ์เดียวกันสามารถมองได้ว่าเป็นการใช้ CPU 50%
    • load average ที่เทียบเท่าการใช้ CPU 100% บนระบบ 2 คอร์ สามารถทำให้ง่ายได้เป็น 2.00
  • การทำให้ง่ายแบบนี้ไม่ถูกต้องเสมอไป เพราะโปรเซสสถานะ uninterruptible ถูกนับรวมใน load ด้วย
    • จึงอาจเกิดสถานการณ์ที่ load average สูง แต่อัตราการใช้ CPU ไม่สูงได้
  • อัตราการใช้ CPU ณ ขณะนั้นสามารถตรวจสอบได้ด้วย mpstat
    • sudo apt install sysstat -y
    • mpstat 1

Tasks, PID, process tree

  • Tasks ที่มุมขวาบนของ htop แสดงจำนวนโปรเซสทั้งหมดและจำนวนโปรเซสที่กำลังรัน
  • Linux kernel เรียกโปรเซสภายในว่า task และ htop ใช้คำว่า Tasks แทน Processes เพื่อลดพื้นที่บนหน้าจอ
  • ใช้ Shift+H เพื่อสลับการแสดง thread
    • หากเห็นแบบ Tasks: 23, 10 thr แปลว่ากำลังแสดง thread อยู่
  • ใช้ Shift+K เพื่อสลับการแสดง kernel thread
    • หากเห็นแบบ Tasks: 23, 40 kthr แปลว่ากำลังแสดง kernel thread อยู่
  • ทุกครั้งที่โปรเซสใหม่เริ่มทำงาน จะมีการจัดสรร PID
    • หากรันแบบเบื้องหลังอย่าง sleep 1000 & จะแสดงหมายเลข job และ PID
    • $! ของ bash จะขยายเป็น ID ของโปรเซสเบื้องหลังล่าสุด
  • ข้อมูลเกี่ยวกับโปรเซสอยู่ใต้ /proc/<pid>/
    • /proc/<pid>/cmdline เก็บคำสั่งที่ใช้รัน และอาร์กิวเมนต์ถูกคั่นด้วยไบต์ \0
    • สามารถดูให้อ่านง่ายได้ด้วย tr '\0' '\n' < /proc/<pid>/cmdline หรือ strings /proc/<pid>/cmdline
    • /proc/<pid>/cwd เป็นลิงก์ไปยังไดเรกทอรีทำงานปัจจุบัน และ /proc/<pid>/exe เป็นลิงก์ไปยังไบนารีที่ถูกเรียกใช้
  • เครื่องมือวินิจฉัยอย่าง htop, top, ps อ่านรายละเอียดโปรเซสจาก /proc/<pid>/<file>
  • ฝั่งที่สร้างโปรเซสใหม่คือ parent process ส่วนฝั่งที่ถูกสร้างขึ้นใหม่คือ child process และความสัมพันธ์นี้ก่อให้เกิด process tree
  • กด F5 ใน htop เพื่อดูโครงสร้างลำดับชั้นของโปรเซส
    • ps f และ pstree -a ก็แสดงความสัมพันธ์เดียวกัน
  • เมื่อรัน date ใน bash ตัว bash จะสร้างสำเนาของตัวเองด้วย fork จากนั้นโหลด /bin/date เข้าในหน่วยความจำด้วย exec แล้ว bash ซึ่งเป็น parent จะรอให้ child จบการทำงาน
  • /sbin/init เริ่มทำงานตอนบูตและเรียก sshd ขึ้นมา เมื่อเชื่อมต่อผ่าน SSH ตัว sshd จะสร้างโปรเซสเซสชัน และเซสชันนั้นจะรัน shell bash

ผู้ใช้และสิทธิ์ของโปรเซส

  • แต่ละโปรเซสมีเจ้าของเป็นผู้ใช้ และผู้ใช้จะแสดงด้วย ID แบบตัวเลข
  • สามารถตรวจสอบ ID ผู้ใช้ของโปรเซสได้จากรายการ Uid ใน /proc/<pid>/status
  • คำสั่งอย่าง id 1000 จะแสดงชื่อผู้ใช้และกลุ่มที่ตรงกับ ID แบบตัวเลขนั้น
  • id เลือกแหล่งที่ใช้แปลงชื่อ ตามการตั้งค่าใน /etc/nsswitch.conf
    • ในระบบตัวอย่าง จะอ่าน /etc/passwd และ /etc/group
    • compat คือ Compatibility mode ซึ่งเหมือนกับ files แต่อนุญาตรายการพิเศษได้
    • ข้อมูลผู้ใช้อาจถูกเก็บไว้ในฐานข้อมูลหรือบริการอื่น เช่น LDAP ได้ด้วย
  • /etc/passwd และ /etc/group เป็นไฟล์ข้อความธรรมดาที่แมป ID แบบตัวเลขให้เป็นชื่อที่มนุษย์อ่านได้
  • ข้อมูลรหัสผ่านจริงอยู่ใน /etc/shadow
    • $6$ หมายถึงอัลกอริทึมแฮช sha512
    • ถัดจากนั้นจะเป็น salt แบบสุ่มเพื่อป้องกันการโจมตีแบบ rainbow table และ hash ของ password+salt
  • โดยพื้นฐานแล้ว โปรแกรมจะรันด้วยสิทธิ์ของผู้ใช้ที่สั่งรัน
    • แม้เจ้าของไฟล์ executable จะเป็นผู้ใช้อื่นก็ยังเป็นเช่นเดียวกัน
  • หากต้องการรันเป็นผู้ใช้อื่นหรือเป็น root ให้ใช้ sudo
    • sudo id จะรันด้วย UID 0 ของ root
    • สามารถรันเป็นผู้ใช้ที่กำหนดได้ เช่น sudo -u daemon id
  • หากพยายามเขียนลง /etc/sudoers โดยใช้ redirect โดยตรง อาจล้มเหลวได้ เพราะมีเพียง echo ที่รันเป็น root ส่วน append ถูกทำโดยผู้ใช้ปัจจุบัน
    • echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee -a /etc/sudoers
    • sudo bash -c "echo '$USER ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
  • ควรแก้ไข /etc/sudoers ด้วย sudo visudo
    • จะตรวจสอบเนื้อหาก่อนบันทึก เพื่อป้องกันความผิดพลาดที่ทำให้ใช้ sudo ไม่ได้
  • /usr/bin/passwd สามารถเขียนลง /etc/shadow ได้ แม้ผู้ใช้ทั่วไปจะเป็นคนรัน
    • ในสิทธิ์ไฟล์มี s จึงทำงานเป็นไฟล์ executable แบบ setuid
    • จะรันด้วยสิทธิ์ของ root ซึ่งเป็นเจ้าของไฟล์ executable
    • สามารถหาไฟล์ executable แบบ setuid ที่เป็นของ root ได้ด้วย find /bin -user root -perm -u+s

โค้ดสถานะของโปรเซส

  • คอลัมน์สถานะใน htop แสดงชื่อเป็น S และค่าหลักมีดังนี้
    • R: running หรือ runnable คือกำลังรันอยู่หรือรออยู่ใน run queue
    • S: interruptible sleep คือรอให้อีเวนต์เสร็จสิ้น
    • D: uninterruptible sleep โดยทั่วไปคือรอ I/O
    • Z: defunct zombie คือจบการทำงานแล้วแต่ parent ยังไม่ได้ reap
    • T: หยุดด้วย job control signal
    • t: หยุดโดย debugger ระหว่าง tracing
    • X: dead เป็นสถานะที่ไม่ควรปรากฏให้เห็น
  • ps ยังแสดง substate เช่น Ss, R+, Ss+ ด้วย
  • R: กำลังรันหรือพร้อมรัน

    • สถานะ R หมายถึงโปรเซสกำลังรันอยู่ในขณะนั้น หรือกำลังรอในคิวรัน
    • ซอร์สโค้ดของโปรแกรมเมื่อคอมไพล์แล้วจะกลายเป็นคำสั่ง CPU และเมื่อรันจะถูกโหลดเข้าเมโมรีเพื่อให้ CPU ประมวลผลคำสั่งเหล่านั้น
    • การที่กำลังรันอยู่หมายความว่า CPU กำลังประมวลผลคำสั่งทางกายภาพจริง ๆ
  • S: sleep ที่ interrupt ได้

    • ในสถานะ S คำสั่งของโปรเซสจะไม่ถูกประมวลผลบน CPU แต่กำลังรออีเวนต์หรือเงื่อนไขบางอย่าง
    • เมื่ออีเวนต์เกิดขึ้น เคอร์เนลจะเปลี่ยนสถานะเป็น running
    • sleep 1000 เป็นตัวอย่างของการรอเป็นเวลาที่กำหนด
    • สถานะนี้สามารถถูก interrupt ได้ด้วย signal
    • ใน htop สามารถกด F9 เพื่อส่ง signal ได้
    • kill คือ system call ที่ส่ง signal และ /bin/kill คือโปรแกรมใน userland ที่เรียกใช้สิ่งนี้
    • signal เริ่มต้นคือ TERM ซึ่งร้องขอให้โปรเซสสิ้นสุดการทำงาน
    • signal เป็นตัวเลข และชื่อมักเขียนเป็นตัวพิมพ์ใหญ่ โดยอาจมี prefix SIG
    • ตัวอย่าง: INT, KILL, STOP, CONT, HUP
    • kill -INT 10089, kill -2 10089, /bin/kill -2 10089 ทำงานเหมือนกัน
    • เมื่อกด CTRL+C bash จะส่ง SIGINT ไปยัง foreground process
    • การส่ง SIGINT หรือ SIGTERM ไม่ได้หมายความว่าโปรเซสจะต้องจบการทำงานเสมอไป
    • โปรแกรมสามารถตั้งค่า signal handler เพื่อจัดการ เช่น ทำงานเก็บกวาดก่อนแล้วจึงจบการทำงาน
    • SIGKILL หรือ 9 ทำให้เคอร์เนลบังคับจบโปรเซสโดยไม่ให้โอกาสโปรเซสตอบสนอง
  • D: sleep ที่ interrupt ไม่ได้

    • สถานะ D ไม่สามารถปลุกด้วย signal ได้ และเนื่องจาก SIGKILL ก็เป็น signal จึงไม่สามารถ kill โปรเซสแบบนี้ได้
    • สถานะนี้ใช้เมื่อโปรเซสจำเป็นต้องรอโดยไม่ถูกขัดจังหวะ หรือคาดว่าอีเวนต์จะเกิดขึ้นอย่างรวดเร็ว
    • ตัวอย่าง: disk read/write
    • uninterruptible process มักอาจเป็นสถานะที่รอ I/O หลังจาก page fault
    • สถานะนี้อาจเกิดขึ้นจากความล่าช้าในการอ่าน·เขียน NFS
    • อาจพบได้ในสถานการณ์ที่หน่วยความจำที่ใช้ได้มีน้อยเกินไปจนโปรเซสทำ swap จำนวนมาก
    • ตัวอย่างเช่น หากรัน sudo mount 8.8.8.8:/tmp /tmp & /sbin/mount.nfs จะอยู่ในสถานะ D
    • เมื่อดูด้วย strace จะเห็นว่า system call mount ทำให้โปรเซสถูก block
    • หากใส่ออปชัน intr ให้กับ mount จะทำให้รันแบบ interruptible ได้
    • sudo mount 8.8.8.8:/tmp /tmp -o intr
  • Z: โปรเซสซอมบี้

    • สถานะ Z คือสถานะที่โปรเซสจบการทำงานแล้ว แต่ parent ยังไม่ได้ reap
    • โปรเซสซอมบี้ที่มีอยู่ช่วงสั้น ๆ อาจเป็นเรื่องปกติได้
    • โปรเซสซอมบี้ที่ค้างอยู่นานอาจบ่งชี้ถึงบั๊กของโปรแกรม
    • โปรเซสซอมบี้ไม่ใช้หน่วยความจำ และครอบครองเพียง PID เท่านั้น
    • ไม่สามารถ kill โปรเซสซอมบี้โดยตรงได้
    • สามารถส่ง SIGCHLD ไปยัง parent process เพื่อร้องขอให้ reap ซอมบี้ได้
    • หาก kill parent process ก็สามารถลบ parent และซอมบี้ของมันได้
    • สามารถจำลองสถานะซอมบี้ได้ด้วยโปรแกรม C ที่หลัง fork แล้ว child เรียก exit(0) และ parent เรียก sleep(20)
    • เมื่อ parent จบลง ซอมบี้จะหายไป
    • เหตุผลที่ซอมบี้ยังคงอยู่คือ parent ต้องสามารถตรวจสอบ exit code ของ child ได้ผ่าน system call wait
  • T และ t: โปรเซสที่หยุดอยู่

    • สถานะ T คือสถานะที่ถูกหยุดด้วย job control signal
    • ระหว่างรัน cat /dev/urandom > /dev/null หากกด CTRL+Z จะเข้าสู่สถานะ T
    • สามารถรันต่อได้ด้วย fg
    • อาจหยุดด้วย signal STOP และกลับมาทำงานต่อด้วย signal CONT ได้เช่นกัน
    • สถานะ t คือสถานะที่หยุดระหว่างที่ debugger กำลัง tracing
    • หาก attach ด้วย sudo gdb -p <pid> ไปยังโปรเซสที่รันด้วย nc -l 1234 & จะเข้าสู่สถานะ t

เวลา CPU, niceness, priority

  • Linux เป็นระบบปฏิบัติการแบบ multitasking จึงทำให้ดูเหมือนว่ามีหลาย process ทำงานพร้อมกันได้ แม้บน CPU เพียงตัวเดียว
  • ในความเป็นจริง CPU ตัวเดียวสามารถรันคำสั่งได้ครั้งละหนึ่งคำสั่งเท่านั้น จึงใช้ time sharing
    • process หนึ่งทำงานช่วงสั้น ๆ แล้วถูกหยุด
    • process อื่นที่รอรันอยู่จะถูกนำมารันตามลำดับ
    • ช่วงเวลาสั้น ๆ ที่ process หนึ่งได้รันเรียกว่า time slice
  • โดยปกติ time slice มีความยาวเพียงไม่กี่มิลลิวินาที หาก system load ไม่สูงจึงแทบไม่รู้สึกถึงเรื่องนี้
  • หาก load average บน single core เป็น 1.0 ถือได้ว่า CPU ถูกใช้งาน 100%
    • หากสูงกว่า 1.0 แปลว่าจำนวน process ที่ต้องการรันมีมากกว่าที่ CPU จะประมวลผลได้ จึงอาจเกิด slowdown หรือ delay
    • หากต่ำกว่า 1.0 แปลว่า CPU อยู่ในสถานะ idle เป็นบางครั้ง
  • เหตุผลที่ running time ของ process อาจไม่เท่ากับเวลาที่ผ่านไปจริงอย่างแม่นยำ ก็อธิบายได้ด้วย time sharing
  • หากมี task ที่ต้องรันมากกว่าจำนวน CPU core ที่ใช้งานได้ ต้องตัดสินใจว่า task ใดควรถูกรันก่อน
  • scheduler ของ Linux kernel จะเลือก process ถัดไปจาก run queue โดยขึ้นอยู่กับอัลกอริทึม scheduler ของ kernel
  • โดยทั่วไปเราไม่สามารถควบคุม scheduler ได้โดยตรง แต่สามารถบอกได้ว่า process ใดสำคัญกว่า
  • niceness ที่แสดงเป็น NI คือ priority ฝั่ง user-space
    • ช่วงค่าคือ -20 ถึง 19
    • -20 คือ priority สูงสุด และ 19 คือ priority ต่ำสุด
    • process ที่ nice มากกว่า อาจมองได้ว่ายอมหลีกทางให้ process ที่ nice น้อยกว่า
  • PRI คือ priority ฝั่ง kernel-space ที่ Linux kernel ใช้
    • ช่วงค่าคือ 0 ถึง 139
    • 0~99 เป็น real time ส่วน 100~139 เป็นช่วงสำหรับ user
  • ความสัมพันธ์ระหว่างค่า nice กับ priority อธิบายได้ด้วย PR = 20 + NI
    • -20~+19 ของ NI จะกลายเป็น 0~39 ของ PR และถูก map ไปยัง 100~139
  • niceness ก่อนเริ่มรันตั้งค่าได้ด้วย nice -n niceness program
  • niceness ของ process ที่กำลังรันอยู่เปลี่ยนได้ด้วย renice -n niceness -p PID
  • สีของอัตราการใช้ CPU มีดังนี้
    • Blue: thread ที่มี priority ต่ำ, nice > 0
    • Green: thread ที่มี priority ปกติ
    • Red: kernel thread

ตัวชี้วัดหน่วยความจำ: VIRT, RES, SHR, MEM%

  • process ดูเหมือนว่ามีตัวเองอยู่ในหน่วยความจำเพียงลำพัง ซึ่งทำได้ด้วย virtual memory
  • process ไม่ได้เข้าถึง physical memory โดยตรง แต่มี virtual address space ของตัวเอง
  • kernel สามารถแปลง virtual memory address เป็น physical memory หรือ map บางส่วนไปยัง disk ได้
  • ด้วยเหตุนี้จึงอาจดูเหมือนว่า process ใช้หน่วยความจำมากกว่าหน่วยความจำที่ติดตั้งอยู่ในคอมพิวเตอร์
  • ปริมาณการใช้หน่วยความจำของ process จะแตกต่างกันตามว่าจะนับรายการต่อไปนี้รวมด้วยหรือไม่
    • shared library
    • disk-mapped memory
    • swapped out memory
  • สีของการใช้หน่วยความจำมีดังนี้
    • Green: used memory
    • Blue: buffers
    • Orange: cache
  • VIRT/VSZ

    • VIRT คือปริมาณ virtual memory ทั้งหมดที่ task ใช้
    • รวมถึง code, data, shared library, swapped out page และ page ที่ถูก mapped แล้วแต่ยังไม่ได้ใช้
    • แม้แอปพลิเคชันจะร้องขอ 1GB และใช้จริงเพียง 1MB ค่า VIRT ก็อาจแสดงเป็น 1GB ได้
    • แม้จะ mmap ไฟล์ขนาด 1GB แล้วไม่ได้ใช้จริง ค่า VIRT ก็อาจแสดงเป็น 1GB ได้
    • ในกรณีส่วนใหญ่ VIRT ไม่ใช่ตัวเลขที่มีประโยชน์
  • RES/RSS

    • RES คือ physical memory ที่ไม่ได้ถูก swapped out กล่าวคือปริมาณ resident memory ที่อยู่ใน physical memory ปัจจุบัน
    • RES อาจสะท้อนการใช้หน่วยความจำจริงได้ดีกว่า VIRT แต่ก็มีข้อจำกัด
    • ไม่รวม swapped out memory
    • หน่วยความจำบางส่วนอาจถูกแชร์กับ process อื่น
    • หาก process ใช้หน่วยความจำ 1GB แล้ว fork() ค่า RES ของ process ทั้งสองอาจดูเหมือนเป็น 1GB แต่ละตัว แต่จริง ๆ แล้วอาจใช้เพียง 1GB เนื่องจาก copy-on-write ของ Linux
  • SHR

    • SHR คือปริมาณ shared memory ที่ task ใช้
    • สะท้อนหน่วยความจำที่อาจแชร์กับ process อื่นได้
    • ตัวอย่างโปรแกรม C แสดงให้เห็นว่าค่า VIRT, RES, SHR เปลี่ยนไปอย่างไรผ่านขั้นตอน malloc, การใช้หน่วยความจำบางส่วน, fork และการเขียนหน่วยความจำเพิ่มเติม
    • ส่วนตัวอย่างหน่วยความจำดังกล่าวยังคงถูกทิ้งไว้เป็น TODO
  • MEM%

    • MEM% คือสัดส่วนของ available physical memory ที่ task ใช้อยู่ในปัจจุบัน
    • เป็นค่าที่ได้จากการนำ RES หารด้วย RAM ทั้งหมด
    • ตัวอย่าง: หาก RES เป็น 400M และ RAM เป็น 8GB จะได้ 400/8192*100 = 4.88%

โปรเซสพื้นฐานของ Ubuntu Server 16.04

  • สำรวจโปรเซสที่เริ่มทำงานบน Ubuntu Server 16.04.1 LTS x64 ของ Digital Ocean droplet ใหม่เอี่ยม

  • /sbin/init

    • /sbin/init ทำหน้าที่ประสานงานส่วนที่เหลือของ boot process และตั้งค่าสภาพแวดล้อมของผู้ใช้
    • กลายเป็น parent หรือ grandparent ของโปรเซสที่เริ่มทำงานโดยอัตโนมัติ
    • ผลลัพธ์ของ dpkg -S /sbin/init คือ systemd-sysv: /sbin/init ซึ่งในระบบนี้หมายถึง systemd
    • แม้จะ kill ก็ไม่เกิดอะไรขึ้น
  • /lib/systemd/systemd-journald

    • systemd-journald เป็น system service ที่รวบรวมและจัดเก็บ logging data
    • สร้างและดูแล structured, indexed journal จากข้อมูล log ที่ได้รับจากหลาย source
    • ใช้รูปแบบไฟล์พิเศษที่ปรับให้เหมาะกับ log message แทนไฟล์ log แบบข้อความธรรมดา
    • ดูได้ด้วย journalctl
    • journalctl _COMM=sshd
    • journalctl _COMM=sshd -o json-pretty
    • journalctl --since yesterday
    • journalctl -b
    • journalctl -f
    • journalctl --disk-usage
    • journalctl --vacuum-size=1G
    • ดูเหมือนจะลบหรือปิดใช้งานไม่ได้ ทำได้เพียงปิด logging เท่านั้น
  • /sbin/lvmetad -f

    • lvmetad cache metadata ของ LVM เพื่อให้คำสั่ง LVM อ่าน metadata ได้โดยไม่ต้อง scan disk
    • การ scan disk ใช้เวลาและอาจรบกวนการทำงานปกติของระบบและ disk
    • LVM มองได้ว่าเป็น “dynamic partitions” ที่สามารถสร้าง, resize และลบ logical volume ได้ขณะที่ Linux กำลังทำงาน
    • สรุปว่าหากใช้งาน LVM อยู่ก็ควรเก็บไว้
  • /lib/systemd/udevd

    • systemd-udevd ฟัง kernel uevent และรัน matching instruction ของ udev rules สำหรับแต่ละ event
    • udev เป็น device manager ของ Linux kernel และจัดการ device node ใน directory /dev เป็นหลัก
    • ไม่แน่ใจว่าจำเป็นสำหรับ virtual server หรือไม่
  • /lib/systemd/timesyncd

    • systemd-timesyncd เป็น system service ที่ซิงก์ local system clock กับ remote NTP server
    • ใช้แทน ntpd
    • ในระบบตัวอย่าง timedatectl status แสดง network time และ NTP synchronized เป็น yes
    • ในผลลัพธ์ netstat เห็นเฉพาะ SSH port ที่อยู่ในสถานะ listening และไม่ได้เปิด UDP 123 port หลายพอร์ตเหมือน ntpd ของ Ubuntu 14.04
  • /usr/sbin/atd -f

    • atd รัน job ที่ถูกใส่ไว้ใน queue เพื่อให้ทำงานในภายหลัง
    • at และ batch อ่านคำสั่งจาก stdin หรือไฟล์ แล้วนำไปรันภายหลัง
    • ต่างจาก cron ที่นัดหมายการทำงานซ้ำ ๆ at จะรันครั้งเดียว ณ เวลาที่กำหนด
    • ในตัวอย่างใช้ echo "touch /tmp/yolo.txt" | at now + 1 minute เพื่อสร้างไฟล์หลังจาก 1 นาที
    • หากไม่ใช้ ให้ลบด้วย sudo apt remove at -y --purge
  • /usr/lib/snapd/snapd

    • Snappy Ubuntu Core ถูกแนะนำว่าเป็น Ubuntu rendition ที่ใช้ transactional update
    • snap ถูกอธิบายว่าเป็น universal Linux package format ที่ทำให้ binary package เดียวทำงานได้บน Linux desktop, server, cloud และ device
    • เข้าใจได้ว่าเป็น deb package แบบ simplified ที่รวม dependency ไว้ใน snap เดียวเพื่อแจกจ่าย
    • เนื่องจากไม่เคย deploy หรือ distribute แอปพลิเคชันด้วย snappy บน server จึงลบด้วย sudo apt remove snapd -y --purge
  • /usr/bin/dbus-daemon

    • D-Bus เป็นกลไก IPC และ RPC ระหว่างหลาย process ที่รันพร้อมกันบน machine เดียวกัน
    • จำเป็นสำหรับ desktop environment แต่มีข้อสงสัยว่าจำเป็นสำหรับ server ที่รัน web app หรือไม่
    • เมื่อลบ dbus ออก timedatectl status ล้มเหลวด้วยข้อความ Failed to create bus connection: No such file or directory
    • ดังนั้นจึงสรุปว่าควรเก็บไว้
  • /lib/systemd/systemd-logind

    • systemd-logind เป็น system service ที่จัดการ user login
  • /usr/sbin/cron -f

    • cron เป็น daemon ที่รัน scheduled command
    • -f หมายถึง foreground mode คือไม่ daemonize
    • งานที่ต้องรันเป็นระยะสามารถนัดหมายด้วย cron ได้
    • crontab -e
    • สรุปว่าใน Ubuntu มักใช้ /etc/cron.hourly, /etc/cron.daily เป็นต้น
    • ดู log ได้ด้วยวิธีต่อไปนี้
    • grep cron /var/log/syslog
    • journalctl _COMM=cron
    • journalctl _COMM=cron --since="date" --until="date"
    • มีความเป็นไปได้สูงว่าจะเก็บ cron ไว้
    • หากไม่ลบ สามารถหยุดและปิดใช้งานด้วย sudo systemctl stop cron, sudo systemctl disable cron
    • apt remove cron อาจพยายามติดตั้ง postfix เป็นต้น
    • เพราะ cron suggest mail transport agent
  • /usr/sbin/rsyslogd -n

    • rsyslogd เป็น system utility ที่รองรับ message logging
    • ทำหน้าที่เติมไฟล์ log ใน /var/log/ เช่น /var/log/auth.log
    • ไฟล์ config อยู่ใน /etc/rsyslog.d
    • สามารถส่ง log ไปยัง server ระยะไกลเพื่อทำ centralized logging ได้
    • ใช้คำสั่ง logger เพื่อให้ background script เขียนข้อความลงใน /var/log/syslog ได้
    • แม้จะมี systemd-journald อยู่แล้ว แต่ rsyslog กับ journal มีคุณลักษณะต่างกัน จึงอาจมีกรณีที่ใช้ร่วมกันแล้วเป็นประโยชน์
    • ดังนั้นตอนนี้จึงเก็บไว้ก่อน
  • /usr/sbin/acpid

    • acpid เป็น ACPI event daemon
    • ออกแบบมาเพื่อแจ้ง ACPI event ให้ user-space program
    • ACPI ใช้กับ hardware component discovery/configuration, power management, status monitoring เป็นต้น
    • เนื่องจากไม่ได้ตั้งใจใช้ suspend/resume บน virtual server จึงลองลบออก
    • reboot สำเร็จ แต่หลังจาก halt แล้ว Digital Ocean ยังคงรับรู้ว่าเปิดอยู่ จึงต้อง Power Off จาก web interface
    • ดังนั้นจึงสรุปว่าควรเก็บไว้
  • /usr/bin/lxcfs /var/lib/lxcfs/

    • lxcfs เป็น FUSE filesystem ที่ออกแบบมาสำหรับ LXC container
    • ให้ virtualized view ของไฟล์บางส่วนใน /proc และ filtered access ไปยัง host cgroup filesystem
    • ทำให้ uptime, top เป็นต้นภายใน container ให้ผลลัพธ์ที่ “ถูกต้อง” มากขึ้น
    • หากไม่ได้ใช้ LXC container สามารถลบด้วย sudo apt remove lxcfs -y --purge
  • /usr/lib/accountservice/accounts-daemon

    • AccountsService ให้ D-Bus interface และ implementation สำหรับ query และจัดการข้อมูล user account
    • implementation อิงตามคำสั่ง usermod(8), useradd(8), userdel(8)
  • หลังลบออกแล้ว อะไรจะพังบ้างนั้นปล่อยให้ “Time will tell”

  • /sbin/mdadm

    • mdadm เป็นยูทิลิตีของ Linux สำหรับจัดการและมอนิเตอร์อุปกรณ์ software RAID
    • RAID คือวิธีใช้ hard drive หลายลูกให้เหมือนเป็นลูกเดียว
    • RAID 0 ใช้เพื่อขยายความจุของ drive
    • RAID 1, RAID 5, RAID 6, RAID 10 มีจุดประสงค์เพื่อป้องกัน data loss เมื่อ drive failure
    • สามารถลบออกได้ด้วย sudo apt remove mdadm -y --purge
  • /usr/lib/policykit-1/polkitd --no-debug

    • polkitd คือ PolicyKit daemon และ polkit เป็น Authorization Framework
    • เข้าใจได้ว่าเป็น sudo แบบ fine-grained
    • สามารถให้สิทธิ์แก่ non-privileged user ในการทำ action บางอย่างในฐานะ root ได้
    • ตัวอย่าง: อนุญาตให้ reboot บน desktop Linux
    • สำหรับ server สรุปไว้ว่าสามารถลบออกได้ด้วย sudo apt remove policykit-1 -y --purge
    • แต่อะไรจะพังบ้างยังคงเป็นคำถามอยู่
  • /usr/sbin/sshd -D

    • sshd คือ OpenSSH Daemon
    • ตัวเลือก -D ทำให้ไม่ detach และไม่กลายเป็น daemon ช่วยให้ monitoring ได้ง่ายขึ้น
  • /sbin/iscsid

    • iscsid เป็น background daemon ที่ทำงานตาม iSCSI configuration และจัดการ connection
    • iSCSI เป็นมาตรฐาน storage networking บน IP ที่ส่ง SCSI command ผ่าน IP network ทำให้ใช้ remote storage ได้เหมือน local disk
    • สามารถลบออกได้ด้วย sudo apt remove open-iscsi -y --purge
  • /sbin/agetty --noclear tty1 linux

    • agetty คือ alternative Linux getty
    • getty จัดการ physical หรือ virtual terminal และเมื่อพบการเชื่อมต่อจะเปิด username prompt จากนั้นรันโปรแกรม login
    • บน Digital Ocean สามารถโต้ตอบกับ terminal นี้ผ่าน browser ได้จาก Console ใน droplet details
    • เมื่อลบไฟล์ที่เกี่ยวข้องกับ getty@tty1.service แล้ว reboot ยังเชื่อมต่อ SSH ได้ แต่ไม่สามารถ login ผ่าน Digital Ocean web console ได้
  • เซสชัน SSH, bash, htop

    • sshd: root@pts/0 หมายความว่า SSH session ของผู้ใช้ root ถูกตั้งค่าไว้บน pseudoterminal pts/0
    • pseudoterminal จำลอง text terminal จริง
    • bash คือ shell ที่กำลังใช้งาน
    • ถ้ามี dash นำหน้าอย่าง -bash แปลว่าเริ่มต้นเป็น login shell
    • shell ที่อักขระแรกของ argument zero เป็น - หรือเริ่มด้วย option --login คือ login shell
    • ในกรณีนี้จะอ่าน configuration file set อีกชุดหนึ่ง
    • htop คือ interactive process viewer ที่กำลังรันอยู่ใน screenshot

การทดลองลบบริการ

  • รายการลบทั่วไปมีดังนี้
    • sudo apt remove lvm2 -y --purge
    • sudo apt remove at -y --purge
    • sudo apt remove snapd -y --purge
    • sudo apt remove lxcfs -y --purge
    • sudo apt remove mdadm -y --purge
    • sudo apt remove open-iscsi -y --purge
    • sudo apt remove accountsservice -y --purge
    • sudo apt remove policykit-1 -y --purge
  • Extreme edition รวมงานต่อไปนี้ด้วย
    • sudo apt remove dbus -y --purge
    • sudo apt remove rsyslog -y --purge
    • sudo apt remove acpid -y --purge
    • sudo systemctl stop cron && sudo systemctl disable cron
    • sudo rm /etc/systemd/system/getty.target.wants/getty@tty1.service
    • sudo rm /lib/systemd/system/getty@.service
  • คอนฟิก nginx, PHP7, MySQL ที่ทำตามคำแนะนำ unattended installation of WordPress on Ubuntu Server ใช้งานได้

ภาคผนวก: เครื่องมือสำรวจและพฤติกรรมของ shell

  • การค้นหาซอร์สโค้ด

    • เมื่อใช้แค่ strace ยังไม่พอ สามารถดู source code ได้
    • หา location ของ binary ด้วย which uptime แล้วหา Ubuntu package ด้วย dpkg -S /usr/bin/uptime
    • ในตัวอย่าง uptime อยู่ใน package procps
    • สามารถค้นหา package ที่ packages.ubuntu.com และหา link ไปยัง source repository ได้
  • file descriptor และ redirection

    • เมื่อต้อง redirect stderr ไปยัง stdout ให้ใช้ 2>&1
    • echo something > file คือการเขียน stdout ลง file และเหมือนกับ echo something 1> file
    • echo something 2> file เขียน stderr ลง file
    • echo something 2>1 หมายถึง redirect stderr ไปยัง filename ชื่อ 1
    • ใน 2>&1 ที่มี & นั้น 1 ไม่ใช่ filename แต่เป็น stream ID
  • ปัญหาสีของ PuTTY

    • หากองค์ประกอบของ htop ดูเหมือนหายไปใน PuTTY สามารถแก้ได้ที่การตั้งค่า Window → Colours
    • คลิกขวาที่ title bar
    • Change settings...
    • Window → Colours
    • เลือก Both radio button
    • Apply
  • shell แบบง่ายที่เขียนด้วย C

    • shell แบบง่ายที่เขียนด้วย C แสดงการใช้ system call fork, exec, wait
    • หาก input เป็น exit จะออกจากโปรแกรมด้วย shell built-in
    • คำสั่งอื่น ๆ จะ fork แล้วให้ child รันด้วย execlp ส่วน parent รอสถานะการจบด้วย waitpid
    • ตัวอย่างการรัน date, true, false จะแสดง child exit code ตามลำดับ
    • เหตุผลที่ข้อความจบของ background process อย่าง sleep 1 & จะแสดงก็ต่อเมื่อกด Enter แล้ว คือ shell กำลังรอ input และจะตรวจสอบสถานะของ background process ตอนมีการป้อนคำสั่ง

รายการที่เหลือต้องสำรวจและประวัติการแก้ไข

  • รายการที่อยากศึกษาเพิ่มเติม ได้แก่ process state substatus, kernel thread, /dev/pts, หน่วยความจำ CODE·DATA·SWAP, ความยาว time slice, อัลกอริทึม Linux scheduler, core pinning, manual page, สีของ CPU/memory bar, process ID limit และ fork bomb, lsof, ionice, schedtool เป็นต้น
  • การแก้ไข·อัปเดตหลักมีดังนี้
    • idle time ของ /proc/uptime เป็นผลรวมของทุก core
    • แก้ printf ของ parent/child ในตัวอย่าง zombie C
    • เพิ่มว่า apt remove cron จะพยายามติดตั้ง postfix เนื่องจาก dependency ของ MTA
    • id สามารถโหลดข้อมูลจาก source อื่นนอกจาก /etc/passwd ผ่าน /etc/nsswitch.conf ได้
    • เพิ่มคำอธิบาย password hash format ของ /etc/shadow
    • ควรแก้ไข /etc/sudoers อย่างปลอดภัยด้วย visudo
    • เพิ่มคำอธิบาย MEM%
    • เขียนส่วน load average ใหม่
    • แก้ไขว่า signal เริ่มต้นของ kill 1234 ไม่ใช่ INT แต่เป็น TERM
    • เพิ่มคำอธิบาย CPU และ memory color bar

1 ความคิดเห็น

 
GN⁺ 5 시간 전
ความคิดเห็นจาก Hacker News
  • ช่วงหลังผมย้ายมาใช้ btop แล้ว อินเทอร์เฟซดูทันสมัยเท่าที่ต้องการ ใช้งานได้ดี และให้ข้อมูลมากพอ
    อย่างที่คนอื่นพูดกัน ดูเหมือนจะแสดงการใช้พลังงาน (Watts) ด้วย และยังมีข้อมูลเครือข่าย, GPU, ดิสก์มาพร้อมกัน
    https://github.com/aristocratos/btop

    • btop ดี แต่ก็มีข้อเสีย: ไม่มี สถิติ zram/zswap (htop ก็รองรับแค่ zram), ไม่มีการแยกรายละเอียดสถิติ ZFS และยังไม่รองรับ Arc GPU
      ปิดแถบการใช้งานดิสก์ไม่ได้ ทำให้ถ้าหน้าต่างคอนโซลไม่ใหญ่มาก กราฟความเร็ว I/O จะถูกบีบจนดูอึดอัดมาก
    • ใช้ btop มานานแล้ว สิ่งที่ขาดไปก็ประมาณ คอลัมน์พอร์ต อีกคอลัมน์ข้าง ๆ คอลัมน์อื่น
      กราฟ CPU/GPU กินพื้นที่มากเกินไป และโดยรวมอยากให้ตารางไฟล์ที่เปิดอยู่ใช้พื้นที่มากกว่านี้
    • ยังมีบางครั้งที่ใช้ Alpine เป็นอิมเมจพื้นฐานของคอนเทนเนอร์ แต่ดูเหมือน btop จะไม่รองรับ musl เลยต้องตัดออก
    • เป็นสาวก btop เลยถึงขั้นใช้แทน iStatMenu บน MacBook เครื่องใหม่ด้วย
  • มีการตั้งค่า 2 อย่างที่ผมเปลี่ยนทุกครั้งเวลาใช้ htop และมันต่างกันมาก
    อย่างแรก ปิด เธรดของผู้ใช้ โดยมากมันแค่ทำให้หน้าจอ htop รก และแทบไม่ให้ข้อมูลที่เป็นประโยชน์
    อย่างที่สอง เปิด มุมมองต้นไม้ของโปรเซส บ่อยครั้งการรู้ว่าโปรเซสเริ่มมาจากไหนสำคัญกว่าข้อมูลอื่น ๆ และยังช่วยติดตามสิ่งอย่างโปรเซสคอมไพเลอร์ที่ประมวลผลไฟล์จำนวนมากและกิน CPU ได้ง่ายขึ้น
    ส่วนตัวคิดว่าทั้งสองอย่างควรเป็นพฤติกรรมเริ่มต้นของ htop

    • มุมมองต้นไม้ของโปรเซสดี แต่พอเปิดแล้ว การอัปเดตและจัดเรียงใหม่แบบไดนามิก ของรายการโปรเซสจะหยุดไป น่าเสียดาย
  • ดีใจที่มีคำอธิบายว่าความจำเสมือนไม่น่าเชื่อถือเท่าไร วิธีที่ Windows Task Manager แสดงเป็นค่าเริ่มต้นก็ไปทางนี้เลย แย่มาก
    Resident Set Size (RSS) เป็นตัวชี้วัดที่เชื่อถือได้ที่สุด และค่าอื่น ๆ อาจถูกขยายจนผิดเพี้ยนเพราะสิ่งอย่างไฟล์ที่แมปเข้าหน่วยความจำ ซึ่งในความเป็นจริงไม่ได้ก่อปัญหา
    เช่น ต่อให้แมปไฟล์ล็อก 2GB เข้าหน่วยความจำ ส่วนนั้นจะถูกโหลดเป็นเพจเฉพาะตอนอ่านเท่านั้น ไม่ได้ใช้หน่วยความจำจริง ๆ แต่ผู้ใช้เห็นโปรเซสแล้วก็พูดว่า “ทำไมแอปนี้ใช้เมมเยอะขนาดนี้”
    Chrome ก็เคยเจอปัญหานี้อยู่ช่วงหนึ่งจนลดการใช้ไฟล์ที่แมปเข้าหน่วยความจำ ไม่ใช่เพราะไฟล์ที่แมปเข้าหน่วยความจำไม่ดี แต่เพราะผู้ใช้เห็นค่าที่ไม่ใช่การใช้หน่วยความจำกายภาพจริงแล้วตอบสนองเกินเหตุ
    บนเว็บยังมีไกด์ที่บอกให้ตัดสินการใช้งานจากปริมาณการจองหน่วยความจำเสมือนด้วย อย่างน้อยบทความนี้ก็ชี้ประเด็นส่วนนั้นได้ถูกต้อง

    • จริง ๆ แล้ว Proportional Set Size (PSS) แม่นยำกว่า RSS
      อ้างอิง: https://en.wikipedia.org/wiki/Proportional_set_size
    • ถ้าใช้ไฟล์ที่แมปเข้าหน่วยความจำ เพจที่ถูกแคชจะถูกรวมอยู่ใน Resident Set Size ของโปรเซสนั้น
      ถ้าใช้ I/O ไฟล์แบบปกติจะไม่ถูกรวม ในคลัสเตอร์ HPC ที่คอยเฝ้าดูการใช้หน่วยความจำของแต่ละงานแล้วฆ่าทิ้งเมื่อเกินปริมาณที่ขอไว้ จึงเกิดผลลัพธ์ที่ค่อนข้างน่าสนุก
    • Resident Set Size ไม่ใช่ปริมาณหน่วยความจำที่โปรเซสต้องการ แต่คือ ปริมาณที่ระบบปฏิบัติการตัดสินใจให้โปรเซสนั้น
      เมื่อเริ่มมีแรงกดดันด้านหน่วยความจำ มันก็ไม่เป็นตัวแทนที่ดีอีกต่อไป ผมเคยเห็นการตัดสินใจผิด ๆ หลายครั้งเพราะความเข้าใจผิดนี้ และเคยถึงขั้นเอาค่านี้ออกจากชาร์ตเพื่อกันไม่ให้สมาชิกทีมตีความกลับด้าน
    • พูดให้ถูกคือ Windows Task Manager ใช้ Private Working Set เป็นค่าเริ่มต้นสำหรับการใช้หน่วยความจำของโปรเซส และไม่รวมเพจที่แชร์กับโปรเซสอื่น เช่น ไลบรารีหรือไฟล์ที่แมปเข้าหน่วยความจำ
      ตามชื่อ มันแสดงเฉพาะส่วนที่แมปไปยังหน่วยความจำกายภาพซึ่งจัดสรรแบบส่วนตัวต่อโปรเซส และใกล้เคียงกับ Resident Set ของ Unix มากกว่า
      เดาว่าน่าจะหมายถึงการใช้หน่วยความจำในแท็บ Performance แต่คนอาจเข้าใจผิดว่าเป็นรายการการใช้หน่วยความจำทั้งหมด เลยแยกไว้ให้ชัดเจน
  • ใน top ถ้าใช้ตัวอักษร > จะเป็น การจัดเรียงตามการใช้หน่วยความจำ
    ใช้เป็นครั้งคราวเวลาไล่หาว่าทำไมโฮสต์ช้า และยังเห็นได้ด้วยว่า swapd กิน CPU อยู่

    • ผมชอบใช้ M ตัวใหญ่สำหรับหน่วยความจำ และ P ตัวใหญ่สำหรับ CPU มากกว่า
  • เวลาอ่านบทความแบบนี้ก็ทำให้รู้ว่าแม้จะใช้ Linux ทุกวันมานานกว่า 20 ปีแล้ว ก็ยัง ใช้ศักยภาพได้แค่บางส่วน อยู่ดี เป็นบทความที่ดี

  • รู้สึกเหมือน HN กำลังฟื้นตัวกลับมา
    หวังว่านี่จะไม่ใช่ช่วงซอมบี้เดินได้ของ HN

    • หน้าแรกมีบทความเกี่ยวกับ AI อยู่ 3 บทความ แต่หนึ่งในนั้นเป็นบทความด่างานสร้างคุณภาพต่ำ เลยพอมีความหวัง
    • ดูเหมือนกำลังฟื้นตัวโดยย้อนกลับไปเป็น บทความก่อนยุคสลอปเมื่อ 7 ปีก่อน
  • ใครไม่รู้จัก nmon ก็น่าลองดูเหมือนกัน
    กด h จะแสดงรายการมอนิเตอร์ที่ใช้ได้ กดอีกครั้งจะหายไป และออกด้วย q
    https://nmon.sourceforge.io/pmwiki.php
    โดยเฉพาะ throughput ของดิสก์และ I/O ที่ดูด้วยปุ่ม d และ D ค่อนข้างมีประโยชน์

    • รู้จักมันจากเครื่อง AIX ที่ใช้ในที่ทำงาน และทำให้นึกถึง topas ด้วย
    • เป็นเครื่องมือที่มีประโยชน์มาก เลยติดตั้งไว้ในทุกเครื่องที่ผมควบคุมได้
      ชอบที่ กราฟการใช้ CPU แบบ Wide จัดการกับจำนวนคอร์มาก ๆ ได้ง่าย
  • ในแง่วิธีใช้งานที่ต่างจากพวก *top ผมเริ่มชอบรายงานแบบ diff สไตล์ ps ที่นิ่ง ๆ และรายงานทั้งระบบแบบ vmstat มากกว่า
    วิธีนี้ทำให้ทุกอย่างยังคงอยู่ในบัฟเฟอร์ scrollback ของเทอร์มินัล: https://github.com/c-blake/procs
    เขียนด้วยภาษา Nim ซึ่งมีประสิทธิภาพและสื่อความหมายได้ดีอย่างไม่ค่อยพบ

  • บุ๊กมาร์กบทความนี้ไว้ตั้งแต่ปี 2016 และกลับมาอ้างอิงซ้ำหลายครั้งตลอดหลายปี