2017/08/20

大雪山一日遊遇好心人協助,大感謝

最近幾天實在很熱,趁機跑到台中大雪山的橫嶺山步道避暑兼運動。

騎上橫嶺山第一個入口,海拔約 1300 m 就能感受到涼意。在大坑派出所向警員問了路,才知步道有二個入口,第一個入口海拔較低,但是也可以從第二個入口 (在山洞旁) 進入 ,第一個入口會一路爬坡銜接道第二個入口,大約要走 4 ~ 5 小時。如果不想太累的話,可以直接從個入口進入,路比較平。

在第二個入口處比較不好找車位,停好車發現難得有手機訊號,並收到一個簡訊,表示劉先生撿道我的皮夾並送到派出所,要我盡快前往領取。

摸了一下口袋,幹 ... 皮夾因為山路叫抖、運動口袋又淺,居然已經滑出去了!!!

心跳瞬間衝到 180 bpm,馬上騎車回到剛剛問度路的派出所並找到聯絡上員警,沒想到聯絡我的警察和剛剛問度的是同一位,笑了一下說:「看來你今天是註定要來看我的」 XD

從四次元背包翻出了幾個收據和個人資料確認身份以後,發現皮夾的現金、證件一個都沒有少,實在太感動了。

這裡再次感謝匿名的劉先生和大坑派出所的林警員,謝謝!

-----

這樣跑了一趟以後,走步道的時間已經不夠了,想說就直接回市區。在派出所外面遇到一位陌生人,說先生走路上山去開車,但是已經走了好幾個小時還沒道,看看我有沒有辦法騎車上去找人順便傳話。

機車油箱還夠,借手機給那位太太試著聯絡,並同步了一下我和他先生穿的衣服樣式後,便上山找人了。這為先生很拼,從太坑派出所一直走,打算走到第二個山洞開車下來接他太太,不過聽起來太陽下山可能還來不及走到定點,便直接在他去找車。

這位毅力斐淺的林先生也是常常爬山旅遊的山友,一路上還特別推薦我台中附近幾個不錯的踏青步道,聊的實在很開心。

覺得這次受到好心人幫助以後,應該抱著同樣的心情,把這份恩情傳給別人,這樣社會才會更好 (就像是電影「讓愛傳出去」的感覺吧,有聽過這部電影的年紀應該都不小了 XD)。

ps. 覺得篇箱地區的人們,比城市裡的人更有人情味、更好相處

大雪山的橫嶺山步道路況

最後更新時間:2017/08/19


跑去大雪山的橫嶺山步道,順便記錄一下路況。

我是騎機車上山的,第一件事情就是不要完全按照 Google Maps 的建議路線行走,他會帶你去走私有土地 ... (死)

從東勢沿著專一道晚上騎到恆嶺山比較上面的入口,柏油路僅有幾處破洞,大致上沒什麼安全疑慮,不過沿路有幾處有落石,建議小心行駛。

越往山上的路寬越窄,請留意會車問題,且大約中午 12 點過後便開始起霧,行駛時請務必開大燈,讓自己與對象來車都能保持行車安全!

2017/08/18

puppeteer from Google Chrome

前幾天 Google 發布了 Puppeteer:一個可以控制 Chrome Headless 的 nodejs library。

透過 demo code 可以看到要產生 PDF 也好、要做 screen shot 也好,基本上都可以在數行以內解決:
const puppeteer = require('puppeteer');

(async() => {

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});

browser.close();
})();

感覺就是拿來做壞事的好工具呀,也不用寫什麼 JavaScript emulator 去取得實際的網頁 DOM 狀態了 XD

官方文件已經有 Chrome Headless + Pupetteer 的網頁 debug demo:https://developers.google.com/web/updates/2017/04/headless-chrome

2017/08/17

rpm 列出套件時不顯示套件版本號

一般在尋找 CentOS 上到底安裝哪一些套件時,指令大概會這樣下:
$ rpm -aq | grep php-fpm
php71-php-fpm-7.1.7-1.el7.remi.x86_64

不過如果是要用 diff 比對二台機器安裝的套件是否相同,這個時候多了套件版本號就頭大了。

查了一下資料,rpm 有提供「--qf」(query-format) 可以自行設定列表要輸出的內容。

若使希望看到套件名稱,而不想列出套件版本時,指令可以這樣下:
$ rpm -aq --qf "%{NAME}\n" | grep php-fpm
php71-php-fpm

記得行尾要換行,不然就 GG 了 XD

2017/08/05

PHP strict typing performance

聽說 PHP 使用 strict type hint 會讓速度變慢,於是來做了個簡單的測試,先來個沒有 type hint 的:
<?php

function repeat($str)
{
    return $str;
}

$start = microtime(true);

for ($i = 0; $i < 100000000; $i++) {
    repeat('test');
}

$end = microtime(true);

var_dump($end - $start);

使用 PHP 7.1.8 執行,大概會花費 3.7 秒左右:
$ php main.php
float(3.713329076767)


接下來改成 strict type 的寫法:
<?php

declare(strict_types=1);

function repeat(string $str): string
{
    return $str;
}

$start = microtime(true);

for ($i = 0; $i < 100000000; $i++) {
    repeat('test');
}

$end = microtime(true);

var_dump($end - $start);

執行時間大概變成 5.3 秒左右:
$ php main.php 
float(5.3128638267517)

的確慢了不少,不過先別著急,不要因為慢了一些就打算放棄 strict type hint。

使用 PHP 5.6 去執行第一個測試 (沒有 strict type) 就大約需要 19 秒:
$ php5.6 main.php
float(19.477375030518)

其實把 PHP 版本升級上 7.x 才是正確的吧 XD

2017/08/02

Apache / Nginx 與 PHP 各種搭配方式的效能測試

以 PHP 為主的 HTTP server 有很多種架設方式,最傳統的大概就是 Apache + mod_php 來執行 PHP scripts。隨著技術一直在翻新,後來也有了 Nginx + php-fpm 的搭配模式出現,甚至連 PHP 在 5.4.0 都推出了 built-in server

因公司需要,就順手測試了以下幾種搭配:

在開始看壓力測試結果之前,先來說一下測試環境:
  • 所有的 HTTP server 除了以上搭配方式之外,其他都使用預設值 (像是不開啟 gzip 壓縮等)
  • 另外壓力測試的 PHP script 內容也很簡單,僅有「phpinfo();」一行
  • 1 core CPU
  • 4 GB RAM
  • 使用 ab (Apache Bench) 做測試
  • ab 中每個 concurrency 固定會發出 1000 個 HTTP request,如 concurrency = 1 時僅有 1000 個 request,concurrency = 100 時,則送出 1000 x 100 個 request。
  • 每次 ab 跑完一次壓力測試,均重新啟動 HTTP server 與 PHP server,以防止使用到 cache。

先簡單做個結論,詳細的壓力測試結果再請大家自行過目:
  • concurrency = 1 時,沒有壓力測試會出現的情況,不過可以把 response time 和伺服器的 CPU、記憶體使用量當作一個基準值作為參考。
  • Apache mpm-prefork 搭配 mod_php 的記憶體使用量最大,畢竟要 fork 一個 Apache instance 出來就要把 Apache 個 module 也 initialize 出來。小型伺服器不推薦這個方案。
  • php-fpm 即使設定「pm.max_children = 50」,也可以輕鬆負荷超過 50 個 concurrency。比較微妙的是從 htop 看不出 php-fpm 有使用 thread 來同時處理 request。
  • php-fpm listen on Unix socket 的效率比 listen TCP (127.0.0.1:9000) 的效率還要高一些,但是在高負荷的情況下會變得很不穩定,猜測和 OS 的 socket 實作、設定有關連。
  • PHP built-in server 遇到在高負載的情況下表現的不錯,唯獨 log 給的資訊太少,不方便做分析。但也可考慮透過 Nginx proxy 給 PHP built-in server,讓 Nginx 來處理 log。

最後做個廣告,Hackmd 真不錯用,筆記寫完最後還以轉換成 HTML 下載,有夠方便的啦!

2017/08/01

在 PHP 判斷參數為 anonymous function 的方法

在追各個 framework 的一些元件結構,anonymous function 已經被大量使用在不同的用途上了。

如果 function 要判斷外部傳進來的參數,是否為 anonymous function,有幾個作法。

一個是判斷是否可以被呼叫:
is_callable($param)

另外,由於所有的 anonymous function 其實屬於一個 PHP Closure 類別,所以也可以用下面這個方法做判斷 (且判斷結果還比較準確):
$param instanceof \Closure