Joe Horn 的啟示錄
Joe Horn's Blog
  • About.me
  • Facebook
  • Flickr
  • GitHub
  • Instagram
  • LinkedIn
  • Pinterest
  • Slideshare
  • Twitter
  • YouTube
  • Tumblr
RSS
  • All Posts
  • VPS Referrals
  • My Plurk
  • My Plurk Bot

7 月 24 2019

Logstash 筆記

為了分析某些儲存在 MySQL 的 log,敝單位在兩年前(2017)導入 Logstash;當時我們用最新的 5.5.1 版,運作狀況還不錯,所以就沒什麼人理它…
最近冒出問題,救完火後寫個紀錄。

第一個問題是這個:

[WARN ][logstash.inputs.jdbc     ] Exception when executing JDBC query {:exception=>#<Sequel::DatabaseError: Java::ComMysqlJdbcExceptionsJdbc4::MySQLDataException: '2.147483727E9' in column '1' is outside valid range for the datatype INTEGER.>}

資料的第一個欄位是 auto-increment 的 ID,看到 ‘2.147483727E9’ 就聯想到是 32 位元正整數溢位問題。
我們先換 MySQL Connector/J (& 改用 OpenJDK);換完之後,看到的錯誤訊息變成這樣:

[WARN ][logstash.inputs.jdbc     ] Exception when executing JDBC query {:exception=>#<Sequel::DatabaseError: Java::JavaSql::SQLDataException: Value '2147483727' is outside of valid range for type java.lang.Integer>}

於是我們就開始升版 Logstash;目前最新的版本是 7.2.0,但 官方的 migration guide 說要先升版到 6.7。
最後我們順利升上 7.2.0,在過程中也發現 6.7.2 已無 32 位元正整數溢位問題。

第二個問題發生在升版後:
DATETIME 欄位存放的 ‘2019-07-23 14:18:59’ 抓成 ‘2019-07-23T19:18:59.000Z’。
沒人能保證系統/伺服器會跨多少時區,為免夜長夢多,我們的解決方式是轉成 UNIX timestamp。
(Year 2038 problem? 以後再說! XD )

分享此文:

  • Tweet

By Joe Horn • Computer Software 0 • Tags: JDBC, Logstash, MySQL

5 月 30 2019

Toshiba KXG6AZNV512G on Lenovo T590

Toshiba KXG6AZNV512G 是 M.2 2280 規格的 NVMe SSD;官網可以查得 XG6 Series 產品資訊頁。

分享此文:

  • Tweet

By Joe Horn • Computer Hardware 0 • Tags: KXG6AZNV512G, Lenovo, T590, Toshiba

5 月 26 2019

HTTP 壓縮的 workaround : ProgressEvent & Cache-Control

這幾個月前後經手處理兩個 HTTP 壓縮相關的問題,寫個紀錄…

第一個問題跟 ProgressEvent 有關。
敝單位有個 PWA ( Progressive Web Application ),幾個月前釋出一個新模組,讓 user 可獲取公司內部發佈的公告訊息。考量到訊息內容長度與行動裝置所在網路環境,我們便試著在訊息載入時加上進度條 (Progress Bar)。
實作期間,我們發現只能取得 ProgressEvent.loaded,抓不出 ProgressEvent.total,而且這個現象僅發生在 server response,瀏覽器發出請求/上傳檔案無此狀況。
確認這現象跟 HTTP 壓縮有關後,我們也發現 ProgressEvent.loaded 的值是未壓縮前的大小。
目前我們採用的解法是在讀取內容前先發個 HTTP request 取得內容長度,用該值取代 ProgressEvent.total。

第二個問題被發現時,我們正在調整 Cache-Control 設定;而且這問題只跟 Apache HTTPD 有關。
我們讓 HTTP server 壓縮 .js , .css , .htm 這類固定文字檔,也加上這串 HTTP header :

Cache-Control: public, max-age=86400, no-cache

但我們發現瀏覽器在 nginx 可正確獲得 304 Not Modified,但遇上 Apache HTTPD 永遠都是 200 OK。
花一堆時間測試/追蹤後發現兇手是 mod_deflate;原因是檔案被壓縮處理後,傳給瀏覽器的 HTTP ETag 後面被加上 “-gzip” 這串後綴。
目前的解法是參考這篇,用下面這段設定處理 .js , .css , .htm 這類固定文字檔的 Cache-Control:

RequestHeader edit "If-None-Match" "^\"(.*)-gzip\"$" "\"$1\""
Header edit "ETag" "^\"(.*[^g][^z][^i][^p])\"$" "\"$1-gzip\""

Apache HTTPD 2.5 版的 mod_deflate 應該會多個 DeflateAlterETag 供作調整;等吧… XD

分享此文:

  • Tweet

By Joe Horn • WWW 0 • Tags: Apache HTTPD, Cache-Control, HTTP compression, mod_deflate, ProgressEvent

4 月 7 2019

Toshiba KBG30ZMT128G on Lenovo L580

Toshiba KBG30ZMT128G 是 M.2 2242 規格的 NVMe SSD。
在 Google 用這個型號查詢,得到的官網零售產品是 RC100;KBG30ZMT 應該是出貨給廠商裝機用的版本。

分享此文:

  • Tweet

By Joe Horn • Computer Hardware 0 • Tags: KBG30ZMT128G, L580, Lenovo, Toshiba

3 月 16 2018

開始用 Let’s Encrypt 的 wildcard certificate

2016 年自己寫過 改用 Let’s Encrypt 的 certificates,文內提到的 dehydrated 也持續在使用。

這幾天看到 Let’s Encrypt 貼出 ACME v2 and Wildcard Certificate Support is Live。

Let’s Encrypt 的 wildcard certificate 實作大概要注意以下幾點:

  • 要用 ACME v2 compatible client(官方有提供列表: ACME Client Implementations)
  • 不能用 HTTP challenge,改用 DNS challenge

使用 dehydrated 進行 DNS challenge 可以參考這幾份文件:

  • dehydrated / docs / dns-verification.md
  • dehydrated Wiki : Examples for DNS 01 hooks

我選擇用 nsupdate 的方式(參考 dehydrated Wiki : example dns 01 nsupdate script),在 DNS master server 建立 _acme-challenge.{DOMAIN} 的 NS record,讓 hook script 透過 nsupdate 連線到指定的 name server 更新 TXT record 。

DNS 方面完成後,要記得佈署 hook script 與 nsupdate 使用的 key。
接著是調整語法,原本的語法:

/SOMEWHERE/dehydrated/dehydrated -c -d {網站hostname}

改為:

/SOMEWHERE/dehydrated/dehydrated \
    -c -d *.{DOMAIN} \
    -t dns-01 -k {HOOK_SCRIPT} \
    --alias wildcard.{DOMAIN}

( –alias 指定的 wildcard.{DOMAIN} 會成為目錄名稱,用來存放憑證 )

分享此文:

  • Tweet

By Joe Horn • WWW 0 • Tags: certificate, dehydrated, DNS, HTTPS, Let's Encrypt, nsupdate, SSL

12 月 4 2017

PHP 的 MySQL driver/library 與記憶體耗用

再來還些債…

前陣子我們家在看一些 PHP 的版本差異,也順便拆一些地雷。
先說記憶體耗用,我們用下面這段程式在一些 PHP 版本上執行,觀察記憶體耗用:

<?php
$a = memory_get_usage();
echo "begin:\t$a" . PHP_EOL;

$arr = array();
for ( $i = 0; $i < 100000; $i++ ) {
    array_push($arr, $i);
}

$b = memory_get_usage();
echo "end:\t$b" . PHP_EOL;

echo "diff:\t" . ($b - $a) . PHP_EOL;

在 PHP 5.1 ( on 32-bit Linux ) 觀察到的記憶體差距值大約是 5.8 MB,在 PHP 5.3 ~ 5.6 ( on 64-bit Linux ) 觀察到的記憶體差距值大約是 14 MB,而 PHP 7.1 ~ 7.2 ( on 64-bit Linux ) 觀察到的記憶體差距值大約是 4 MB。

至於 PHP 的 MySQL driver/library 方面…
參考官方提供的 Overview of the MySQL PHP drivers : Buffered and Unbuffered queries ;PHP 的所有的 MySQL extensions 預設使用 buffered mode,所以在撈取大量資料時,PHP 執行完 SQL statement 就會耗用大量記憶體。
另外,在官方提供的 Overview of the MySQL PHP drivers : Choosing a library 可以看到,PHP 5.3 以前的預設 MySQL driver ( libmysqlclient ) 沒使用 PHP 的原生記憶體管理,PHP 5.3 之後的預設 MySQL driver ( mysqlnd; MySQL Native Driver) 才開始用。
對這些行為,我們另外生了一段測試程式:

<?php
$a = memory_get_usage();
echo "begin:\t\t$a" . PHP_EOL;

$dbConn = new PDO(.....);
$b = memory_get_usage();
echo "new PdoMySQL:\t$b\t\tDiff: " . ($b - $a) . PHP_EOL;

$st = $dbConn->query("SELECT * FROM testTable LIMIT 30000");

$b = memory_get_usage();
echo "get Stmt:\t$b\tDiff: " . ($b - $a) . PHP_EOL;

$row1 = $st->fetch();

$b = memory_get_usage();
echo "fetch once:\t$b\tDiff: " . ($b - $a) . PHP_EOL;

$row2 = $st->fetch();

$b = memory_get_usage();
echo "fetch twice:\t$b\tDiff: " . ($b - $a) . PHP_EOL;

$st->closeCursor();

$b = memory_get_usage();
echo "closeCursor:\t$b\t\tDiff: " . ($b - $a) . PHP_EOL;

$row3 = $st->fetch();
$b = memory_get_usage();
echo "fetch:\t\t$b\t\tDiff: " . ($b - $a) . PHP_EOL;

var_dump($row3);

在 PHP 7.1 ( with mysqlnd , 64-bit Linux ) 的數據如下:

begin:          355552
new PdoMySQL:   378784          Diff: 23232
get Stmt:       25866944        Diff: 25511392
fetch once:     25868752        Diff: 25513200
fetch twice:    25870568        Diff: 25515016
closeCursor:    384104          Diff: 28552
fetch:          384104          Diff: 28552
bool(false)

在 PHP 5.1 ( with libmysqlclient , 32-bit Linux ) 的數據則是:

begin:          50432
new PdoMySQL:   85752           Diff: 35320
get Stmt:       92184   Diff: 41752
fetch once:     93584   Diff: 43152
fetch twice:    95248   Diff: 44816
closeCursor:    95312           Diff: 44880
fetch:          95400           Diff: 44968
bool(false)

應該有為數不少的 PHP developers 曾經踩過這種記憶體相關的地雷… XD

分享此文:

  • Tweet

By Joe Horn • PHP • Tags: libmysqlclient, memory, MySQL, mysqlnd, PHP

11 月 30 2017

PHPExcel 的活頁簿標題 ( SheetTitle ) 處理

之前曾經使用 PHPExcel 踩到地雷,處理完之後一直忘記載這邊留個紀錄(拖稿?)。

Excel 的活頁簿標題有字元 & 長度限制,但 library ( PHPExcel ) 沒有特別判斷 & 處理,所以…

    // Excel 的活頁簿 title 不允許 * : / \ ? [ ]
    $currTitle = str_replace(
        array('*', ':', '/', '\\', '?', '[', ']'),
        "",
        $currTitle
    );

    // 字數上限 31,保守抓 30
    $maxByte = 90;
    $chars = mb_strlen($currTitle, 'UTF-8');
    while ( $chars > 30 ) {
        $currTitle = mb_strcut($currTitle, 0, $maxByte, 'UTF-8');
        $chars = mb_strlen($currTitle, 'UTF-8');
        $maxByte--;
    }

分享此文:

  • Tweet

By Joe Horn • PHP • Tags: PHP, PHPExcel

2 月 22 2016

改用 Let’s Encrypt 的 certificates

之前都在用 StartSSL 的免費 certificate,雖知道有 Let’s Encrypt,但因手邊幾乎都轉用 nginx,遲遲沒下手。

約莫一週前 zeroplex 丟了這個網頁:「Why I stopped using StartSSL (Hint: it involves a Chinese company)」,三、四天前 DK 大神也撰文提及,就決定趁週末沒什麼事來動工…

用 DK 大神在一個月前撰文提過的 dehydrated 這個 GitHub 專案可以輕鬆搞定,步驟大致如下…

  1. 找個自己喜歡的目錄(不是 /tmp …),把 dehydrated clone 出來
  2. 在 clone 出來的目錄之下建立 .acme-challenges 目錄
    mkdir dehydrated/.acme-challenges
  3. 在原本的 HTTP (80 port) 設定下建立 alias,把網站的 /.well-known/acme-challenge 指向剛建立好的目錄
  4. 讓 HTTP daemon 重讀設定
  5. 執行這個指令
    dehydrated/dehydrated -c -d {網站hostname}
  6. 完成 & 成功後就會在 dehydrated/certs 發現目錄,目錄下有數個檔案
  7. 我自己讓 nginx 使用 fullchain.pem 跟 privkey.pem,設定大致如下:
    server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
    
        ssl on;
        ssl_certificate /SOMEWHERE/dehydrated/certs/{網站hostname}/fullchain.pem;
        ssl_certificate_key /SOMEWHERE/dehydrated/certs/{網站hostname}/privkey.pem;
        ssl_trusted_certificate /SOMEWHERE/dehydrated/certs/{網站hostname}/fullchain.pem;
        ....
    }
    

我記得 Let’s Encrypt 的 certificate 要在 90 天內 renew,所以 cron job 這樣放:

0 0 1 */2 * /SOMEWHERE/dehydrated/letsencrypt.sh -c -d {網站hostname} &gt; /dev/null 2&gt;&amp;1

Updated : letsencrypt.sh 改為 dehydrated 。

分享此文:

  • Tweet

By Joe Horn • WWW • Tags: certificate, dehydrated, HTTPS, Let's Encrypt, letsencrypt.sh, nginx, SSL, StartSSL

12 月 10 2015

網頁相關技術的抉擇

以往的網頁純粹就是 HTML,之後的動態網頁技術 ( CGI、PHP、ASP、JSP、… )、CSS、VBScript、Javascript 雖讓網頁內容/效果愈來愈多元,網頁開發/維護難度的關鍵亦僅取決於語言的熟悉度。

近幾年則是冒出了不少網頁前端 frameworks。 node.js、io.js 與 React、Angular、Backbone、Ember、…,雖說是使用相同的程式語言,但各種 frameworks 的選用與導入著實讓不少網頁前端開發人員頭疼。

考量多螢、多裝置的兼容性, COSCOP 2015 就有人提出 “每18至24個月,前端技術的難度會增加一倍以上”。
但… 真只有網頁前端開發人員的日子愈來愈難熬嗎?
SQL Injection、XSS、CORS 等議題與考量呢?

我個人一直認為程式語言只是工具,沒特別去吹捧某特定程式語言;同理,我也把 frameworks 當作是工具。
我們看到的一些新技術/framework 固然很好,真有立即導入的必要性嗎?
若看到新的技術屏除跟風心態,先稍作觀望,讓環境的變化幫我們除強汰弱,另一方面加強人員的教育訓練,新技術導入前仔細評估,審慎抉擇,是否網頁開發人員就可以不必過得如此辛苦?

分享此文:

  • Tweet

By Joe Horn • Thoughts, WWW • Tags: framework, front-end developer, web, web developer

8 月 25 2015

調整 Apache HTTPD & Apache Tomcat & nginx 的 content cache & compression

前陣子調整了一些 Apache HTTPD & Tomcat & nginx 的 cache 機制與內容壓縮機制,稍微紀錄一下。

Apache HTTPD 的 cache:

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType image/gif "access plus 1 month"
  ExpiresByType image/jpeg "access plus 1 month"
  ExpiresByType image/png "access plus 1 month"
  ExpiresByType text/css "access plus 1 month"
</IfModule>

Apache HTTPD 的壓縮:

<IfModule mod_deflate.c>
  DeflateCompressionLevel 9
  AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php
  AddOutputFilter DEFLATE js css
</IfModule>

Apache Tomcat 的 cache(在 application 的 web.xml 做調整):

  <filter>
    <filter-name>ExpiresFilter</filter-name>
    <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
    <init-param>
      <param-name>ExpiresByType image</param-name>
      <param-value>access plus 1 month</param-value>
    </init-param>
    <init-param>
      <param-name>ExpiresByType text/css</param-name>
      <param-value>access plus 1 month</param-value>
    </init-param>
    <init-param>
      <param-name>ExpiresByType application/javascript</param-name>
      <param-value>access plus 1 month</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>ExpiresFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>

Apache Tomcat 的壓縮(在 conf/server.xml 做調整):

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               compression="on" compressableMimeType="text/html,text/xml,text/plain,text/css,application/javascript"
               redirectPort="8443" />

nginx 的 cache(在 server tag 內做調整):

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires 1M;
}

nginx 的壓縮(在 http tag 內做調整):

gzip_vary on;
gzip_proxied any;
gzip_comp_level 9;
gzip_buffers 8 32k;
gzip_http_version 1.0;
gzip_types text/plain text/css application/json
           application/javascript application/x-javascript text/javascript
           text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;

大概就調這些,其他多媒體檔案就看需求了…

分享此文:

  • Tweet

By Joe Horn • WWW • Tags: Apache HTTPD, Apache Tomcat, cache, compression, deflate, gzip, nginx

‹ 1 2 3 4 ›»

Site Info

本站小貼紙
本站小圖
There are lots of zh_TW words encoded with UTF-8 in this Blog.
創用 CC 授權條款
本站所有內容係採用創用 CC Attribution-NonCommercial-NoDerivatives 4.0 國際 授權條款授權.

About me

profile for Joe Horn at Stack Overflow, Q&A for professional and enthusiast programmers

My mail!

獅子座

Coffee Powered!

F1 fans

motoGP fans

Linkin Park

I am a Taiwanese!

Recent Comments

  • Avatar of johnpupu johnpupu: PHP 還有這個 phpsavant.c……
  • Avatar of Jerry Jerry: 这个不是foreach的问题。 0 ==……
  • Avatar of Joe Horn Joe Horn: 看來問題在 if ... else ..……
  • Avatar of jnlin jnlin: 因為 'b' 被轉型成 0 了…
  • Avatar of 路人 路人: 跟 foreach 沒有關係 ?…
  • Avatar of bill bill: 註冊表那裡要設定 BasicAuthLe……
  • Avatar of 虫 虫: .svn 的檔案減少可以增加在 wind……
  • Avatar of mars mars: 如果說寫程式是理性極致的話,那寫小說就是……
  • Avatar of Joe Horn Joe Horn: 已更新文章。…
  • Avatar of jackcal jackcal: joehorn.idv.tw關於轉貼 h……

Post Categories

  • About My Sites (16)
  • Computer Hardware (24)
  • Computer Software (45)
  • Database (20)
  • FreeBSD (21)
  • Funny (14)
  • Life (23)
  • Linux (4)
  • Mail (19)
  • Network (11)
  • Programing (40)
    • .NET (5)
    • JAVA (2)
    • Javascript (6)
    • PHP (29)
  • Thoughts (34)
  • Windows (13)
  • WWW (78)
    • phpBB (7)
    • WordPress (18)

Blogroll

  • ziway 的 Blog
  • 小麻的 Blog
  • RB susu 的 Blog
  • 這裡沒有美食
  • 小恬的 Blog
  • 哈寶的 Blog
  • ケロン軍團戰略室 (INGRESS)
  • DK Moto Club
  • 日落的 Blog
  • Huckly 的 Blog

Tags Cloud

AMD Apache Bloglines C# Coppermine DNSBL domain name eAccelerator extension Firefox Formula 1 free FreeBSD Gmail Google HDD Hsin-chu IE Intel Javascript Lenovo Longhorn Microsoft MSN MySQL Office PCHome performance PHP phpBB pirate Postfix restaurant RSS sendmail software SpamAssassin Subversion SVN Taiwan theme translation Windows WordPress Yahoo

Ads

↑

© Joe Horn 的啟示錄 2021
Powered by WordPress • Themify WordPress Themes