ArozOS 1.110 穩定版發佈賀圖
就是因為與 Alanyeung 說到要不要在 ArozOS 1.0 首個 Stable release 的時候興祝一下,於是說著說著就說到了關於「不如畫一張賀圖出來」這樣的話題。 嘛,畫賀圖倒是沒問題啦,問題是誰畫? 結果因為只有 500 港幣預算問題,香港和台灣的繪師都敲不動,跑去了外國看看有沒有人願意接。想不到以同樣的金額還意外的多人畫,而且有的質素也十分不錯。 來自某 Freelance 網站截圖 結果我們就把繪圖要求外判出去,然後最近成品終於回來了。 這比我想像中的還要好啊啊啊(咳咳 就是這樣,我們就用這張立繪來做 1.110 Release 賀圖了! 設計中的 ArozOS 1.110 Release 賀圖
Go 語言在 Linux IoT 開發板上處理大檔案上傳的解決方法
近年來不少本來用於物聯網開發的主板已經差不多具備 10 年前電腦主機的 IO 速度和處理水平了。在網上不難看到具備 1000Mbps 網絡接口並同時使用多核心的處理器的單片電腦(SBC),價格上也不太貴(約 100 - 120HKD 一塊),可玩性還是很高的。 其中我使用過的兩種開發板:ZeroPi 跟 OrangePi Zero Plus 然後,我想用它來組網絡儲存系統 對,理論上你是可以用這種 SBC 來做網絡儲存器(NAS),我們一個一個來看: ✔️ CPU: H3 / H5 處理器 ( 1.3Ghz ,一般作為文件伺服器完全沒問題) ✔️ 1000Mbps Ethernet / 網絡接口 ✔️ USB2.0 接口(480Mbps,對於家中只有 100Mbps 上下載的我來說完足夠) ✔️ 40 x 42 cm,可以直接黏在硬碟盒後面 ✔️ 運行時只需要 5V 0.2 - 0.3A,超級省電 可是問題就是它只有 512MB 的 RAM 啊!!! 現在這年代連最便宜的 Synology DS118 都要比它多 512MB RAM 啊! 可是,要這麼多 RAM 到底用來幹麼? Golang 網頁伺服器的文件上載的運作原理 一般來說使用 Golang 處理文件上載的邏輯都長這樣 r.ParseMultipartForm(10 << 20) file, handler, err := r.FormFile("myFile") if err != nil { fmt.Println("Error Retrieving the File") fmt.Println(err) return } defer file.Close() //然後用 io.Copy 把暫存檔案複制到目的地,這裡我就不仔細寫了 在一般電腦上運行這段代碼是完全 OK 的,在上載檔案時 Golang 會把 multipart form data 中的檔案緩存到 RAM,然後在 io.Copy 之後,defer 的 file.Close() 會把 Reader 關掉,之後交由 GC 處理刪除。 這情況只能適用於上載的檔案比系統能用的 RAM 還要細的情況,對於像 ZeroPi / Orange Pi 這種 SBC 要上載大型檔案,就不能用這傳統的方法,而需要特別處理了。不然就會出現以下情況 就是所謂的「爆 RAM」 那讓我們先來了解一下 parseMultipartForm 的原理吧,簡單來說是 你的 browser 把檔案塞到了一個 HTTP FORM 裡面browser 把 FORM 的資料連同你要的檔案在同一個(或多個) Request 裡面送到伺服器因為檔案太大,沒有辦法使用同一個 HTTP REQUEST 處理,所以到達的時候檔案可能被切成幾個 「區塊」,而這個就是 Multipart FormGolang 把這些「 區塊 」寫到 RAM 裡面(在 Debian 的情況下就是寫到 /tmp 裡面)然後如果檔案大小比RAM 大,/tmp 就會被塞爆,出現「no space left on device」錯誤如果 Golang 繼續把東西塞進去,它就會被作業系統殺掉(Killed) 要解決這個問題,我們可以使用兩個方法,首先是不要使用 Golang 內置的 Request library,自己重新寫一個。但是那樣實在太麻煩了,所以我決定直接在前端作更改 WebSocket 是個好東西 說到 WebSocket 很多人會想起類似 Chatroom 或是 Web 的 online game 之類,但是…
同步上載與 RAM 不足的問題
在 Raspberry Pi 上面執行類似 arozos 之類的大型系統不免會出現一個問題,就是當要處理大量 IO 的時候總會卡住(畢竟最快的儲存器( RAM、記憶體) 只有那 2 - 4GB,雖然說現在已經出到 8GB 了,但是那個價格我倒不如買台二手的 ThinkCentre M73?),所以要如何在有限 RAM 的情況下讓檔案上下載速度最佳化是其中一個很有趣的研究方向。 上載的方式 Single-thread Upload (單執行緒上載) 我們就先由正常的上載情況說起吧,我在這裡說的就是一般的 HTML5 Form 的檔案上載。每次一個檔案,很簡單吧?可是這速度實在太慢了,例如 Google Drive 之類的很久之前就已經用了多執行緒上載了,所以要一個一個檔案上載的話,速度是無法接受的。 Multi-thread Upload (多執行緒上載) 就是如此,我在這文章裡說的主要是多執行緒上載模式。簡單來說 Multi-thread Upload 就是由 Browser 對伺服器的上載接點打開多個 request,並同時向接點上載資料的方式。 那 Multi-thread Upload 又有甚麼問題? Multi-thread Upload 雖然能夠縮短使用者上載檔案的時間,能夠盡用 bandwidth,但是伺服器也要處理短時間內同時上載的檔案,導致系統的開發有點考功夫,有時候甚至要考慮 Race Condition 問題。 在以前純 PHP 5 + Apache 2的年代,伺服器每次只能夠同時處理一個要求,因此很少會出現資源不足的這個問題。但是到現在,很多人都轉用更先進的語言來開發網頁伺服器了,自然也需要處理到資源分配的問題。以下我就以 Go 作為「思考語言」來分析一下吧。 先 Buffer (緩存)到 RAM 不就行了嗎? Buffering 是一個常用來處理 IO 的方法,由於下載的時候就是由作業系統跟硬碟的緩存機制處理,所以我們只需要處理上載就好。我們就先假設系統採用以下的一個邏輯處理使用者上載的檔案 //建立一個 25MB 的 Buffer r.ParseMultipartForm(25 << 20) //從 POST 中取得 file file, handler, _ := r.FormFile("file") //建立儲存的檔案 dest, _ := os.Create(handler.Filename) //從 File 把內容複制到 dest if _, err := io.Copy(dest, file); err != nil { panic(err) } //關閉打開了的 file descriptor (通稱 fd,即檔案描述符) file.Close() dest.Close() 你那看到,在檔案上載到伺服器的一刻,伺服器已經分配了 25MB 的記憶體給這個 request 了。而這個 request 會把這空間卡住,直到 file.Close() 之前都不會把記憶體還給作業系統,因此每上載一個檔案 = 吃掉一個不少於檔案大小的記憶空間。而在 file.Close() 之前還有一個 blocking 的 io.Copy() 把上載的資料複制到最終的儲存位置(例如硬碟),所以最後就是要等硬碟寫完才能把記憶體釋放出來。 簡單來說就是這樣 所以,這東西很慢! 為了解決慢的問題,我們來做多執行緒的檔案搬運吧!Go-routine 是一個很神奇的東西,不需要幾行我們就可以寫出支援 Multi-threading 的程式,只要我們把 io.Copy 的部分改成: //建立儲存的檔案 dest, _ := os.Create(handler.Filename) //把複制的部分放到 Go routine,讓客戶端繼續上載下一個檔案 go func(dest *os.File, file *os.File) //從 File 把內容複制到 dest if _, err := io.Copy(dest, file); err != nil { panic(err) } //關閉打開了的 file descriptor (通稱 fd,即檔案描述符) file.Close() dest.Close() }(dest, file) 新的方法看起來像這樣,比起上面的方法快多了 對,這樣檔案上載的速度快多了,而且還能同時發起幾個上載的要求,但是這還在檔案比較小,RAM 裝得下的情況下都還好,但是檔案大的時候該怎麼辦? 例如說,在只有 2GB…
由網頁拖放檔案到桌面的神奇方法
你有沒有想過到底怎樣可以把檔案由 DOM ELEMENT 拖放下載到桌面? 由本地的檔案管理員或是桌面拖放檔案到網頁上的話大家應該都很容易在一些網站如 facebook 或 youtube 看到可是說由網頁端拖放檔案到桌面就更少見了。 為甚麼我從來都沒看過有網站用這個方法讓使用者下載檔案? 這當然是有原因的,因為這個功能只有 Google Chrome 支援而已。對於不能跨平台用的 API 沒人用那當然很正常吧?但是作為研究最新技術的 imuslab,這個有趣的功能當然要加進去 ArOZ Online 系統吧?但是,要使用這個檔案由網頁拖放到桌面卻是有這麼堆特別要求: 拖放的元件必須是連接 (<a>)元件的 href 一定要填寫不能留空,但是也可以填 javascript:void(0); draggable 需要設為 true不能使用DOM 屬性 ondragstart ,需要使用 JavaScript 來 加 EventListener 如果你的情況符合上面的條件,你就可以把檔案透過這個 <a> Element 拖放到本地檔案系統了。以下為一個簡單的 Example: $("#element")[0].addEventListener("dragstart",function(evt){ var targetMime = "plain/text"; $.ajax({ url: "media/getMime/?file=" + encodeURIComponent(properties.filepath), success: function(data){ if (data.error !== undefined){ targetMime = "text/directory"; }else{ targetMime = data; } }, async: false }); evt.dataTransfer.setData("DownloadURL",targetMime+":"+ properties.filename +":"+ "http://" + location.hostname + ":" + location.port + "/media/?file=" + encodeURIComponent(properties.filepath)); },true); 到這裡有幾點值得注意 MIME Type 必須符合檔案的內容,不然拖放之後會出現 Internet Shortcut 檔案而不是檔案本身如果要在 event 裡使用 AJAX,那 Request 必須為 Synchronize ,就好像上面的例子中用來要求取得檔案 MIME Type 的 AJAX request 一樣當設定 DownloadURL 參數時時必需使用完整 URL 而不能使用 Relative PathaddEventListener 的 Option 值必須為 true 就是這樣,你就能成功的做出一個可以拖放到桌面的 HTML5 DOM Element 了喔! 19/6/2020 補充 如果你在下載的時候遇到這個問題 失敗 已封鎖的例子 一般是因為以下兩個原因 你寫入的 URL 不正確或檔案不存在上面的例子裡的一個小 Bug (Hard code 了 http 的問題) 對於非 http 的使用者來說,你可以把這一行 evt.dataTransfer.setData("DownloadURL",targetMime+":"+ properties.filename +":"+ "http://" + location.hostname + ":" + location.port + "/media/?file=" + encodeURIComponent(properties.filepath)); 改成 evt.dataTransfer.setData("DownloadURL",targetMime+":"+ properties.filename +":"+ location.protocol + "//" + location.hostname + ":" + location.port + "/media/?file=" + encodeURIComponent(properties.filepath)); (注意多出來的 location.protocol)來自動 Detect 目前是使用 http: 還是 https: 協議
高自由度的 Web Desktop 服務?
說到高自由度的網上平台,你會想起哪一些網頁 / 平台? Google Drive? Facebook? Youtube? 還是說可以 post 奇怪照片的網站 Twitter(?) 平台自由度與用途 一般網頁都不會給予用家太高的自由度,這理由很簡單,一個網頁就是為了提供一種服務,無論那種服務所覆蓋的範圍是廣還是窄,以下是一些例子: draw.io → 網上圖表制作easyEDA → 網 上 PCB 制作與設計onlinesequencer → 網 上音樂制作facebook / twitter → 網 上社交分享Youtube / viemo / po***** → 網 上影片分享平台Office 365 / Google Document → 網上辦公軟件 所以,以商業角度來說,每一個平台必須要有他們的獨立功能才能夠有辦法營運,然而這亦會導致一些問題,就是平台依賴性 (Platform dependencies) 跟 供應商鎖定 (Vendor Lockdown) 問題。 為甚麼我應該擔心這些問題? 由於這篇文章不是說關於這些 WebApps 的問題,所以我也不詳細解釋這些問題了。簡單來說就是: 如果 A 網頁系統用的格式跟 B 網頁系統用的格式不一樣,你是沒辦法把檔案移動到另一平台上面如果提供 A 網頁系統的公司倒閉了,那你使用 A 系統編寫的檔案全部都再用不了 要解決這個問題,除了使用開放格式 / 標準格式(如 IEEE 制定的格式)外,就是開源系統本身了。但是, 真的這麼不幸擁有 A 系統的公司倒了,我想應該不太多人會懂得用開源的系統重建一套新系統出來吧?比較有可能的是會有人開發一個轉接器把 A 系統的格式轉成另一家 B 系統,但是這個也不是這麼容易可以做到,特別對於重度依賴 A系統並有大量 A 系統格式的檔案的人來說。有甚麼可能更槽糕?就是連檔案本身也是儲存在 A 系統裡面的,當 A 系統倒的時候檔案就跟著系統消失了。 以本地運作為前提設計的 WebApp 所以另一個想法,也就是 ArOZ Online 裡面一直在用的系統,就是把 WebApp 的擁有權取回來的方法。由用者擁有 WebApp 而不是由網頁提供者所擁有。這樣,就算供應該服務的公司倒了,WebApp 依舊能用,檔案也不會消失。例如好像說能在主機啟動的時候檢查更新,並把 WebApp 模組下載到啟動資料夾之類的。當然,你也可能會問: 這不就是 React Native 了嗎? 不對喔! (´・ω・`) 這裡就是 ArOZ Online 設計的不同了。React Native 針對的是本地的作業系統,例如 iOS,Windows 或是 MacOS,不同的作業系統會有不同的安裝檔,裡面各包一個 Chromium。那既然是這樣,那為甚麼不直接讓用家在 Chromium ( 或 Firefox / Chrome /Edge 之類的瀏覽器)打開你的 WebApp 呢?這樣不但省空間還能直接用標準 Web Standard 來開發模組。 而這個就是 ArOZ Online 的設計理念:屬於自己的 WebApp 伺服器;而且由於是使用 Web Protocol 傳送的,所以也跟其他 WebApp 一樣去到哪裡,甚至不需要是自己的電腦,都可以透過網絡存取到 WebApp 的內容。 論高自由度平台的條件 然而,因為這種設計已經脫離了一般 Web 開發的範圍,所以要開發一個這麼高自由度,多用途的系統會產生一大堆的問題,例如說 要重新設計 WebApp要想辦法解決本地檔案儲存問題怎樣以人性化的方式尋找及啟動 WebApp (aka 代替 Google 找 WebApp 的過程)怎樣讓使用者不用學習也能適應使用這套系統? 嗯?你有沒有覺得這些要求跟你平常在用的東西很像?沒錯,那就是作業系統 (Operating System),而作業系統本身也的確是一個很高自由度的東西,你可以把它用作 Media Center,可以用來辦公,遊戲,開發等等的用途。 我們需要的是一個能夠在網頁上運作的作業系統! 這個也是我開發 ArOZ Online 的理由:把自己需要的服務放到 Web Desktop 上,那去到世界各地,只要有網絡連接都能用自己的系統和存取到自己主機上的檔案。這跟 NAS 系統很像,只不過不同的地方在於這系統不單單用來放檔案,它亦能用來做其他事情。 這說起來簡單,做起來卻很複雜。這是因為自由度太高會導致很想意想不到的錯誤。好像說只是要處理使用者上載的檔案名稱就已經是一個大麻煩了。由於要跟其他系統兼容,所以不能隨便把檔案改名然後把原檔名放進資料庫這種 wordpress 般的操作;也不能讓使用者隨便把 ../ 放進去檔案路徑裡,就結果而言就是很多很多的麻煩。(有興趣的話可以參考這篇文章) 但是,經過了 Beta + 1.0 preview 差不多 5 年的開發和測試,最終於出來的效果也超乎了我的想像:一個用起來跟本地作業系統一樣的高自由度網頁桌面系統! 很有 Ubuntu…
使用 Golang 動態載入插件 / 模組的方法
Golang 跟 PHP 或 Nodejs 不一樣,是一種需要預先 compile 的語言,相信這個大家都知道了。然而,這有一個很大的問題,就是無法像 php 那樣動態載入插件 / 模組。 那如果我想在已經 Compile 好的 Golang 程式上加上額外的功能應該怎樣做? 一開始我就為這問題煩惱了很久,然而最後我發現了一個不錯的解決方法,就是使用 Reverse Proxy。舉個例子,如果你能夠設定動態的 Reverse Proxy ,然後把一個新的模組指向一個新的 subdirectory ,那樣看上去不就跟新增了功能很相近了嗎? 所以,就在新的 ArOZ Online Core 裡面加入了這樣的一個結構,這裡我把它稱為 Subservice: Subservice 的概念很簡單,就是把 Reverse Proxy 的 process 拼進去跟 Core 共用同一個 STDIN 跟 STDOUT,然後網頁的部分就是用 Reverse Proxy 來處理,看上去所有模組都是由同一個程式所執行似的(實際上卻不是),它的運作邏輯大約是這樣: 掃描所有存在的資料夾,看看裡面有沒有可執行檔案使用 cmd.exec 加上 -info argument 啟動,等待回傳 JSON 格式的啟動設定把 working directory 轉換到資料夾內,並以 cmd.exec -port {指派的端口} 執行該程式把程式的 STDERR 跟 STDOUT 都指向 parent 的 STDOUT把服務要求的 Reverse Proxy 終端指向到該程式在用家存取該終端的時候進行 URL rewrite【在 Reverse Proxy 下使用模組】在parent 遇上 SIGKILL 的時候把 SIGKILL 都傳送到子服務並關掉程式 問題:可是這樣就存取不了伺服器的 DB 跟 File System API 對,所以這方法後來改成了只讓非兼容 ArOZ Online 的模組使用(例如 Aria2)。對於真的有需要存取系統核心部分 API 的模組來說,這個方法無法處理到 Database 存取跟 File System Virtualization 的部分,如果把 系統核心 API 都用 RESTful 的方式開出來錄又會有另一些安全問題,所以得想另一個方法去處理這個部分。 欸,那我內嵌一套 JavaScript Interpreter 不就可以了嗎? AJGI 架構 沒錯,所以後來就使用了一個新的架構,暫名 AJGI。這是一個可以讓系統執行 Javascript 的方法,同時讓 JavaScript 存取到系統內部的 function,可謂一舉兩得,至於效率嘛,既然你都是在寫插件就不要介意這麼多了。簡單來說邏輯是這樣的 由 front end 呼叫 AJGI ,並從檔案系統載入一段兼容的 JavaScript 代碼在 JavaScript 虛擬機中執行代碼透過 轉接器 使用 JavaScript 存取 ArOZ Online Core Golang 部分的核心功能(如需要)回傳資料到 frontend結束虛擬機 至於功能和限制之類的就要等之後的開發再進行測試才知道了
ArOZ Online Pre-1.0 檔案存取路徑虛擬層
ArOZ Online BETA 與 Pre 1.0 版本的差別 在 ArOZ Online Pre-1.0 裡面,我幫 ArOZ Online 系統加上了一層虛擬層;你可能會問:為甚麼要加這個東西?這真是一個好問題,如果不是我開發過一個這樣的系統我也不知道檔案路徑虛擬化的重要性 問題一:檔案路徑安全性 一般如果你用 PHP 來寫系統,你很容易會使用一個檔案的真實路徑。舉個例子,你想讓用家選擇一個檔案,然後打開讓用家下載那個檔案,一般來說你會使用 realpath() 這個功能。然而,這有一定的危險性,例如有人在傳給伺服器的資料中加入 "../" ,讓他能離開你指定的存取範圍。 在 ArOZ Online Beta 的 implementation 中,由於所有檔案都是使用真實路徑存取的,這導致使用者很容易就可以在 path 裡面偷塞一點奇怪的字符以存取一些本來不應該被存取的東西。當然,你可以加一點東西來避免這問題,好像 Stack Overflow 上就有這樣的答案 Stack Overflow 上避免 PHP Directory Traversal 的方法 然而,每次都要透過一個特定的 function 來處理,總會有一天出問題的。(好像說某個開發者忘了用這個 function 或是這個 function 本身有 bug) 問題二:外置存取裝置 由於 ArOZ Online Beta 系統由原本的小網頁變成了一個類似作業系統的物體,它也需要去管理外置的存取裝置(如外接硬碟,或是 www root 所 mount 在的硬碟)。然而 PHP 並不是設計來做這樣的跨硬碟存取的,所以自然有不少的 Bug 存在,而開發起需要存取外置裝置的時候也特別麻煩,需要為。 在 ArOZ Online Beta 的 implementation 裡,使用者需要在 Apache conf 裡面設定 modXSendFile 來讓 PHP 可以在外置硬碟提供(serve)大型檔案如影片,音樂等等。然而,由於外置存取位置的路徑被直接寫進了 Apache conf,即使使用者想更改存取路徑也沒有辦法簡單完成。 解決方案:檔案路徑虛擬化 甚麼是路徑虛擬化?簡單來說就是把 file 的存取路徑進行轉換,讓不同的裝置也能夠輕易的讓模組使用 Virutalized path 來存取。簡單來說是這樣: 請求 Virtual Path模組把 Virtual Path 掉到 file system 的轉換 function回傳真實路徑處理資料 以 ArOZ Online Pre-1.0 的 File system listdir 功能來說,先假設你有兩隻 HDD mount 在了 /media/storage1 跟 /media/storage2,並把 storage.json 設定成以下的樣子: [ { "name":"Storage 1", "uuid":"S1", "path":"/media/storage1", "access":"everyone", "hierarchy":"users", "automount":true }, { "name":"Storage 2", "uuid":"S2", "path":"/media/storage2", "access":"everyone", "hierarchy":"public", "automount":true } ] 然後你可以傳入以下虛擬路徑用來處理檔案 S1:/video/ S2:/ user:/Music user:/Desktop/test 然而實際上,上術的虛擬路徑卻是在存取以下的真實路徑 /media/storage1/users/{username}/video /media/storage2/ ./files/users/{username}/Music ./files/users/{username}/Desktop/test/ 而設定當中,hierarchy 就是決定了虛擬路徑構造的元素,裡面的原理有點複雜,但是作為開發者,你只要存取 virtualPathToRealPath() 這個功能就能夠取得真實路徑了,簡單吧?
一種語言的極限:PHP
在 2020 年 3月尾的時候,我向內部其他幫忙開發 ArOZ Online Beta 系統的工程師(Programmer / 程式員 / 開發者)宣布 ArOZ Online 系統將會停止支援 PHP 。你可能會問:為甚麼要終止支援 PHP? 這系統的核心不是一向也是由 php 開發的嗎? Apache + PHP 是一個好用而且適合大型系統開發的程式語言 開始開發 ArOZ Online Beta 版時,在選擇到底應該選擇使用 PHP 或是 Nodejs 開發 ArOZ Online 系統。當時在網上也找到不少意見是說如果要開發大型系統, php 的 project structure (項目結構)的確是會比較適合。再之後,我亦在網上找到了一篇講述為甚麼 Nodejs 不適合開發大型系統的文章,讓這個想法得以確實。然而,這問題仍然比我想像中的複雜,我直接跳到結論來看: PHP 是適合開發 靜態 大型系統 甚麼是靜態系統?一般常見的 CMS、BMS 如 warehouse management system (倉庫管理系統), Learning management system (學習管理系統)等。這些系統不需要太大量的即時互動性,資料只需要在頁面載入的一刻提供就可以了,不必要即時對頁面更新。 PHP 的設計本來就是這個用途,而一開始 ArOZ Online 系統也是只提供這個簡單的用途: 在頁面載入的時候提供一個音樂 / 影片列表當用戶點擊媒體之後,JavaScript 把該媒體載入(用 Apache modXSendFile)播放 這個設計在 ArOZ Online Alpha 跟 Beta 初階段也沒甚麼問題,畢竟就只是一個簡單的影片網頁而已。 當 PHP 遇上網頁桌面系統 到了 ArOZ Online Beta 開發的中期,Virtual Desktop Mode (虛擬 / 網頁桌面模式)被開發出來了。由於桌面的互動性設計(例如使用者拉動桌面上的圖示之類的),客戶端對伺服器的請求數目多了很多,由原本只是使用者有按按鈕才會做一次 request 變成了每 5 秒做一次請求,看看有沒有桌面圖示或是檔案變動。如果你在 ArOZ Online Beta 的桌面模式打開 Developer Console,你將會看到以下一大堆的 Ajax Request。當然,這種 request 方法完全說不同是 best practice。 桌面模式下超多次的 AJAX Request 在 Windows 的工作管理員明顯能看到每次 AJAX Request 時的 CPU 負載尖端(Load Spike) 然而,桌面的難題還是透過不斷 request 來算是暫時解決了。可是真正讓我發現 PHP 真的不夠用的部分是 File Explorer (檔案管理員)的部分。 PHP 與 檔案管理員 — 一種語言的極限 對,就是因為要開發一個基於 PHP 的檔案管理員,就把 PHP 這個語言推到了它的能力極限。 ArOZ Online Beta 下使用 PHP 開發的檔案管理員 這個工作管理員一開始是使用 100% 純 PHP 開發而成。但是如果你對 PHP + Apache 有一點的開發經驗,你就會知道一個 PHP 在處理的時候是會把另一個 PHP request 卡住。即是說,伺服器每次只能處理一個 request。當你把這個 request 用作處理 file operation 如 檔案移動、複制等等,如果檔案是比較小的還好,但是如影片檔案(1 - 2GB)一個的話,你整個伺服器就卡住了。 就是在這個時候我發現了 Golang 就是這個時候,我學會了基本的 Golang。這個時候我為 ArOZ Online 的 File Explorer 開發了三大系統: fsexec / fszip / fsconv…
WAMP SERVER MySQL 無法連線,因為目標電腦拒絕連線。
最近在幫伺服器由 php 7.0 升級到 php 7.4.4,然而在升級 wordpress 的時候出現了無法連接到資料庫的問題,於是簡單的從網上找到了一個測試資料庫的 php script,發現原來不是 wordpress 的問題,是 MySQL 的問題。 $DBServer = 'localhost'; $DBUser = 'username'; $DBPass = 'password'; $DBName = 'wordpress'; $link= new mysqli($DBServer, $DBUser, $DBPass); if(!$link) echo "失敗!"; else echo "成功!"; 錯誤 解決方法:在 localhost 後面加上 :3307 結果在網上找了一整天也找不到能處理的解決方法,於是在想會不會是 port 設定的問題呢?於是在 localhost 後加上了 :3307 $DBServer = 'localhost:3307'; 然後居然就 fix 好了!? 不過話說,在 Fix 這個 bug 的時候整個網頁伺服器上的服務都不能用,除了其中一個完全不依賴 Database 的服務,我想我不用說你也已經猜到了: ArOZ Online 系統!這套系統在 PHP Extension 一個都沒開 + MySQL 完全 offline 的情況下也能繼續正常運作還真的是滿壯觀的。 升級途中居然對 ArOZ 系統一點影響都沒有,還能夠一邊聽音樂一邊升級 就是這樣,伺服器就有驚無險地升級上 PHP7.4.4 囉! P.S. 有人問邊到睇到 MySQL 個 port你可以係 WAMP 個 menu 下面找 MySQL → Port used by MySQL: 3307
ArOZ Online 的使用者定位?
說到 ArOZ Online 系統,很多人看完 README 會覺得它又是一套普通的 NAS 作業系統。如果我要自己組 NAS 的話那我用 OwnCloud 或是 OpenMediaVault 就好,幹麼要用一套這麼新,沒幾個使用者的系統來放我重要的資料呢? ArOZ Online 的網頁桌面環境 對,如果你要 NAS 作業系統你不應該選擇 ArOZ Online 系統 ArOZ Online 系統從來也沒向過檔案儲存的方向發展。這是一個顯然易見的答案。ArOZ Online 系統缺少了幾個 NAS 作業系統必須的東西:RAID 管理器跟磁碟管理工具。這兩項日後可能會被太有空的工程師給加進去,但是在目前階段我們是沒有打算向這方向發展的。 再者,市面上除了開源的 OwnCloud, OneCloud, OpenMediaVault 之類的方案外,也有需要購買特定硬件的 QNAP 跟 Synology DSM,而且更不用說大家熟悉的雲儲存方案了,Google Drive,Dropbox ,MediaFire 甚麼的要多少有多少。相比之下 ArOZ Online 系統只是一個非常普通,只是到達「能用」地步的儲存系統。 用 ArOZ Online 系統代替真正的作業系統? 那如果不向 NAS OS 的方向發展,難道 ArOZ Online 系統要代替真正的作業系統?這也是不可能的。作業系統三大家庭:Windows Mac Linux,ArOZ Online 系統也只是建基於 Debian Linux 之上,不可能說取代他們其中一員。 Google 的 Chrome OS 也曾嘗試過做類似的東西,使用 Chrome 本身作為作業系統,提供各類型的 WebApp 服務;話雖如此,Chrome OS 到現在在一般使用者(consumer level)的市佔率還是比不上 Windows 跟 Mac,這很大程度上是跟系統兼容性有關了。然而,Chrome book 之類的作為 輔助設備 ( secondary device)的用者卻大有人在,證明 Chrome OS 雖然不及 Windows 或 Mac 那樣高兼容性和高市佔率,但仍然有它的優點和使用者群。而 ArOZ Online 系統要向的方向也是類似的:特定的使用者群,而外面並沒有類近能取代它的系統。 所以,ArOZ Online 的優點是甚麼? ArOZ Online 說到最極端它只是一個由PHP,Js,HTML5 跟 Golang 組合出來的系統,就如你所想的,就是一套網頁系統。然而,你不覺得為甚麼明明都有 PHP 了,卻多了一個 Golang 出來?他們的功能不是重複了嗎? 對,就是這個多出來的 Golang 讓這套系統變得超級神奇。無論是功能上還是效率上。 沒錯,這個 Golang 並不是用來作為網頁伺服器,而是用來處理後台大型運算用的。 我們先從功能說起。自從 2019 年的版本中,Golang 開發的部分開始取代 php 的部分工作,系統的功能開始變多了。由 Gcode 發送器,備份組建系統等等,都是因為 Golang 的加入讓這些原本不太可能用 php 來開發的部分變得有可能。再者,Golang 可以比 PHP 接觸更底層的系統資源,做出更多你想不到的功能。之後的分散式文件系統,集群通訊協議也將會使用 Golang 進行大重寫,讓用家可以在一個界面裡就控制到好幾台使用 ArOZ Online 的裝置。 在效率上,Golang 的加入也讓系統效率更快。原本 PHP 要 Copy & Paste 一個檔案能會把整個伺服器卡上好幾分鐘,現在使用 Golang 重寫後的 fsexec (檔案系統)架構,讓 Copy & Paste 功能變成非同步功能,並可以在背景同步運行多個檔案移動指令,讓系統效率更高。另外,在 ArOZ Cluster 裡面,Golang 寫的掃描器也讓 HDS 運作率更佳,掃描速度更快。 所以說了這麼多廢話,總結來說就是 ArOZ Online 的特點是: 物聯網 / 集群連接網頁桌面環境高後台處理能力完整的檔案管理系統支援中文在地化 所以?創作者用的雲系統! 最後,我們選擇向創作者的方向發展! 到底是哪類型創作者?我們的目標打算放在以下三大類: 移動 / 遠端創作者數碼生產類(Digital Manufacturing)創作者ArOZ Online 模組開發者 首先是移動或遠端創作者,這一個例子就是經常個人旅行的 Youtube 創作者之,讓他們可以不用隨身攜帶這麼多儲存裝置,只要在旅途跟旅途之間的一小段時間把檔案放到伺服器 / 電腦上,之後即使是再出發了也能夠在途中對之前的影片或音源檔案進行編輯、匯出。另一個例子就是產品設計,可以使用 ArOZ Online 上的建模軟件或…