Author Archives: Enrico

GNU readline cheatsheet

在 Linux環境中,command line如bash或是interpreter如python常常有支援readline的keymap,以下整理常用的快速鍵,其他可參考以下連結 https://en.wikipedia.org/wiki/GNU_Readline 移動游標 Ctrl + f : move forward 1 character → Ctrl + b : move backward 1 character ← Alt + f : move forward 1 word Alt + b : move backward 1 word Ctrl … Continue reading

Posted in System Administration | Leave a comment

WebSocket node.js ws 註解整理 – 1

這裡 註解 整理在Node.js中,WebSocket client/server常用的實現 ws 套件的程式碼 https://github.com/websockets/ws 關於WebSocket protocol,可參考另一篇文章的整理 index.js 所有的implementation在lib資料夾,大約3600行,算是一個輕量的實現,可先從index.js export的WebSocket開始追起,這也是一般js WebSocket client使用的class,WebSocket client API在實現上也是參考 browser使用的API,所以https://developer.mozilla.org/en-US/docs/Web/API/WebSocket 也要一併參考 以下逐行整理註解lib/websocket.js lib/websocket.js 上面可以看到支援的兩個version 8、13 8主要是對應https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-08 開始的版本到 -12 ,13主要是對應 https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-13 開始的版本,不過實際上支援的程度或相容性仍要看實作細節 繼承 EventEmitter,可參考 Nodejs Events整理的說明 constructor的部分: 接下來從constructor內的initAsClient往下追 以下設置http req,透過http.get function,可參考: https://nodejs.org/docs/latest-v12.x/api/http.html#http_http_request_options_callback 上面的error event … Continue reading

Posted in nodejs | Leave a comment

Nodejs Events 整理

Nodejs Events module是一個很重要的元件,主要原因是在asynchronous programming,Node.js在Javascript的語言層面提供了如callback、Promise、async/await等機制,這些機制都是類似於request-response的概念,也就是先發起一個function call,等待function call回應,可以對於notification類型,特別是event driver programming,就必須使用callback方式。在browser的DOM規範中,也有定義類似的介面EventTarget https://dom.spec.whatwg.org/#interface-eventtarget 主要就是定義註冊管理使用callback function的介面 event driven programming的特色就是將event透過handler/listener function來處理,並且event的時間點不確定,所以handler/listener callback function的角色是被動的,有什麼event過來就處理什麼event,event可以是新的資料,譬如說網路socket接收到的內容,也可能是狀態的改變,譬如說XMLHttpRequest的progress event。 在瀏覽器的javascript,因為UI有各種IO原始事件(滑鼠、鍵盤),進而在瀏覽器產生對應出衍生的UI事件。在Nodejs更多的IO操作也是透過event傳達狀態改變,例如’open’, ‘ready’等。或是如Readable stream的’data’ 在Node.js中,按照習慣,會發出event的object繼承於EventEmitter,透過.on(eventName, eventHandler/Listener) 來接收event,並且eventName建議是以camel case的方式命名,只是Nodejs大部分的event不需要用到第二個字,所以常見的都只是小寫event name 這裡節錄一段官方文件的範例,透過extends EventEmitter方式,使物件具有收發event的能力,emit透過 function argument,傳遞eventName之外的其他資訊。 .on呼叫的callback不應該是async function,並且callback被呼叫的順序是按照註冊的順序被 synchronously呼叫,另外也有一個.once 的API,主要用於handler/listener只一次性處理event,可參考另一篇文的說明 在Node.js中,錯誤處理有兩類,一種是js exception機制,synchronous function call內部透過throw,可以將錯誤傳遞出來,另外一種是callback中帶err argument,但這些都是function call流程很明確的時候。event … Continue reading

Posted in nodejs | 1 Comment

WebSocket protocol整理

WebSocket作為在HTTP下一個很重要的雙向通信延伸的protocol,HTTP 1.0/1.1的設計是half-duplex,也就是同一個時間只會有單向傳輸(request->response),雖然HTTP 1.1有支援http pipelining,但本質上他還是單向傳輸的的架構(第二個request不用等到第一個response收到就可以發出,但是response order還是根據request),並且這項功能在大部分的client/server實作不完整 WebSocket出現於2009年左右(並於Chrome 4開始實作支援),在此之前要在Web上透過HTTP protocol進行雙向通信,需要用一些技巧模擬出來 因為HTTP 通信是half-duplex,從web browser client的角度,browser可以知道什麼時候要send資料,隨時可以由browser發起http request,而recv則是由server傳來的資料,但是在http request-response的架構下,因為不知道server什麼時候有資料,最簡單的做法就是要定期去polling,這個在早期的聊天室系統都是這樣處理,每隔幾秒鐘就發一次http request更新最新的內容,但是這樣做有個缺點 – 不即時 即時性的問題在後來發展出hidden iframe以及long polling兩種做法,以兩種做法解決問題主要是因為browser的限制(browser只支援單純的http request-response),雖然在HTTP協定中其實有定義可以做雙向通信的,像是HTTP/1.1 CONNECT(主要用在tunnel proxy情境),或是HTTP/1.1 Upgrade header,但是tunnel或是upgrade完的通信方式要由app決定。 hidden iframe的做法算是巧妙地利用browser load javascript的行為,他透過inline iframe建立起一個隱藏的iframe,在iframe裡面load一個特別的網頁,那個網頁會一直傳<script>,將要server通知的內容即時透過<script>結合javascript,在裡面嵌code和data,因為browser收到script會立即執行,並且按順序執行,透過巧妙地安排script內容,將訊息傳出來給parent page,因為網頁還沒load完,連線就會一直持續 long polling則是透過http XMLHttpRequest方式,連上server後,在沒有新的event data情況下,server就掛起連線,等有資料再response,當client收完資料後連線結束,再馬上發起新的long polling request,這個好處是可以即時的收到event data,缺點是XMLHttpRequest browser有一些限制(例如cross origin等問題),以及每次HTTP … Continue reading

Posted in Network | 1 Comment

linux ls -l

整理一下 ls -l 相關的內容意義 ls -l 預設顯示第一欄是file type/ permissions / attributes, 第一各字元是file type,d代表 directory,l代表 symbolic link, 在linux中總共有7種file type,分別是 – : regular file d : directory l : symbolic link c : character device file b : block device file s : local socket file p : named … Continue reading

Posted in System Administration | Leave a comment

sudo note

在Linux中,使用者取得root權限執行可以透過sudo 或是 su root (直接切換成root),差別是sudo 是不需要知道root密碼的,並且可以透過定義sudoer限制可使用的命令。修改/etc/sudoers,透過visudo command 在CentOS中, 定義了 wheel group有sudo權限,可將使用者直接加入wheel群組 usermod –aG wheel username 上面除了定義wheel群組,也定義了root使用者,當然root本身就具有最高權限了,會在sudoers定義最主要是因為讓root不會因為用sudo命令被擋下來 例如將 root那行註解後,(以root身分) 輸入 sudo ls會失敗 在Ubuntu中,則是定義了admin 和 sudo group,不過admin group是早期Ubuntu 11及之前在使用的,在Ubuntu 12後不使用 如過要讓使用者sudo 時不需再輸入密碼,可以在檔案的最後面加上 user ALL=(ALL) NOPASSWD:ALL 如果不在最後面加上,則會以最後一筆match的設定apply,以ubuntu預設建立的使用者來說,會自動加進sudo group,所以會導致上面的設定被override When multiple entries match for … Continue reading

Posted in System Administration | Leave a comment

docker-compose project name

docker-compose透過docker-compose.yml檔案描述的方式,操作docker container,特別是multi containers的情境,讓使用和管理上變得很容易,不過需要注意的是 docker compose是透過project name來識別要操作的container,例如啟動、停止等。 一般來說,啟動就只要下docker-compose up就可以,不同的container是isolated,但是在某些情境,對於不同的docker-compose.yml下 docker-compose up有可能會互相干擾,例如以下,起始一個container name為testm2 docker instance 在另一個資料夾下的啟動testm3 上面出現了recreating testm2,查看container list,testm2消失,取代的是testm3 而原來testm2也顯示被踢掉了 這表示testm2被停掉,主要的原因是project name相同 直覺上會覺得container name不同應該就會不會衝突,事實上docker compose是透過project name來管理,參考: https://docs.docker.com/compose/ The default project name is the basename of the project directory. You can set a … Continue reading

Posted in System Administration | Leave a comment

yum repo sync to local

要複製remote yum repo到local有兩種方式 rsync reposync 但不是所有的remote repo都提供rsync存取權限,例如vault.centos.org就無法使用(https://lists.centos.org/pipermail/centos-mirror/2013-April/007069.html 裡面提到將rsync關掉了) https://vault.centos.org/readme.txt The Following External Vault mirrors (not monitored by the CentOS Infra team !) also provide direct downloads for all content, including isos and rsync access: USA: http://archive.kernel.org/centos-vault/ rsync://archive.kernel.org::centos-vault/ Europe: http://mirror.nsc.liu.se/centos-store/ rsync://mirror.nsc.liu.se::centos-store/ … Continue reading

Posted in System Administration | Leave a comment

CentOS 6 docker yum更新

在centos 7環境下跑centos 6 docker image docker run -it centos:6 下 yum update 報錯,顯示無法retrieve repomd.xml 確認一下原因,主要是因為 centos 6在2020 Nov就停止支援了,參考https://forums.centos.org/viewtopic.php?t=72710 Red Hat have pulled the plug on RHEL 6.x as of Nov 30th 2020 and as a result CentOS 6 is now … Continue reading

Posted in System Administration | Leave a comment

rsyslog in docker environment

在docker中,預設沒有啟用systemd所需要的 CAP_SYS_ADMIN  privileged capabilities,因此在執行服務時,一般採用直接執行process的方式而不透過systemd控制(systemctl) 不過rsyslogd在CentOS預設是透過journald讀取syslog,journald在systemd的架構下主要處理來自systemd service的stdout/stderr、以及syslog(透過/run/systemd/journal/dev-log,並將/dev/log symlink到前述位置),以及處理systemd forward log到 /run/systemd/journal/syslog (須設定ForwardToSyslog開啟,新版本的rsyslogd已經直接讀取journal,不再使用此方式) 如果要跑journald則需要對docker另外開一些capabilites(可參考systemd的service裡面的CapabilityBoundingSet設定,雖然部分應該是處理kern log),另外要處理listen unix socket的設定(描述在/lib/systemd/system/systemd-journald.socket、/lib/systemd/system/syslog.socket) ,因此最簡單的方式就是直接讓rsyslog listen unix socket /dev/log,並且如果不用systemd,單純使用syslog的話沒有理由需要透過journald來處理。 在/etc/rsyslog.conf 將所有journald相關的設定註解,並且開啟imuxsock 並且刪掉 /etc/rsyslog.d/listen.conf 啟動rsyslogd就可以正常運行將syslog寫入到對應的log檔 以 logger測試 值得一提的是 因為透過imuxsock 模組讀取log,是透過 /dev/log unix socket 讀取log 而這個socket是由 rsyslogd產生的,logger預設也是寫入此socket 可參考 util-linux/logger.c 另外docker執行時,一般習慣上是用foreground執行,rsyslogd預設是會跑在背景,並且會做fork,這對於在整合一些process manager如supervisor或是chapterone的工具無法正確追蹤process是否正確執行,或是要設定專門的rsyslog … Continue reading

Posted in System Administration | Leave a comment