2017年9月29日 星期五

PHP 7 and PHP 5.6 for Windows XP/2003

Original page: http://www.lindasc.com/php/  (Here is just a translation.)
PHP Version: 7.0.9 / 5.6.24
Updated: 2016-7-28
Supported OS: Windows XP/2003
Description:
  Instead of patching and rebuilding the whole PHP completely, which is a complicated work, this work implements the API functions that are only available after Vista and then patches the import descriptors of the executable files.
  The implemented functions are listed as follows.

DLL file function name ver. of nonxp.dll
iphlpapi.dll if_nametoindex 0.0.1.11
kernel32.dll GetFinalPathNameByHandleA 0.0.2.20
GetFinalPathNameByHandleW 0.0.2.20
GetTickCount64 0.0.1.11
InitializeConditionVariable 0.0.4.40
InitializeCriticalSectionEx 0.0.3.30
SleepConditionVariableCS 0.0.4.40
WakeAllConditionVariable 0.0.4.40
WakeConditionVariable 0.0.4.40
shell32.dll SHGetKnownFolderPath 0.0.3.30
ws2_32.dll WSASendMsg 0.0.1.11
inet_ntop 0.0.1.11
inet_pton 0.0.1.11

  Instructions of installation:
  PHP 7: the OS must install IE8 and VC14 redistributable package.
      PHP 5.6: the OS must install IE8 and VC11 redistributable package.
  Download links:
Source code
Source code of nonxp.dll
The source code of nonxp.dll and the patch tool have been uploaded to github, php-5.6-xp-2003, according to the permission of the original author.

2017年9月20日 星期三

Slim 2 與 Laravel 5.0,小比一下

使用 Laravel 一陣子了,好像只用到其中一小部分,如 Query builder、Request、View 等。然後,可以使用 Composer 將一些東西包進 Slim,程式就可以跑了。

環境是 Windwos server 2003+fast-cgi,PHP 為 PHP 5.4.45+wincache 及 PHP 5.6.24+opcache。

 $ ab -n 100 -c 4 http://10.161.81.188/test/sdic_qry/index.php/sql_qry?dep=P020

hello-world,只是單純送出 "Hello, world!" 的字串,用來測試空的 framework 的性能。Slim 2 有加裝一些 package,也設定一些習慣使用的 Laravel 的靜態介面。

sql_qry 則進行資料庫的 query,用以測試資料庫存取的影響。其中,後端資料庫為安裝在 VM 的 SQL 2000 server。

PHP 5.6.24

Slim 2,debug off,hello-world,,Requests per second:    189.16 [#/sec]
Slim 2,debug on,hello-world,Requests per second:    187.35 [#/sec] (mean)
Slim 2,debug off,sql_qry,Requests per second:    143.17 [#/sec] (mean)
Slim 2,debug on,sql_qry,Requests per second:    129.30 [#/sec] (mean)

Slim 3,debug on,hello-world,Requests per second:    143.44 [#/sec] (mean)
Slim 3,debug off,sql_qry,Requests per second:    118.56 [#/sec] (mean)

Laravel 5.0,hello-world, 66.33 [#/sec] (mean)
Laravel 5.0,sql_qry,5.6.24,Requests per second:    55.74 [#/sec] (mean)

Slim 2,debug off,laravel-session (file/database),Requests per second:    60 [#/sec] (mean)

PHP 5.4.45

Slim 2,debug on,hello-world,Requests per second:    80.37 [#/sec] (mean)
Slim 2,debug off,hello-world,Requests per second:    110.83 [#/sec] (mean)
Slim 2,debug off,sql_qry,Requests per second:    87.60 [#/sec] (mean)
Slim 2,debug on,sql_qry,Requests per second:    72.85 [#/sec] (mean)
L5,sql_qry,5.6.24,Requests per second:    25.22 [#/sec] (mean)
L5,hello-world, 29.75 [#/sec] (mean)

測試中,Tracy/Debuger 會造成 Failed requests。
在 Slim 2 中,加上 Laravel 的 session 後,效能降到和 Laravel 差不多。
其中,session 的垃圾收集,會大幅的拖慢效能。垃圾收集的時機,由設定中的 'lottery' => [2, 100] 來決定,此代表 50 次,會做一次垃圾收集。減少垃圾收集的機率,可提升效能。
請參考 PHP Session Garbage Collection: The unknown performance bottleneck
所以,是否使用 Laravel 的 session,會是一個決擇。然而,其可以選擇不同的 drvier,實在是非常方便的作法。

以下為使用下列指令測試的結果

$ ab -n 100 -c 10 http://10.161.81.188/test/sdic_qry/index.php/cou_cur/introduction?cur=P020

Slim 2 的結果如下

Server Software:        Microsoft-IIS/6.0
Server Hostname:        10.161.81.188
Server Port:            80

Document Path:          /test/sdic_qry/index.php/cou_cur/introduction?cur=P020
Document Length:        18064 bytes

Concurrency Level:      10
Time taken for tests:   1.373 seconds
Complete requests:      100
Failed requests:        26
   (Connect: 0, Receive: 0, Length: 26, Exceptions: 0)
Write errors:           0
Total transferred:      1829852 bytes
HTML transferred:       1806452 bytes
Requests per second:    72.85 [#/sec] (mean)
Time per request:       137.275 [ms] (mean)
Time per request:       13.727 [ms] (mean, across all concurrent requests)
Transfer rate:          1301.74 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.7      0       4
Processing:    52  129  41.4    119     330
Waiting:       50  128  41.4    118     329
Total:         52  130  41.5    120     331

Percentage of the requests served within a certain time (ms)
  50%    120
  66%    131
  75%    140
  80%    145
  90%    178
  95%    206
  98%    308
  99%    331
 100%    331 (longest request)

Laravel 5.0 的結果如下

Server Software:        Microsoft-IIS/6.0
Server Hostname:        10.161.81.188
Server Port:            80

Document Path:          /test/sdic_for_reg/index.php/cou_cur?cur=P020
Document Length:        14987 bytes

Concurrency Level:      10
Time taken for tests:   3.927 seconds
Complete requests:      100
Failed requests:        0
Write errors:           0
Total transferred:      1606344 bytes
HTML transferred:       1498700 bytes
Requests per second:    25.46 [#/sec] (mean)
Time per request:       392.702 [ms] (mean)
Time per request:       39.270 [ms] (mean, across all concurrent requests)
Transfer rate:          399.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   1.1      0       5
Processing:   146  372  95.2    346     738
Waiting:      143  370  95.0    345     737
Total:        147  373  95.4    347     739

Percentage of the requests served within a certain time (ms)
  50%    347
  66%    400
  75%    436
  80%    463
  90%    495
  95%    527
  98%    626
  99%    739
 100%    739 (longest request)

結果是 Slim 2 大概是 Laravel 5.0 的 3 倍。然後,隨著程式成長,使用 Slim 的環境,也由每秒完成的 request 也由 72 個降到 65 個左右。

再 Optimizing Composer's autoloader 一下,指令 composer  dumpautoload -o,又稍微提升到每秒完成 75 個 request。

2018-01-29 測試

應用程式的條件,使用 Laravel 的 DB 和 View,關掉 debug。在 optimize 以前,大約 100 [#/sec],optimize 後,約 118 [#/sec]。
不過,結果不是很穩定,後來再測,降到約 70 [#/sec]。

使用 ApacheBench (ab) 測 Slim 變得很慢

參考 HTTP, Slim and ApacheBench

使用 Apache 伺服器跑 Slim 時,用 ab 測效能,會變得很慢,一秒才處理一個 request。
這是因為 ab 送出 HTTP/1.0 的 request,它會等伺服器關閉 connection。可是 Slim 卻回應 HTTP/1.1 的 header,因此雙方在互相等待連線關閉。

解決辦法,針對所有的 HTTP/1.0 或沒有 Connection header 的 request,都送出 "Connection: close" 。在 Slim 初始化後,加上下面的程式碼。

if ($_SERVER['SERVER_PROTOCOL'] == 'HTTP/1.0' && 
   empty($_SERVER['HTTP_CONNECTION'])
) {
    // header('Connection: close');
    $app->response->headers->set('Connection', 'close');
}


2017年9月18日 星期一

透過 WINE 安裝 FileZilla ftp server (失敗)

因為想把一些在 Windows 2003 server 上跑的服務,移到 docker 的虛擬平台上,所以想透過 WINE 安裝 FileZilla ftp server。先說測試結果 -- 失敗,雖然離成功只剩一小步,但可能無法跨越。

起先在 docker 下執行 WINE,參考 suchja/wine 的作法。
在 docker host 上,不需安裝 X window,使用 suchja/x11server 來當圖形界面輸出。
docker run -d --name display -e VNC_PASSWORD=newPW -p 5900:5900 suchja/x11server

然後啟動  Wine container,如下:
docker run --rm -it --link display:xserver --volumes-from display suchja/wine:latest /bin/bash

啟動 container 後,啟始 wine
wine wineboot --init

下載安裝檔
curl http://xxx.com/yyy/FileZilla_Server-0_9_43.exe -o FileZilla_Server-0_9_43.exe
XP 支援的版本,只到 0.9.43。

安裝,在便令視窗下指令,然後,要透過 vnc client 連上 server,操作圖形視窗。
wine FileZilla_Server-0_9_43.exe

注意,安裝時,需要 root 的身分,才能開啟 port,ftp server才能啟動。在上述指令,不要加上 --rm 的選項,離開 container 的互動介面後,將此 container 存成 image。
docker commit f26355b23ac6 wine-filezilla-server

使用新的 image 啟動 container,使用下列指令啟動 ftp server,以及進入管理界面。
wine FileZilla\ Server.exe /compat /start &
wine FileZilla\ Server\ Interface.exe &

管理界面,有點怪怪的,右側 acount list 不會出現,按一下左邊的 item,就會出現。可以建立帳號,但指定目錄,有點不太行。

建好帳號後,用 client 端登入,可以登入,但是讀資料失敗,ls -aL 無法成功。
"503 Bad sequence of commands" 的錯誤,推測 wine 不適合執行網路伺服器的程式。

以上,記錄安裝測試的大致過程,供做參考。

2017年9月12日 星期二

ThinkPad Trackpoint 設定



$xinput
⎡ Virtual core pointer                     id=2 [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer               id=4 [slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                   id=12 [slave  pointer  (2)]
⎜   ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint id=8 [slave  pointer  (2)]
⎣ Virtual core keyboard                   id=3 [master keyboard (2)]
    ↳ Virtual core XTEST keyboard             id=5 [slave  keyboard (3)]
    ↳ Power Button                             id=6 [slave  keyboard (3)]
    ↳ Power Button                             id=7 [slave  keyboard (3)]
    ↳ Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint id=9 [slave  keyboard (3)]
    ↳ Logitech USB Receiver                   id=13 [slave  keyboard (3)]

$xinput list-props "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint"
Device 'Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint':
Device Enabled (152): 1
Coordinate Transformation Matrix (154): 1.000000, 0.000000, 0.000000, 0.000000, 1.000000, 0.000000, 0.000000, 0.000000, 1.000000
Device Accel Profile (413): 0
Device Accel Constant Deceleration (414): 1.000000
Device Accel Adaptive Deceleration (415): 1.000000
Device Accel Velocity Scaling (416): 10.000000
Device Product ID (271): 6127, 24585
Device Node (272): "/dev/input/event14"
Evdev Axis Inversion (417): 0, 0
Evdev Axes Swap (419): 0
Axis Labels (420): "Rel X" (162), "Rel Y" (163)
Button Labels (421): "Button Left" (155), "Button Middle" (156), "Button Right" (157), "Button Wheel Up" (158), "Button Wheel Down" (159), "Button Horiz Wheel Left" (160), "Button Horiz Wheel Right" (161), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412), "Button Unknown" (412)
Evdev Scrolling Distance (422): 0, 0, 0
Evdev Middle Button Emulation (423): 0
Evdev Middle Button Timeout (424): 50
Evdev Middle Button Button (425): 2
Evdev Third Button Emulation (426): 0
Evdev Third Button Emulation Timeout (427): 1000
Evdev Third Button Emulation Button (428): 3
Evdev Third Button Emulation Threshold (429): 20
Evdev Wheel Emulation (430): 0
Evdev Wheel Emulation Axes (431): 0, 0, 4, 5
Evdev Wheel Emulation Inertia (432): 10
Evdev Wheel Emulation Timeout (433): 200
Evdev Wheel Emulation Button (434): 4
Evdev Drag Lock Buttons (435): 0

$xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation" 1
$ xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation Button" 2
$ xinput set-prop "pointer:Lite-On Technology Corp. ThinkPad USB Keyboard with TrackPoint" "Evdev Wheel Emulation Timeout" 200


The need for the "--with-bdeps y" and "--backtrack 100" switches will go away over upcoming



2017年9月9日 星期六

使用 docker 安裝及執行 Laravel

因為環境的關係,例如,在 Windows server 2003 下,只能跑 PHP 5.4,就限制了只能使用Laravel 5.0。而要裝 Laravel 5.0,也必需使用 PHP 5.4 ~ 5.6 的版本來安裝。相對的,使用 CentOS,則能使用最新版本的 PHP,相對的,也必須使用較高版本的 Laravel。

可是,自己個人使用的電腦,一定不想要同時安裝各種版本的 PHP,通常也不允許。甚至,像 PHP 5.4,因為官方不再支援,有可能無法安裝。在這種情形下,docker 實在是一個很理想的環境或工具。在這裡,要安裝 Laravel 5.0,選擇使用的 image 是 composer/composer:php5-alpine,它用的是 PHP 5.6,雖然標註為 DEPRECATED,但還是能用的。

我是習慣在一個專用的目錄下,放置和 Laravel 相關的專案,因此,將 composer 的 cache 也放在此目錄下,就可以省下很多等待下載的時間。其中 "-v $(pwd)/cache:/composer" 的選項,就是指定存放 cache 的 volume。

在建立專案時,會在該目錄下建立一個新的目錄,因此用 "-v $(pwd):/app" 來指定 volume。但是 update 時,則需在該專案的目錄下,因此 volume 的指定便成為 "-v $(pwd)/la-50:/app",而不用真的切換目錄。

$ docker run --rm -v $(pwd):/app  -v /cache:/composer composer/composer:php5-alpine create-project laravel/laravel la-50 "5.0.*" --prefer-dist

# 移險 la-50/vendor/compiled.php 後,進行 update
$ cd la-50
$ rm vendor/compiled.php

$ docker run --rm -v $(pwd):/app  -v ~/php-projects/cache:/composer composer/composer:php5-alpine update

接著用 PHP 5.4 來執行測試。注意,這裡使用的 image 已安裝所需的 PHP extension 了。
docker run -it --rm -v $(pwd):/app -p 8000:8000 php54_app php /app/artisan --host=0.0.0.0 serv

然後,使用瀏覽器開啟 http://localhost:8000/ 即可看到結果。













網誌存檔