2019/12/24
2019/12/06
相信很多人看過這個錯誤訊息:
想必開剛使接觸 Python 的人應該都會遇到這個問題吧?然後就乖乖的「pip install MySQL db」、「pip install ConfigParser」之類的。
不過大家不用擔心,地雷我已經踩完,邊直接給答案。
先在系統上安裝套件「sud aptitude install libmysqlclient-dev」再回到 python 環境底下安裝「pip install mysqlclient」。到這邊都沒有看到錯誤的話,就可以試試看做一次 migration 了。
Ref: https://stackoverflow.com/a/4169790
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
想必開剛使接觸 Python 的人應該都會遇到這個問題吧?然後就乖乖的「pip install MySQL db」、「pip install ConfigParser」之類的。
不過大家不用擔心,地雷我已經踩完,邊直接給答案。
先在系統上安裝套件「sud aptitude install libmysqlclient-dev」再回到 python 環境底下安裝「pip install mysqlclient」。到這邊都沒有看到錯誤的話,就可以試試看做一次 migration 了。
Ref: https://stackoverflow.com/a/4169790
標籤:
Python
2019/11/15
杯蓋的迷思
以前一直聽到別人說:咖啡外帶的蓋子材質不耐熱,一直蓋著可能會釋出有毒物質 ...。
今天叫外送的時候稍微看了一下杯蓋的材質:
左邊的標示材料為「PP 聚丙烯」,到 Widipedia 查了一下這個材料,耐熱可以到攝氏 140 度,所以其實當杯蓋應該還算安全。
備註:大家要注意的幾個點:
今天叫外送的時候稍微看了一下杯蓋的材質:
左邊的標示材料為「PP 聚丙烯」,到 Widipedia 查了一下這個材料,耐熱可以到攝氏 140 度,所以其實當杯蓋應該還算安全。
備註:大家要注意的幾個點:
- 水的沸點是攝氏 100 度,但如果改成玉米濃湯可就不一定囉
- 杯蓋通常比較容易遇到的是水汽 (水蒸氣),蒸氣的溫度是可以破百的喔
標籤:
生活雜記
2019/11/12
2019/11/11
MySQL non-interactice installation
相信大家對這個畫面都不陌生:
除了 MySQL 5.7 的某幾個版本會自動產生 root 的 password 以外,大多都是在安裝時讓使用者自行輸入密碼。
但今天你不是手動安裝,而是寫 script 讓主機自行部屬,這下就麻煩了,因為你不可能每台主機都人工輸入密碼,另外像是 AWS 自動部屬的話,你大概連 console 都沒有。但若透過 debconf 是有機會做到完全自動安裝。
除了 MySQL 5.7 的某幾個版本會自動產生 root 的 password 以外,大多都是在安裝時讓使用者自行輸入密碼。
但今天你不是手動安裝,而是寫 script 讓主機自行部屬,這下就麻煩了,因為你不可能每台主機都人工輸入密碼,另外像是 AWS 自動部屬的話,你大概連 console 都沒有。但若透過 debconf 是有機會做到完全自動安裝。
2019/11/01
一般感冒與流行性感冒 (流感) 的差異
這幾天被感冒的一些病狀搞到實在很不舒服,誰身酸痛不說,喉嚨雖然沒有很痛,但整個乾得很難說話。
另外就是整個體力下降,本來要去公司撐的一、二天,結果出門時發現連機車都快牽不動,只好乖乖請假在家。
在網路上找到了一些區分一般感冒與流行性感冒 (流感) 差異的說明,簡單練出幾個差異比較大的症狀,如下 (Blogger 居然不支援畫表格 ....QQ):
ps. 感謝 emmet 贊助畫表格 QQ
這次自己判斷可能還沒有到流感,暫時請狂睡,外加補充水份和維他命,希望週末、週日就可以恢復正常。
另外也感謝同事幫我把工作 hold 住,不然我應該會掛彩吧
另外就是整個體力下降,本來要去公司撐的一、二天,結果出門時發現連機車都快牽不動,只好乖乖請假在家。
在網路上找到了一些區分一般感冒與流行性感冒 (流感) 差異的說明,簡單練出幾個差異比較大的症狀,如下 (Blogger 居然不支援畫表格 ....QQ):
症狀 | 一般感冒 | 流感 |
---|---|---|
影響範圍 | 呼吸道局部症狀 | 全身性 |
發病速度 | 突發、漸進式 | 突發性 |
發病症狀 | 喉嚨痛、打噴嚏、流鼻涕 | 喉嚨痛、肌肉酸痛、倦怠 |
發燒 | 少發燒、或僅體溫稍微升高 | 發高燒 |
ps. 感謝 emmet 贊助畫表格 QQ
這次自己判斷可能還沒有到流感,暫時請狂睡,外加補充水份和維他命,希望週末、週日就可以恢復正常。
另外也感謝同事幫我把工作 hold 住,不然我應該會掛彩吧
2019/10/30
2019/10/24
綠聯的 3.5mm + usb charger 不會產生噪音
才說有些轉接頭在充電和聽音樂時會導致噪音出現,不過後來嘗試了綠聯的充電、3.5mm 轉接頭以後,發現不會有噪音。
個人對綠聯的品質不算有信心,不過在還沒有比較好的選擇之下,我聽音樂時暫時會使用這款充電器。
ps. PChome 的貼紙把產品名稱全蓋掉了,所以我再下方留下商品購買連結,請大家自行決定是否要購買。
圖一:這款感覺有將充電電流和音訊隔離
個人對綠聯的品質不算有信心,不過在還沒有比較好的選擇之下,我聽音樂時暫時會使用這款充電器。
ps. PChome 的貼紙把產品名稱全蓋掉了,所以我再下方留下商品購買連結,請大家自行決定是否要購買。
USB type C 轉 3.5mm 音源接頭
據說是廠商希望讓手機可以做的更薄,所以決定將 3.5mm 音源輸出孔移除,只保留 USB type C。
但個人認為這樣做有幾個不方便的地方:
但個人認為這樣做有幾個不方便的地方:
- 只剩下一個對接端口,所以我沒辦法接 USB 並同時聽 USB 上的音樂或看影片。
- 已目前的技術,無線耳機 (藍芽等) 由於電池現有的技術瓶頸,通常很難持續運作很久;不然就是體積會變得很大。
- 一邊充電、一邊聽音樂變得不太可行。
最近找了二款轉接頭,都是 USB type C 轉 3.5mm 音源輸出。
圖一:綠聯的轉接頭,僅支援轉 3.5mm 音源輸出
上面這款就只能聽音樂,因為 USB 孔直接轉 3.5mm 音源輸出了,所以沒辦法充電,只能祈禱你的音樂播放程式夠省電。
圖二:不知道哪個廠牌的轉接頭,支援同時充電+聽音樂
上面這款明顯高級很多,支援 OTG、並同時輸出音訊。不過是用以後發現其實沒有想像中的好,因為充電時的電流和音訊用的線路很靠近,一旦接上充電線,輸出的聲音便會出現雜音。 (好死不死是我的痛點)
不曉得之後有沒有什麼其他的替代方案,總之我覺得這個設計實在有點不太方便。
2019/10/23
2019/10/07
Laravel UrlGenerator 判斷 HTTP or HTTPS 的因素
第一個要求 Laravel 要使用 HTTP or HTTPS (以下簡稱 protocol ... 因為字太多了 .._Drz) 的方法,其實就是在「.env」做設定,例如:
再來網路上應該會找到,要開發者在 AppServiceProvider 中加入設定:
這邊的 URL facade,可以從 config/app.php 中追蹤到,是 \Illuminate\Routing\UrlGenerator::class 的 alias,設定了 forceSheme() 以後,未來透過 UrlGenerator 建立的 link 都會是設定好的 protocol。
BUT .... 就是這個 BUT,若是遇到另一個其他的 method 來產生 URL (例如 Illuminate\Routing\Redirector::route() ...),這樣就可能吃到開發者設定的 protocol ,則由 Laravel 會自動抓進來的 request 來判斷該用什麼 protocol,若 application 剛好是靠 Nginx 在 handle HTTP SSL 的話,request 到 Laravel 這端時 HTTPS 就已經轉成 HTTP,導致 Laravel 以為 application 沒有上 HTTPS。
若要讓 reverse proxy 後面的 Laravel application 都固定用 HTTPS 的話,可以再到 app/Http/Middleware/TrustedProxy.php 去修改設定,讓 Laravel 識別 proxy 做出對應的動作 (給正確的 protocol)。
Ref: Laravel 5 force HTTPS issue with login routing to HTTP
APP_URL=http://zeroplex.tw
再來網路上應該會找到,要開發者在 AppServiceProvider 中加入設定:
\URL::forceScheme('https');
這邊的 URL facade,可以從 config/app.php 中追蹤到,是 \Illuminate\Routing\UrlGenerator::class 的 alias,設定了 forceSheme() 以後,未來透過 UrlGenerator 建立的 link 都會是設定好的 protocol。
BUT .... 就是這個 BUT,若是遇到另一個其他的 method 來產生 URL (例如 Illuminate\Routing\Redirector::route() ...),這樣就可能吃到開發者設定的 protocol ,則由 Laravel 會自動抓進來的 request 來判斷該用什麼 protocol,若 application 剛好是靠 Nginx 在 handle HTTP SSL 的話,request 到 Laravel 這端時 HTTPS 就已經轉成 HTTP,導致 Laravel 以為 application 沒有上 HTTPS。
若要讓 reverse proxy 後面的 Laravel application 都固定用 HTTPS 的話,可以再到 app/Http/Middleware/TrustedProxy.php 去修改設定,讓 Laravel 識別 proxy 做出對應的動作 (給正確的 protocol)。
Ref: Laravel 5 force HTTPS issue with login routing to HTTP
2019/09/10
RaspBian Lite - 專為台灣客製化的免初始化 image
上次給台灣人的 Raspbian 懶人版映象檔趕時間做的有點潦草,這次重新調整了一下設定。
版本:
以下是我手動調整過得設定:
另外採用 EricPi 的建議,我加上了 mDNS,這樣只要接到有線網路上,可以直接「ping raspberry.local」得到 IP 位址,initialize 會方便很多
下載:
版本:
- Raspbian Buster Lite
- Version: June 2019
- Release Date: 2019-06-20
- Kernal version: 4.19
以下是我手動調整過得設定:
- Localization
- Locale:en_US.utf8 + zh_TW.utf8
- 時區:Asia/Taipei
- 鍵盤對應:en (US)
- Wify county:TW
- SSH 預設啟動 (port 22)
- 有線網路自動 DHCP
- etc/apt/source.list 的 source 改為 NCHC (快超多)
- apt-get upgrade @ 2019-09-09
另外採用 EricPi 的建議,我加上了 mDNS,這樣只要接到有線網路上,可以直接「ping raspberry.local」得到 IP 位址,initialize 會方便很多
下載:
載點:https://mega.nz/#!JcpxhYQb!-1A7CoYVBEal5I5iTjtQkul9W2Js8cW2xE5QEqt6yK4
SHA1: 638436e2c7b550875793d32e3ce995d9e5198f3aeceb8ed5bca3d9265c3ee061
SHA256: 638436e2c7b550875793d32e3ce995d9e5198f3aeceb8ed5bca3d9265c3ee061
2019/08/23
讓 less 可以顯示 ANSI 色彩
應該不少人有經驗,在使用 grep 時,要搜尋的關鍵字會用顏色 highlight 方便閱讀,例如:
不過如果因為列表很長,在把搜尋結果 pipe 給 less 以後,顏色就消失了。
這其實是 grep 這邊會判斷 output 到哪一種型態的 I/O,像是後面接的是 bash pipe,grep 就會自動移除 ANSI color 的 syntax,畢竟不知道 pipe 資料給誰,如果後者不支援 ANSI color 就會變成亂碼。
如果很確定 pipe 後面的指令、工具支援 ANSI color 的指令,就可以下參數要求 grep 輸出顏色。例如:
$ ls -lh | grep php
-rw-rw-r-- 1 zero zero 178 Aug 22 19:15 autoload.php
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 cakephp
drwxrwxr-x 5 zero zero 4.0K Aug 22 19:01 phpdocumentor
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpoffice
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpoption
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpseclib
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpspec
drwxrwxr-x 8 zero zero 4.0K Aug 22 19:01 phpunit
不過如果因為列表很長,在把搜尋結果 pipe 給 less 以後,顏色就消失了。
這其實是 grep 這邊會判斷 output 到哪一種型態的 I/O,像是後面接的是 bash pipe,grep 就會自動移除 ANSI color 的 syntax,畢竟不知道 pipe 資料給誰,如果後者不支援 ANSI color 就會變成亂碼。
如果很確定 pipe 後面的指令、工具支援 ANSI color 的指令,就可以下參數要求 grep 輸出顏色。例如:
$ ls -lh | grep php --color=always | less
-rw-rw-r-- 1 zero zero 178 Aug 22 19:15 autoload.php
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 cakephp
drwxrwxr-x 5 zero zero 4.0K Aug 22 19:01 phpdocumentor
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpoffice
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpoption
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpseclib
drwxrwxr-x 3 zero zero 4.0K Aug 22 19:01 phpspec
drwxrwxr-x 8 zero zero 4.0K Aug 22 19:01 phpunit
2019/08/13
快速判斷 Ubuntu (或該 distribution) 是否重新開機的方法
登入 Ubuntu 時,常會看到最底下會有一行字,提醒你主機是否需要重新開機:
追了一陣子,才知道判斷的方法非常簡單,只要到 /var/run 目錄下檢查是否有「reboot-required」的檔案即可。
例如:
就這樣,沒了。
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.4.0-142-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
0 packages can be updated.
0 updates are security updates.
*** System restart required ***
追了一陣子,才知道判斷的方法非常簡單,只要到 /var/run 目錄下檢查是否有「reboot-required」的檔案即可。
例如:
$ ls /var/run
acpid.pid crond.reboot initctl log motd.dynamic resolvconf snapd.socket udev
acpid.socket dbus initramfs lvm mount rsyslogd.pid sshd unattended-upgrades.lock
agetty.reload dhclient.enp0s3.pid init.upgraded lvmetad.pid mysqld screen sshd.pid user
atd.pid dmeventd-client irqbalance.pid lxcfs network sendsigs.omit.d sudo utmp
blkid dmeventd-server iscsid.pid lxcfs.pid reboot-required shm systemd uuidd
crond.pid grub lock mdadm reboot-required.pkgs snapd-snap.socket tmpfiles.d xtables.lock
就這樣,沒了。
標籤:
Ubuntu
2019/07/30
MySQL 8.0 的新密碼加密 plugin 導致 PHP 連線失敗
今天很難得打開 phpMyAdmin 來看一下有什麼改變,但發現一直無法登入,顯示錯誤訊息「」。
查了一下才發現 MySQL 8 預設的密碼有多種格式,預設的格式 PHP 還不支援,所以會登入失敗 (但用 console 會成功)。
解決方法是暫時改為舊版本的密碼儲存方式:
然後在設定檔裡面多新增一條規則,把預設的密碼儲存方式改回舊版的:
查了一下才發現 MySQL 8 預設的密碼有多種格式,預設的格式 PHP 還不支援,所以會登入失敗 (但用 console 會成功)。
解決方法是暫時改為舊版本的密碼儲存方式:
alter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your-password';
flush privileges;
然後在設定檔裡面多新增一條規則,把預設的密碼儲存方式改回舊版的:
[mysqld]
default-authentication-plugin = mysql_native_password
2019/07/21
LibreOffice 加油啊
昨天鄰居想嘗試使用 Linux,大致上都沒什麼問題,但卡到二個點:
- 輸入法:沒有順手的輸入法 (倉頡)
- Office 文件工具組:LibreOffice 的操作實在很不直覺,從 M$ 跳到 LibreOffice 目前還沒聽過有人說好用的。
今天還是幫他改回 Windows 系統,實在可惜。
2019/07/20
MySQL 8.0 不再使用的設定參數
以下幾個參數,在 MySQL 8.0 不在繼續支援、使用:
- query-cache-type
- query-cache-size
- innodb_large_prefix
標籤:
MySQL
2019/07/19
家電的耗電量
因為一個意外,收到了 4000 元的電費帳單,所以決定把目前租屋內的家電用品全部都測量一次耗電量,找出兇手才罷休。
先從我的電腦開始列:
先從我的電腦開始列:
- 桌上型電腦主機 (待機):120 瓦
- 風扇 .... 不屑跳過 XD
- 筆電:變壓器最高支援到 60 瓦,所以最高就是 60 瓦
- 冰箱 (舊型,冷藏、冷凍分離 2 公尺高):200 瓦
- 舊洗衣機:250 瓦
- 除濕機 (省電一級、變頻):150 瓦 (有點強)
- 舊窗型冷氣機:3000+ 瓦
吹冷氣吹到心痛。
2019/07/18
使用 Eloquent migration 刪除有 key constrain 的 table / index
建立 table 時可能會同時建立 foreign key:
這個情況下要直接 dropIndex() 是會出現錯誤的,要先把 key constraint 解掉再來刪除 index。
而 constraint key name 用 show index from TABLE 是看不到的,但是可以使用下面的語法看到 create table 時做的事情:
看到 contrain key name 以後先用 dropForeign() 刪除,再 dropIndex() 即可。
ps. 記得事情處理完以後,要把 constraint 加回去喔
$table->foreign('good_id')
->references('id')
->on('goods')
->onDelete('cascade');
$table->index('value');
這個情況下要直接 dropIndex() 是會出現錯誤的,要先把 key constraint 解掉再來刪除 index。
而 constraint key name 用 show index from TABLE 是看不到的,但是可以使用下面的語法看到 create table 時做的事情:
show create table NAME
看到 contrain key name 以後先用 dropForeign() 刪除,再 dropIndex() 即可。
ps. 記得事情處理完以後,要把 constraint 加回去喔
2019/07/06
給台灣人的 Raspbian 懶人版映象檔
這幾天被 Raspbian 安裝搞得七葷八素,所以乾脆把幾個常用設定改好,直接打包給大家用。
我用的是 Raspbian Buster Lite:
我調整過的設定 (目標是接上電源線即可遠端操作):
我用的是 Raspbian Buster Lite:
- Version: June 2019
- Release Date: 2019-06-20
- Kernal version: 4.19
我調整過的設定 (目標是接上電源線即可遠端操作):
- Localization
- Locale:en_US.utf8 + zh_TW.utf8
- 時區:Asia/Taipei
- 鍵盤對應:en (US)
- Wify county:TW
- SSH 預設啟動 (port 2222)
- 有線網路自動 DHCP
- /etc/apt/source.list 的 source 改為 NCHC (快超多)
- 已經做過一次 apt-get update && apt-get upgrade
載點:https://mega.nz/#F!dR5EVABL!Nkynwg5ivQuRyRqpGz1Q4A
SHA1: 71664d5651d660077621f91b29edeecf4810a486
SHA256: 981a8ded523c30f06ec09292445255c55a862e5d756b4e0fff5f8d069ef35afa
2019/07/04
Google Dou 沒有 Desktop 版本 ... 但有 web 版!
近期找到的語音通訊軟體,音質、順暢程度感覺最好的是 Google Duo,但是在行動裝置上運作起來,可以說是個非常吃系統資源的怪獸 (僅次於 LINE 和 Facebook 吧),所以打算找找看有沒有 Desktop 的版本。
沒想到 Google Dou 提供的不是 Desktop 版本 ...
感覺目前資訊產業從個人電腦,又慢慢轉回中央主機系統的架構,只是 terminal 變成彩色瀏覽器而已。
沒想到 Google Dou 提供的不是 Desktop 版本 ...
感覺目前資訊產業從個人電腦,又慢慢轉回中央主機系統的架構,只是 terminal 變成彩色瀏覽器而已。
2019/07/03
使用 setup.py 安裝 Python Package 要切換至根目錄
最近在研究 Python,下載了 RPIO 來安裝:
弄了半天,才知道有路徑問題,要先切到 package 根目錄再安裝才會成功:
沒寫過 Python 直接衝 GPIO 有越級打怪的感覺,不知道機器會不會被我搞爛 Orz
$ wget http://...... -O RPIO.zip
$ unzip RPIO.zip
$ python RPIO/setup.py install
....
running install
running bdist_egg
error: error in 'egg_base' option: 'source' does not exist or is not a directory
弄了半天,才知道有路徑問題,要先切到 package 根目錄再安裝才會成功:
$ cd RPIO
$ python setup.py install
沒寫過 Python 直接衝 GPIO 有越級打怪的感覺,不知道機器會不會被我搞爛 Orz
標籤:
Python
2019/06/28
注意 PHPUnit 的 fixture 行為
理論上,各個 test case 不應該互相影響,所以 PHPUnit 設計的 fixtures 像是 setUp() 和 tearDown() 都會在各個 test case 前後執行。
簡單做個測試:
即使在 test case 加上 @depends 標記,fixture 也會運作,所以若是要讓下一個 test case 繼續使用的測試值,都必須用 return 的方式傳值。
----
另外,Laravel 提供的 testing tools 也有相同的行為。例如:「RefreshDatabase」,在 test case 執行結束以後就會把資料清空,因此如果要對 DB 做多像檢查,就必須在同一個 test case 中建立多個 assertions (個人不喜歡這樣做),不然即使加上 @depends,DB 中的資料也會被 refresh 掉。
簡單做個測試:
<?php
use PHPUnit\Framework\TestCase;
class LibTest extends TestCase
{
public function setUp(): void
{
$this->data = null;
}
public function tearDown(): void
{
$this->data = null;
}
public function testOne()
{
$this->data = 123;
$this->assertEquals(123, $this->data);
return $this->data;
}
/**
* @depends testOne
*/
public function testTwo($data)
{
$this->assertEquals(123, $this->data);
}
}
// -----
PHPUnit 8.2.3 by Sebastian Bergmann and contributors.
.F
即使在 test case 加上 @depends 標記,fixture 也會運作,所以若是要讓下一個 test case 繼續使用的測試值,都必須用 return 的方式傳值。
----
另外,Laravel 提供的 testing tools 也有相同的行為。例如:「RefreshDatabase」,在 test case 執行結束以後就會把資料清空,因此如果要對 DB 做多像檢查,就必須在同一個 test case 中建立多個 assertions (個人不喜歡這樣做),不然即使加上 @depends,DB 中的資料也會被 refresh 掉。
2019/06/27
在 Laravel unit test 手動建立 HTTP request
現在有個 controller 收到 HTTP POST data 以後才會動作,且這個 controller 為 AJAX controller,沒有 view 沒辦法用 Selenium 測試:
要測試的話,其實可以透過一些工具手動測試,像是 PostMan 等類似的工具。但這種測試會遇到一些問題:Middle 有檢查使用者身份、需要拿到 access token 才能進 controller 等等。這樣會讓測試多了不少不確定因素 (變因),導致測試結果不準確。
要進行測試較好的方法,就是建立一個 HTTP request 來模擬實際情況:
不過可惜的是 Request 這個類別,設計原始的用意是從 $_GET、$_POST、$_FILE 等全域變數整理成物件方便 access,所以若要在 request 中加入參數,目前只能透過 replace() 來增加。例如需要新增 key/value pair,必須這樣撰寫:
至於模擬檔案上傳 .... 我還在找方法,確定了以後再來寫筆記。
Ref:
class TargetController extends Controller
{
public function doSomething(Request $req)
{
// do something ....
}
}
要測試的話,其實可以透過一些工具手動測試,像是 PostMan 等類似的工具。但這種測試會遇到一些問題:Middle 有檢查使用者身份、需要拿到 access token 才能進 controller 等等。這樣會讓測試多了不少不確定因素 (變因),導致測試結果不準確。
要進行測試較好的方法,就是建立一個 HTTP request 來模擬實際情況:
$req = new \lluminate\Http\Request();
$ctrl = new TargetController()
$result = $ctrl->doSomething($req);
不過可惜的是 Request 這個類別,設計原始的用意是從 $_GET、$_POST、$_FILE 等全域變數整理成物件方便 access,所以若要在 request 中加入參數,目前只能透過 replace() 來增加。例如需要新增 key/value pair,必須這樣撰寫:
$request->replace([
'key' => 'value',
]);
至於模擬檔案上傳 .... 我還在找方法,確定了以後再來寫筆記。
Ref:
2019/06/15
大量 task in-queue 時對 consumer 造成的影響
若 task 無法立即完成,為了提高 UX,通常不會讓使用者在線上等待 task 完成,而是告知使用者 task 已經在背景執行,完成後再通知使用者。
這個情境下,系統通常是這樣實作:建立一個 queue,將等待處理的 task 全部放進 queue 中,並讓 idle 的 consumer 自動從 queue 中取得一個 task 來執行 (當然也有可能是用 dispatch 的方式)。
假設有 A、B、C 三個使用者的 task 的放進 queue 來處理,一般情況下 queue 的狀態大概會向下面這個樣子:
但大多時候工作的分配通常不會這個平均,有時 A 使用者會需要大量處理資料,於是 queue 就會成下面這個樣子:
若這個情況下仍然使用相同的 consume 機制,會變成大多數的時間都在處理 A 的 tasks,導致 B、C 使用者的 task 被 (無限) 延後。
在一般狀態下這樣不是一件好事,就像去餐廳買飯,因為前面有個 50 人份的訂單排在你前面,就導致你買一個便當也要等一個多小時。在我自己碰到的狀況,這個時候餐廳通常會有二種作法:
將上面提到的情況改用在 task queue 上,若遇到類似的問題,則可以考慮不同處理 queue 的方法。
例如為不同用途、類型的 task 分別建立不同的 queue,而每次都從個別的 queue 做一次 de-queue,這樣就不會因為 queue-A 大量的 task 卡住其他的 task:
另外也可以考慮使用類似 Laravel API rate limit 的功能,分別記錄每個時段中,各類型的 task 共處理了多少次,若超過限制,則將原本 de-queue 出來準備處理的 task 在 in-queue 輪到較晚處理:
當然,用錢可以解決的問題都不是問題。把廚房加個 100 倍大,請一批廚師來炒菜,原本那 50 個訂單就根本沒在怕的啦 XD
這個情境下,系統通常是這樣實作:建立一個 queue,將等待處理的 task 全部放進 queue 中,並讓 idle 的 consumer 自動從 queue 中取得一個 task 來執行 (當然也有可能是用 dispatch 的方式)。
假設有 A、B、C 三個使用者的 task 的放進 queue 來處理,一般情況下 queue 的狀態大概會向下面這個樣子:
=> A, C, B, C, A, A, C, A, B, C, B =>
但大多時候工作的分配通常不會這個平均,有時 A 使用者會需要大量處理資料,於是 queue 就會成下面這個樣子:
=> A, C, B, C, A, A, A .... (x1000), A, A, C, A, B, C, B =>
若這個情況下仍然使用相同的 consume 機制,會變成大多數的時間都在處理 A 的 tasks,導致 B、C 使用者的 task 被 (無限) 延後。
在一般狀態下這樣不是一件好事,就像去餐廳買飯,因為前面有個 50 人份的訂單排在你前面,就導致你買一個便當也要等一個多小時。在我自己碰到的狀況,這個時候餐廳通常會有二種作法:
- 直接關店不在讓其他客人點餐,專心處理大量訂單
- 餐廳仍然讓客人點餐,且會在客人與訂單有相同餐點時,一起處理餐點並同時出餐,所以客人會在大量訂單處理完之前,即可以收到餐點並離開
將上面提到的情況改用在 task queue 上,若遇到類似的問題,則可以考慮不同處理 queue 的方法。
例如為不同用途、類型的 task 分別建立不同的 queue,而每次都從個別的 queue 做一次 de-queue,這樣就不會因為 queue-A 大量的 task 卡住其他的 task:
queue for A: t999, t998, t997, ...., t3, t2, t1
queue for B: t3, t2, t1
queue for C: t6, t5, t4, t3, t2, t1
另外也可以考慮使用類似 Laravel API rate limit 的功能,分別記錄每個時段中,各類型的 task 共處理了多少次,若超過限制,則將原本 de-queue 出來準備處理的 task 在 in-queue 輪到較晚處理:
step 1: C, B, A, A, A, A, A, C, A
step 2: C, B, A, A, A, A, A, C
step 3: C, B, A, A, A, A, A
step 4: C, B, A, A, A, A
step 5: C, B, A, A, A // 連續處理二個 A task 了,到達上限
step 6: A, C, B, A, A
step 7: A, A, C, B, A
step 8: A, A, A, C, B
step 8: A, A, A, C
....
當然,用錢可以解決的問題都不是問題。把廚房加個 100 倍大,請一批廚師來炒菜,原本那 50 個訂單就根本沒在怕的啦 XD
2019/05/31
Build AWS EC2 for CodeDeploy
最後更新時間:2019/05/31
文章開頭先謝謝 ellery 大大,沒有你提醒,我大概會繼續通靈 debug 幾個禮拜 XD
先說明 CodeDeploy 大概的運作機制:
TL;DR
文章開頭先謝謝 ellery 大大,沒有你提醒,我大概會繼續通靈 debug 幾個禮拜 XD
先說明 CodeDeploy 大概的運作機制:
- 先設定好 EC2 的基本權限 (IAM)
- 要支援 CodeDeploy 的 EC2 instance 必須安裝 CodeDeploy agent (很重要,EC2 上 trigger event 都是靠這個 agent)
- 設定 CodeDeploy 上 Application 對應到的 EC2 instances
- User 先將打包好的 code 送到 S3 上存放
- 接下來 trigger application 上特定的 deploy-er,將特定版本的 code 從 S3 上派送到 EC2 instance 上
- EC2 instance 的 CodeDeploy agent 收到 event 以後,會按照 appspec.yml 中指定的動作來動作,操作完成會回傳 status 給 CodeDeploy。
- CodeDeploy 會在 pannel 顯示 deploy 的進度和狀態。
TL;DR
2019/05/27
Deploy to AWS EC2 via Rsync
今天嘗試讓 Bitbucket 的 Pipeline 測試完畢以後,自動部屬到 EC2 上。
遇到幾個有點頭大的問題:
注意紅色標記的地方,這幾個都是很重要的 key,把這些資料放在 script、git repository 都是很糟糕的方法。
繼續找方法解決這些鳥問題。
遇到幾個有點頭大的問題:
- EC2 只要 restart 後 IP 都會改變
- RSync based 在 SSH 上,所以再次連線都會有 hand shake 問題 (known_hosts)
- 要連上 EC2 需要 ssh -i my.PEM,把這個 PEM 塞進 Pipeline 或是參數都是好方法
這幾點先不考慮的時候,pipeline script 大概會長這樣:
- step:
name: Deploy to EC2
deployment: test
caches:
script:
- apt-get update && apt-get install -y zip unzip rsync openssh-client ssh
- rm -fr .git vendor
- curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
- composer --version
- composer install --no-interaction --no-progress --prefer-dist --no-dev
- chmod 600 u18-micro.pem
- echo '|1|gdwZ6TN1l9.............GOqLzzpGY=' > ${HOME}/.ssh/known_hosts
- rsync -av --delete --force --progress -e "ssh -i my-ec2.pem" ./ ubuntu@${Host}:/var/www/
注意紅色標記的地方,這幾個都是很重要的 key,把這些資料放在 script、git repository 都是很糟糕的方法。
繼續找方法解決這些鳥問題。
2019/05/23
UbuntuMate 18.04 無法鎖定畫面
開機後突然沒有辦法使用快速鍵「Ctrl + Alt + L」來鎖定畫面,覺得很不對對勁。
網路上看了幾篇文章以後,發現螢幕鎖定和 gnome 的 screen saver 都有關係,由於 UbuntuMate 的預設不是使用 gnome,所以找到的是 mate-screensaver-command:
由於之前腦包把 background daemon 關掉,所以螢幕保護服務沒有啟動,不管怎麼下指令都不會有反應。記得「啟動應用程式」中,把「螢幕保護程式」開啟,以免部份功能失效:
網路上看了幾篇文章以後,發現螢幕鎖定和 gnome 的 screen saver 都有關係,由於 UbuntuMate 的預設不是使用 gnome,所以找到的是 mate-screensaver-command:
$ mate-screensaver-command -h
Usage:
mate-screensaver-command [OPTION…]
Help Options:
-h, --help Show help options
Application Options:
--exit Causes the screensaver to exit gracefully
-q, --query Query the state of the screensaver
-t, --time Query the length of time the screensaver has been active
-l, --lock Tells the running screensaver process to lock the screen immediately
-c, --cycle If the screensaver is active then switch to another graphics demo
-a, --activate Turn the screensaver on (blank the screen)
-d, --deactivate If the screensaver is active then deactivate it (un-blank the screen)
-p, --poke Poke the running screensaver to simulate user activity
-i, --inhibit Inhibit the screensaver from activating. Command blocks while inhibit is active.
-n, --application-name The calling application that is inhibiting the screensaver
-r, --reason The reason for inhibiting the screensaver
-V, --version Version of this application
由於之前腦包把 background daemon 關掉,所以螢幕保護服務沒有啟動,不管怎麼下指令都不會有反應。記得「啟動應用程式」中,把「螢幕保護程式」開啟,以免部份功能失效:
標籤:
Linux
2019/05/07
GNU grep 的 exit code 會因結果而不同
昨天寫了類似以下這樣一段 script:
照理來說,不管 grep 是有有撈到資料,至少會印出「Results found」字樣,但實際執行時卻什麼資料都沒有輸出。
後來使用「bash -xv」來執行,監視值流程,才發現 script 執行到一半就中斷了:
追蹤後發現二個結果交互影響導致 script 中斷:
在 bash 中「set -e」代表遇到錯誤立即中斷執行;而 grep 的 exit code 比較令人意外,當 grep 有找到資料時,則 exit code 為 0 (正常結束),若 grep 都沒有找到指定的字串,則會回傳 1 (錯誤)。這二件事情同時發生,所以就導致了上面的 script 在 grep 執行後就中斷執行。
// ------
shell script 好像沒什麼 debug 的工具,不過在執行時可以透過 bash 的參數,來提供執行時的一些狀態,例如: -xv。
#!/usr/bin/env bash
set -e
R=`ls /dev/ | grep sd`
echo "Results found:"
echo $R
照理來說,不管 grep 是有有撈到資料,至少會印出「Results found」字樣,但實際執行時卻什麼資料都沒有輸出。
後來使用「bash -xv」來執行,監視值流程,才發現 script 執行到一半就中斷了:
$ bash -xv qwe.sh
#!/usr/bin/env bash
set -e
+ set -e
R=`ls /dev/ | grep sd`
++ ls /dev/
++ grep sd
+ R=
追蹤後發現二個結果交互影響導致 script 中斷:
- set -e 的設定
- grep 的 exit code
在 bash 中「set -e」代表遇到錯誤立即中斷執行;而 grep 的 exit code 比較令人意外,當 grep 有找到資料時,則 exit code 為 0 (正常結束),若 grep 都沒有找到指定的字串,則會回傳 1 (錯誤)。這二件事情同時發生,所以就導致了上面的 script 在 grep 執行後就中斷執行。
// ------
shell script 好像沒什麼 debug 的工具,不過在執行時可以透過 bash 的參數,來提供執行時的一些狀態,例如: -xv。
2019/05/06
在 bash 看指令執行後的 exit status code
老題目了,做個筆記。
Linux 底下,所有程式、指令結束都會有個 exit code,有點像是執行成功、或失敗的狀態。一般來說,正常執行的 exit code 都會是 0。
如果要看前一個指令執行後的 exit code,可以使用「echo $?」來看:
Linux 底下,所有程式、指令結束都會有個 exit code,有點像是執行成功、或失敗的狀態。一般來說,正常執行的 exit code 都會是 0。
如果要看前一個指令執行後的 exit code,可以使用「echo $?」來看:
$ cd .
$ echo $?
0
$ mkdir app
mkdir: cannot create directory ‘app’: File exists
echo $?
1
2019/05/03
幾個清空 docker 資料的好用指定
中斷所有正在運作的 container:
刪除所有已中止的 container:
刪除所有的 images:
節錄自:Top 10 Docker CLI commands you can’t live without
docker kill $(docker ps -q)
刪除所有已中止的 container:
docker rm $(docker ps -a -q)
刪除所有的 images:
docker rmi $(docker images -q)
節錄自:Top 10 Docker CLI commands you can’t live without
2019/04/25
幫 MySQL 加上 storage engine 設定來支援 utf8mb4
在前篇有提到要在 my.ini 設定預設值,但實際要完全可以支援到 UTF8mb4 的話,還要多幾項設定,不然還是有機會遇到錯誤,像是:「The maximum column size is 767 bytes」之類的。
先講「innodb_large_prefix」,由於 UTF8mb4 會讓儲存相同內容的 bytes 更多,建立索引時會發生錯誤,所以必須支援 large preefix 來避免建立所以時發生錯誤。可以參考 MySQL 官方說明。
在 MySQL 5.7 之後,InnoDB 新增個幾種儲存格式,像是 Barracuda,可以應付各種不同的情境,也可以支援 UTF8mb5 這種字元,所以要使用的話大概會需要這樣設定:
完整的設定檔大概會類似下面這樣:
先講「innodb_large_prefix」,由於 UTF8mb4 會讓儲存相同內容的 bytes 更多,建立索引時會發生錯誤,所以必須支援 large preefix 來避免建立所以時發生錯誤。可以參考 MySQL 官方說明。
在 MySQL 5.7 之後,InnoDB 新增個幾種儲存格式,像是 Barracuda,可以應付各種不同的情境,也可以支援 UTF8mb5 這種字元,所以要使用的話大概會需要這樣設定:
innodb_large_prefix
innodb_file_per_table = 1
innodb_file_format=Barracuda
innodb_default_row_format=DYNAMIC
完整的設定檔大概會類似下面這樣:
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
innodb_large_prefix
innodb_file_per_table = 1
innodb_file_format=Barracuda
innodb_default_row_format=DYNAMIC
[mysqldump]
default-character-set = utf8mb4
標籤:
MySQL
2019/04/11
讓 MySQL 預設使用特定的 character set
MySQL 支援多個不同的 character set,像是 latin1、utf8 等等,但是只要在規劃、連線時沒有做好設定,就很容易對應到錯誤的 character set 導致出現亂碼。
自己從 gslin 和 Percona、Study-Area 那邊整理出一些比較保險的設定方法,可以避免之後在維護時發生錯誤:
備註:
自己從 gslin 和 Percona、Study-Area 那邊整理出一些比較保險的設定方法,可以避免之後在維護時發生錯誤:
[client]
default-character-set = utf8mb4
[mysqld]
default-storage-engine = InnoDB
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect='SET collation_connection = utf8mb4_unicode_ci'
init_connect='SET NAMES utf8mb4'
備註:
- 以上設定檔適用於 MySQL / Percona server 5.7,不同版本有不同的 config keyword
- 上面的範例為 utf8mb4,可自行調整成自己需要的 character set
- 就算 MySQL server 有這些設定以後,連線到 MySQL 的程式也需要注意編碼設定,否則還是會發生編碼錯誤
標籤:
MySQL
2019/04/09
Garmin fenix 手錶錶帶扣環斷裂的處理
Garmin fenix 3 HR 的手錶,錶帶扣環因為長期使用 (約 2 年) 而斷裂。
查詢後大概知道有幾個處理方式:
錶帶固定扣環我們可以郵局平信的方式免費提供給您,在請您留意郵件。
扣環安裝不需拆下錶帶。
因扣環稍有彈性,在套進去錶帶時,稍微拉撐後,慢慢推入錶帶內即可。
查詢後大概知道有幾個處理方式:
- 到各縣市維修站點送修
- 參考 Garmin 官方網頁說明,請客服協助處理
這次是透過 email 聯繫 Garmin 客服,先請教報修流程,很意外的 Garmin 客服表示扣環斷裂,可以透過寄信的方式,將零件寄送到住處並自行處理:
扣環安裝不需拆下錶帶。
因扣環稍有彈性,在套進去錶帶時,稍微拉撐後,慢慢推入錶帶內即可。
收到扣環後,在將扣環套進錶帶時,會因為最前端的金屬卡榫大小幾乎一致而很難套入,需要稍用力將橡皮扣環拉開。套入後即可正常使用。
標籤:
生活雜記
2019/02/25
Ubuntu 18.04 網路設定檔異動
在 Ubuntu 14.04 時代,網路介面的設定檔在 /etc/network/interfaces,但在 18.04 以後改用了 netplan 來做網路介面的管理,設定檔也跟著改變。
打開 /etc/network/interfaces 後,你會看到以下的說明:
若要修改網路設定檔,大至上要二個步驟:
確認網路介面的 ID (Ubuntu 18.04 的網路介面代號與 14.04 不同)
修改網路設定檔:/etc/netplan/50-cloud-init.yaml
舊版的網路卡 ID 會是「eth0」這樣的表示,不過在 Ubuntu 18.04 代號有變動,記得先使用 ifconfig 確認:
Ubuntu 18.04 使用的 netplan 設定檔位於 /etc/netplan/*.yaml,如果是新安裝好的機器,應該可以看到「50-cloud-init.yaml」這個檔案。
開啟檔案後,可以看到以下格式的設定:
YAML 的檔案格式可以參考 netplan.io 的說明。
假設要改成 static IP,則設定檔的大概會改成以下這個樣子:
設定檔修改以後不會立即生效,需要呼叫 netplan 讀取並套用新的設定:
打開 /etc/network/interfaces 後,你會看到以下的說明:
# ifupdown has been replaced by netplan(5) on this system. See
# /etc/netplan for current configuration.
# To re-enable ifupdown on this system, you can run:
# sudo apt install ifupdown
若要修改網路設定檔,大至上要二個步驟:
確認網路介面的 ID (Ubuntu 18.04 的網路介面代號與 14.04 不同)
修改網路設定檔:/etc/netplan/50-cloud-init.yaml
確認網路介面的 ID
舊版的網路卡 ID 會是「eth0」這樣的表示,不過在 Ubuntu 18.04 代號有變動,記得先使用 ifconfig 確認:
$ ifconfig -a
ens33: flags=4163 mtu 1500
inet 192.168.0.102 netmask 255.255.255.0 broadcast 192.168.0.255
inet6 fe80::20c:29ff:fead:d664 prefixlen 64 scopeid 0x20
....
修改網路設定檔
Ubuntu 18.04 使用的 netplan 設定檔位於 /etc/netplan/*.yaml,如果是新安裝好的機器,應該可以看到「50-cloud-init.yaml」這個檔案。
開啟檔案後,可以看到以下格式的設定:
network:
ethernets:
ens33:
addresses: []
dhcp4: true
version: 2
YAML 的檔案格式可以參考 netplan.io 的說明。
假設要改成 static IP,則設定檔的大概會改成以下這個樣子:
network:
ethernets:
ens33:
addresses: [192.168.0.10/24]
gateway4: 192.168.0.1
nameservers:
addresses: [8.8.8.8, 1.1.1.1]
dhcp4: false
version: 2
設定檔修改以後不會立即生效,需要呼叫 netplan 讀取並套用新的設定:
$ sudo netplan apply
2019/02/19
Kali Linux 2019.1 released
2019/02/18
Ruby 語法一些不太喜歡的地方
最近學 Ruby 看到一些特性,讓我覺得有點毛毛的,像是 Ruby 的 function call syntax:
count() 還算好,如果是 fetch() 就有趣了:
不否認這種特性可以工程師提高開發效率,算是 syntax sugar 吧?但是若沒有一致的 coding srandard,可能會讓整個專案的程式碼變的雜亂不容易閱讀,這樣就變成「syntax salt」了。
感謝 @david50407 提供 Ruby Style Guide!
list = [0, 1, 2, 3, 4]
list.count()
# 寫可以這樣寫
list.count
count() 還算好,如果是 fetch() 就有趣了:
list.fetch(3) # 3
# 刮號可以省略
list.fetch 3 # 3
不否認這種特性可以工程師提高開發效率,算是 syntax sugar 吧?但是若沒有一致的 coding srandard,可能會讓整個專案的程式碼變的雜亂不容易閱讀,這樣就變成「syntax salt」了。
list = [1, 2, 3]
# 這個應該沒什麼問題
list.fetch(1) + 5 # 7
# 這個就很容易誤會了
list.fetch 1 + 5 # IndexError
感謝 @david50407 提供 Ruby Style Guide!
標籤:
Ruby
2019/02/07
2019/01/16
PHP 5.6 new release
官方原本要在 2018/12 中止對 PHP 5.x 的支援,但 2019/01 還是發布了 5.6 的更新,自動內容大致如下:
- GD library 的 security fix
- mbstring 的 bug fix
- Phar 的 security fix
- xmlrpc 的 security fix
還沒更新上 PHP 7.x 的人記得更新。
標籤:
PHP
訂閱:
文章 (Atom)