2026/10/26

魔獸爭霸3

《魔獸爭霸III:混亂之治》(Warcraft III: Reign of Chaos)是暴雪娛樂出品的即時戰略遊戲,於 2002 年發行。 2003 年 5 月暴雪公司又發行了《魔獸爭霸III:寒冰霸權》(Warcraft III: The Frozen Throne),它是本作的資料片。 《魔獸爭霸III》在 1.21b 移除了光碟檢查機制,1.27b 則是其最後一版能夠線下更新的版本, 在 1.28 之後因為機制改變的關係,只能夠線上更新。

如果使用 WINE 執行,在 1.29 版以前可以嘗試加上 -opengl 選項。因為只是用來懷舊,所以我並沒有持續更新版本, 而是停留在 1.27b 版。

可以參考的資料:

玩家可以選擇在《魔獸爭霸III》中操控四個種族,分別是 Human, Orc, Undead 與 Night Elf。Naga 在製作時曾經設想作為第五個可操控的種族,但在遊戲測試時刪去。而官方解釋是:加上 Naga 族之後很難保證遊戲的平衡性,因為那迦族的部隊可直接跨過水域。而今它則出現在戰役模式和中立生物當中。

  • Human
    • Well-rounded units
    • Buildings can be built anywhere
    • Peasants can become Militia at the main Town Hall
    • Multiple workers can be used to construct buildings faster
  • Orc
    • Very beefy and expensive units
    • Burrows coupled with Peons are used as a defense
    • Orc peons are immune while constructing buildings
    • Several orc units can be upgraded to salvage gold and lumber when attacking enemy buildings
  • Night Elf
    • Several buildings (called "Ancients") can uproot to move and attack land units
    • Night elf units have improved vision during nighttime after researching Ultravision
    • Wisps are immune while harvesting gold and can harvest lumber anywhere without needing to return their resources
    • Wisps sacrifice themselves when building Ancients
  • Undead
    • Can use corpses as a resource
    • Buildings must be built upon Blight
    • Acolytes only need to begin a building's summoning
    • Acolytes can harvest gold at Haunted Gold Mines without returning their resources

《魔獸爭霸III:混亂之治》的人口限制為 90,資料片則增加到 100。 《魔獸爭霸III》使玩家集中注意力於「控制戰鬥單位」而非「生產戰鬥單位」,因此遊戲要求玩家關注於小規模的戰鬥而非宏觀的調兵。 遊戲增加了可透過獲取經驗值升級並增強能力的超級戰鬥單位,也就是英雄,而英雄又可以分為本族英雄和中立英雄。 每當己方殺滅一個敵方單位或中立生物時 (creeping),英雄便可獲取相當的經驗值而累積一定程度時其等級就會上升。 等級每當上升時,英雄便可通過添加技能點學習或加強一項技能。 除此以外,英雄們亦可以攜帶於商店購得或戰勝中立生物後獲取之物品,而此等物品則可提高英雄或整體的作戰能力。

中立生物可視為遊戲中創新之處。即便多人遊戲中,亦存有完全由電腦控制的中立生物,以守衛地圖中關鍵的位置及中立的建築物。 它也成為選手間爭奪的資源,擊殺中立生物後便可獲得相當的經驗值、金錢及物品。

《魔獸爭霸III》採用三級科技樹,需要採集的資源為 Gold 與 Lumber,Gold 的採集人數固定為 5 人。 而另一影響遊戲策略的操施就是維護費徵取 (upkeep),此操施源於一種概念——擁有越多戰鬥單位就須要付出越多的資源去滿足部隊的需要, 如士兵需要補給、武器需要打造、盔甲需要鍛鍊等。該遊戲則以上稅實行此概念。當玩家部隊的數目到達一定程度時,就須於每採集十塊黃金上繳其中三塊。 當部隊數目抵達更高程度時,每十塊就須上繳六塊。

Human 的工人 Peasant,Orc 的工人 Peon,Night Elf 的工人 Wisp 負責採集 Gold 與 Lumber。 Undead 略有不同,工人 Acolyte 只負責採集 Gold,初級攻擊單位 Ghoul 同時也兼具採集 Lumber 的工作。

Human 在第一級的初級攻擊單位為生產自 Barracks 的 Footman 與 Rifleman(在建造 Blacksmith 後解鎖); Orc 在第一級的初級攻擊單位為生產自 Barracks 的 Grunt 與 Troll Headhunter(在建造 War Mill 後解鎖); Undead 在第一級的初級攻擊單位為生產自 Crypt 的 Ghoul 與 Crypt Fiend(在建造 Graveyard 後解鎖); Night Elf 在第一級的初級攻擊單位為生產自 Ancient of War 的 Archer 與 Huntress(在建造 Hunter's Hall 後解鎖)。 Night Elf 比較特別的地方是,一開始的初級攻擊單位是遠程攻擊的弓箭手 Archer,而攻城單位 Glaive Thrower 也是第一級主堡就可以生產。

Human 在第二級的生產建築為 Arcane Sanctum 與 Workshop, 法師 Priest, Sorceress 與資料片新增的反魔單位 Spell Breaker 生產自 Arcane Sanctum, Priest 具有 Heal 技能,Sorceress 具有 Slow 技能,Spell Breaker 具有 Spell Steal 技能以及被動的 Spell Immunity 能力, Flying Machine 與 Mortar Team 則生產自 Workshop。 因為 1.10 的變更,資料片新增的單位 Dragonhawk Rider 在第二級主堡就可以生產,也因此 Gryphon Aviary 在第二級主堡就可以建造;
Orc 在第二級的生產建築為 Spirit Lodge 與 Beastiary, 法師 Shaman 與 Witch Doctor 生產自 Spirit Lodge, Raider, Wind Rider, Kodo Beast, Troll Batrider 生產自 Beastiary,Raider 是個很有用的單位, 攻擊型態與攻城車相同(對於建築有攻擊加成),Ensnare 能力可以網住空軍單位、讓敵人無法移動以及中斷施法, Kodo Beast 的能力 Devour 可以吞食一些對手的陸軍單位並且緩慢的傷害,War Drums Aura 則可以增加攻擊。 注意在 1.30.0 將 Spirit Walker 從 Spirit Lodge 改為從 Tauren Totem 生產, Tauren Totem 也變成在第二級主堡就可以建造;
Undead 在第二級的生產建築為 Temple of the Damned 與 Slaughterhouse, 法師 Necromancer 與 Banshee 生產自 Temple of the Damned, Necromancer 的技能 Raise Dead 可以自屍體產生 Skeleton Warrior/Skeletal Mage, 攻城單位 Meat Wagon 生產自 Slaughterhouse, 反魔單位 Destroyer 則是從 Slaughterhouse 生產的 Obsidian Statue 變身產生, Destroyer 具有被動的 Spell Immunity 能力;
Night Elf 在第二級的生產建築為 Ancient of Lore 與 Ancient of Wind。 Druid of the Claw(生產自 Ancient of Lore)與 Druid of the Talon(生產自 Ancient of Wind)為 Night Elf 的法師, 二者都有變身的能力,Druid of the Claw 可以變身為 bear,Druid of the Talon 可以變身為 Crow。 而 Dryad 是 Night Elf 的反魔單位,擁有被動的 Spell Immunity 能力, Faerie Dragon 則是資料片新增、用來傷害法師的飛行單位。

有些法術的施法類型為 Channel(例如 Priestess of the Moon 的 Starfall 法術), Channel 施法類型的技能要求單位在法術生效期間保持不動。 在過程中如果因為使用者執行其他的動作或者因敵方的打斷,法術效果就會被取消,並且法術隨之結束。 中斷的技能例如英雄單位 Mountain King 的 Storm Bolt 技能,Sorceress 的 Polymorph 法術, 英雄單位 Tauren Chieftain 的 War Stomp 技能,英雄單位 Shadow Hunter 的 Hex 技能,Raider 的 Ensnare 技能, 英雄單位 Keeper of the Grove 的 Entangling Roots 技能,Druid of the Talon 的 Cyclone 法術, 英雄單位 Crypt Lord 的 Impale 技能以及英雄單位 Dreadlord 的 Sleep 技能。

一些法術可以讓使用者設定自動施法(Autocast),允許單位在符合條件時自動釋放特定的技能,而不需手動點擊。 例如 Priest 的 Heal 與 Inner Fire 技能,Sorceress 的 Slow 技能,Shaman 的 Bloodlust 技能。 有些技能則可以對召喚生物造成傷害,例如 Priest 的 Dispel Magic 造成範圍內召喚生物 200 點傷害, Shaman 的 Purge 造成單體的召喚生物 400 點傷害,Spirit Walker 的 Disenchant 造成範圍內召喚生物 250 點傷害, Dryad 的 Abolish Magic 造成範圍內召喚生物 250 點傷害, Destroyer 的 Devour Magic 造成範圍內召喚生物 180 點傷害(在 1.30.0 降為 160)。

遊戲有靈氣 (Aura) 的設計,包含英雄單位 Paladin 的 Devotion Aura,Archmag 的 Brilliance Aura, Death Knight 的 Unholy Aura,Dreadlord 的 Vampiric Aura, Keeper of the Grove 的 Thorns Aura,Priestess of the Moon 的 Trueshot Aura, Tauren Chieftain 的 Endurance Aura,以及非英雄單位 Kodo Beast 的 War Drums Aura。 另外,也有道具可以提供靈氣的能力

Human 的終極兵種為飛行單位、可對空對地的 Gryphon Rider; Orc 的終極兵種為陸軍單位 Tauren(在資料片可以與 Spirit Walker 的法術 Ancestral Spirit 配合); Undead 的終極兵種為飛行單位、可對空對地的 Frost Wyrm;Night Elf 的終極兵種為飛行單位、但是只能對地 Chimaera。 Orc 的終極兵種為陸軍單位,又只有 Orc 沒有 Spell Immunity 的反魔單位, 雖然 Spirit Walker 在 1.19 加入了被動的 Resistant Skin 能力,但是只能免疫一部份的法術, 因此 Orc 在反魔以及對空上比起其它三族是較為弱勢的。

Human 增加人口的建築為主堡 Town Hall 與 Farm (+6),英雄生產的建築為 Altar of Kings, 資料片新增加的商店建築為 Arcane Vault。Human 需要先建立 Scout Tower(沒有攻擊能力), 需要升級為 Guard Tower, Arcane Tower 或者是 Cannon Tower。
Orc 增加人口的建築為主堡 Great Hall 與 Orc Burrow (+10),英雄生產的建築為 Altar of Storms, 資料片新增加的商店建築為 Voodoo Lounge。Peon 可以躲在 Orc Burrow 中進行防禦, Grunt 與 Raider 可以在研發 Pillage 之後,在攻擊的時候掠奪資源。
Night Elf 增加人口的建築為主堡 Tree of Life 與 Moon Well (+10),英雄生產的建築為 Altar of Elders, 資料片新增加的商店建築為 Ancient of Wonders。Moon Well 具有恢復友方 life 與 mana 的能力。
Undead 增加人口的建築為主堡 Necropolis 與 Ziggurat (+10),英雄生產的建築為 Altar of Darkness, 資料片新增加的商店建築為 Tomb of Relics。Undead 的建築除了主堡以及用來讓 Acolyte 收集 Gold 的 Haunted Gold Mine, 都需要建在 Blight 上才行。Ziggurat 可以升級為有攻擊力的 Nerubian Tower 或者是 Spirit Tower, 而 Undead 的主堡在升為第二級之後就具有攻擊能力。

英雄有 Strength, Agility, Intelligence 三種屬性,並且以其中一個為主要屬性。 在《魔獸爭霸III:混亂之治》中四個種族都有三名英雄,資料片又各增加了一名英雄,以及加入中立英雄的設計。

Faction Heroes
Human Alliance Paladin, Archmage, Mountain King, Blood Mage
Orcish Horde Blademaster, Far Seer, Tauren Chieftain, Shadow Hunter
Undead Scourge Death Knight, Lich, Dreadlord, Crypt Lord
Night Elf Sentinels Keeper of the Grove, Priestess of the Moon, Demon Hunter, Warden
Neutral Naga Sea Witch, Dark Ranger, Pandaren Brewmaster, Beastmaster, Pit Lord, Tinker, Firelord

中立英雄在 Tavern 中雇用。

2026/10/09

IceWM Window Manager

IceWM 是一個專為 X Window System 設計的視窗管理員, 由 Marko Maček 於 1997 年開始開發。 IceWM 是個十分輕量的視窗管理員,通常一些設定需要自行修改文字設定檔才行。 要考量的是 IceWM 只是一個視窗管理員,而不是一個桌面環境, 因此缺少檔案管理員 (File Manager) 等內建程式, 需要安裝某個桌面環境提供的程式或者是外部的應用程式。應該也有為了能夠在老舊硬體也能夠執行良好, 使用 IceWM 作為核心,組合其它的應用程式加上自己的設定以後的 Linux Distribution。 因為 Gnome 與 KDE 都相繼轉向 Wayland-only 的環境,但是我仍然需要一個 X Window System 的環境, 所以開始嘗試使用 IceWM。

在安裝完成之後,建立 ~/.config/icewm 目錄(openSUSE 可以使用此目錄進行設定), 再複製下列的設定檔:

cp -a /usr/share/icewm/{prefoverride,toolbar,menu} ~/.config/icewm/

檔案 prefoverride 可以作為主設定檔(包含 theme 設定的項目可以在這裡再設定一次覆蓋掉); 工具列設定在 toolbar;主選單在 menu。

IceWM 支援 theme,在 ~/.config/icewm 下建立 theme 檔案, OpenSUSE 內建的 theme 在 /usr/share/icewm/themes,設定的方式如下:

Theme="win95/default.theme"

下面是我工具列 toolbar 的設定:

prog "xterm" utilities-terminal xterm
prog "Firefox" firefox firefox file:///home/danilo/public_html/index.html
prog PCManFM-Qt pcmanfm-qt pcmanfm-qt

(在 prog 後面的項目是:程式名稱 程式圖示 程式執行路徑與參數,menu 與 toolbar prog 的設定語法相同)

下面是我主選單 menu 的設定:

prog XTerm utilities-terminal xterm
prog PCManFM-Qt pcmanfm-qt pcmanfm-qt
menu Favorites folder {
    prog Firefox firefox firefox
    prog Thunderbird thunderbird thunderbird
    prog LibreOffice libreoffice-main libreoffice
    prog "SciTE Editor" Sci48M SciTE
    prog QPdfView qpdfview qpdfview
    prog Nomacs org.nomacs.ImageLounge nomacs
    prog DeaDBeeF deadbeef deadbeef
    prog "VLC Player" vlc vlc
    prog "Volume Control"  multimedia-volume-control pavucontrol-qt
}
includeprog icewm-menu-fdo --seps -d1400 -D1650 -S --limit-max-len=42
#menufile Programs folder programs
menufile Tool_bar folder toolbar
menuprog SUSE folder xdg_menu --format icewm

icewm-menu-fdo 指令可以從系統資料自動產生選單與子選單。 IceWM 有個很有趣的功能, 可以使用 icesh 這個命令列工具組合選取條件、過濾器與動作來控制視窗屬性或 IceWM 本身。 因此我們可以使用 icesh restart 重新啟動 IceWM, 觀察是否有正確修改 theme 或者是選單。


我修改的主要設定檔 prefoverride 設定項目為:

#  Command to lock display/screensaver.
LockCommand="xautolock -locknow"

#  Opaque window move.
OpaqueMove=0 # 0/1

#  Opaque window resize.
OpaqueResize=0 # 0/1

#  Favour Xft fonts over core X11 fonts where possible.
PreferFreetypeFonts=1 # 0/1

#  Enable Alt+Tab window switching.
QuickSwitch=1 # 0/1

#  Show mailbox status on task bar.
TaskBarShowMailboxStatus=0 # 0/1

#  Show 'show desktop' button on taskbar (value of 2 to put after the clock)
TaskBarShowShowDesktopButton=2 # [0-2]

#  Desktop background color(s), comma separated.
DesktopBackgroundColor=""

#  Desktop background image(s), comma separated.
# DesktopBackgroundImage=""
DesktopBackgroundImage="/home/danilo/Pictures/orange-cat.jpg"

在 prefoverride 設定完桌面的背景桌布以後,可以使用 icewmbg -r 重新載入觀察結果。

PulseAudio and PipeWire

二者我都有用過,都工作的很好。

PipeWire 是目前 openSUSE Tumbleweed 的預設值 (在 20220708 之後,不過如果是從 openSUSE Leap 升上來的,如果使用者沒有手動變更,便用的仍然是 PulseAudio)。 PulseAudio 的問題在於其設計者腦子裡並沒有考慮軟體相容性, 在當時已經有延屬較低而且被不少專業音訊軟體採用的 JACK 存在, 但是其設計者卻完全不考慮軟體相容性並且與 JACK 並不相容,而 Redhat 也不管軟體相容問題直接力推 PulseAudio, 造成一些軟體相容性的問題。 就我來說,建議使用 PipeWire,PipeWire 優越的地方就是提供了 PulseAudio 與 JACK 相容的軟體介面,但是延遲比 PulseAudio 較低且通常使用的資源比較少。

下面是安裝 PipeWire 的指令:

sudo zypper in pipewire-pulseaudio pipewire-alsa

要注意 PipeWire 與 PulseAudio 無法共存,所以要選擇 deinstallation PulseAudio 的套件。


因為 IceWM 本身不包含音訊管理功能,需要在啟動時設定自動執行 PipeWire 服務。 不過好像不設定也可以,在我設定之前,音訊功能似乎也可以正常工作。 IceWM 的自動啟動檔案為 ~/.config/icewm/startup (記得使用 chmod +x startup 設定檔案屬性為可執行)。 使用 systemd 的系統,startup 檔案內容如下:

# Pass environment variables to systemd --user session
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
    dbus-update-activation-environment --systemd --all
fi

# For PireWire (systemd)
systemctl --user start pipewire pipewire-pulse wireplumber

如果使用非 systemd 系統,則改為如下:

#!/bin/bash

pipewire &
pipewire-pulse &
wireplumber &

檢查是否設定成功:

pactl info

如果輸出結果中的 Server Name 顯示為 PulseAudio (on PipeWire x.y.z), 就代表設定成功。

如果想要設定音量,可以安裝 pavucontrol-qt (適合 PulseAudio 以及有安裝 PulseAudio 相容軟體層的 PipeWire 使用)。

NetworkManager

接下來加入網路設定的部份。如果使用 NetworkManager 設定網路,可以安裝 NetworkManager-applet 來更方便的設定網路。 修改 startup 檔案:

#!/bin/bash

# start network manager
sleep 1 && nm-applet &

# allow notifications
/usr/libexec/notification-daemon &

# Pass environment variables to systemd --user session
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
    dbus-update-activation-environment --systemd --all
fi

# For PipeWire
systemctl --user start pipewire pipewire-pulse wireplumber

Lock screen

接下來設定螢幕鎖定功能。 這裡使用 xautolock 與 xscreensaver 結合使用的方式,因此需要二個套件都有安裝。

修改主要設定檔 prefoverride,設定 LockCommand:

#  Command to lock display/screensaver.
LockCommand="xautolock -locknow"

修改 startup 檔案:

#!/bin/bash

# pcmanfm-qt desktop icon manager
#pcmanfm-qt --desktop &

# start network manager
sleep 1 && nm-applet &

# enable screensaver
xscreensaver -nosplash &

# allow notifications
/usr/libexec/notification-daemon &

# enable lockscreen
xautolock -detectsleep -time 10 -locker "xscreensaver-command -lock" &

# Pass environment variables to systemd --user session
if command -v dbus-update-activation-environment >/dev/null 2>&1; then
    dbus-update-activation-environment --systemd --all
fi

# For PireWire
systemctl --user start pipewire pipewire-pulse wireplumber

xautolock 的 -time 用來設定時間,這裡的 10 就是 10 分鐘; -locker 用來呼叫執行螢幕鎖定功能的程式。 在使用 xautolock 控制 xscreensaver 時,需要調整 xscreensaver 本身的設定, 避免二個套件在螢幕鎖定時間的衝突, 執行 xscreensaver-demo(xscreensaver 的設定界面),取消勾選 Lock Screen After。

Theme (Gtk/Qt)

下面嘗試設定 Gtk 以及 Qt 的 theme 設定,讓使用 Gtk 以及 Qt 撰寫的程式看起來比較美觀; 以及 LibreOffice 的相關設定。設定方式為在 ~/.config/icewm/env 這個檔案設定環境變數:

GTK_THEME="Adwaita"
#GTK_THEME="Adwaita:dark"
QT_QPA_PLATFORMTHEME="qt6ct"
SAL_USE_VCLPLUGIN="qt6"

原本我 QT_QPA_PLATFORMTHEME 嘗試使用 platform theme 並且設為 gtk3, 但是在使用中發現這並不是正確的設法,還是需要使用 qt6ct 處理 Qt6 在非 Qt 開發的環境下的視覺設定, 不過也一樣需要設定 QT_QPA_PLATFORMTHEME 為正確的值 (qt6ct) 才行。

xdg-desktop-portal

我發現 xdg-desktop-portal service 並沒有正確啟動(有安裝 xdg-desktop-portal-gtk 但是沒有啟動成功), 而原因是 graphical-session.target 沒有正確啟動服務。 嘗試採用 workaround 避開這個問題, 修改 /usr/lib/systemd/user/xdg-desktop-portal.service:

[Unit]
Description=Portal service
#PartOf=graphical-session.target
#Requisite=graphical-session.target
#After=graphical-session.target

[Service]
Type=dbus
BusName=org.freedesktop.portal.Desktop
ExecStart=/usr/libexec/xdg-desktop-portal
Slice=session.slice

使用下列的指令檢查目前的服務狀態:

systemctl --user status xdg-desktop-portal.service

PCManFM-Qt

PCManFM-Qt 是一個輕量的檔案管理以及桌面管理程式。 檔案管理方面有二個地方要設定,Edit > Preference > Advanced, 選擇要使用的 Terminal emulator 以及 Archiver integration(如果沒有安裝其它桌面環境的 archive manager, 可以安裝同樣是 LXQt 桌面環境組件的 lxqt-archiver 並且設定使用)。

IceWM 使用 icewmbg 處理桌面上的桌布。如果要讓 pcmanfm-qt 處理, 那麼要在 prefoverride 將 DesktopBackgroundImage 與 DesktopBackgroundColor 都設為空白, 並且在 startup 設定啟動 pcmanfm-qt desktop manager。加入下面的設定內容:

#!/bin/bash

# pcmanfm-qt desktop icon manager
pcmanfm-qt --desktop &

在 pcmanfm-qt 管理桌面以後,按右鍵選擇 Desktop Preferences 就可以設定桌面選項 (我使用的版本行為是這樣)。 但是有個麻煩的地方是 desktop icon 不管什麼桌面環境都會放在家目錄下的 Desktop 目錄, 所以彼此可能會發生衝突。在考慮以後,我決定使用 IceWM 原來的 icewmbg 管理桌布, 而不使用 pcmanfm-qt(在 startup 關於 pcmanfm-qt 的設定需要移除或者是註解掉)。

XTerm

X Window 內建的終端模擬器為 XTerm,其設定檔可以使用家目錄下的 .Xresources。

! Set font and anti-aliasing
xterm*faceName: Monospace
XTerm*faceSize: 16

! Enable a scrollbar on the right side
XTerm*scrollBar: true
XTerm*rightScrollBar: true

! Configuring the maximized window size
XTerm*maximized: true

! Set color scheme (Black background, white text)
XTerm*vt100.background: black
XTerm*vt100.foreground: white

! Display Scrollbar
XTerm.vt100.scrollBar: true
XTerm.vt100.scrollbar.width: 8

! Increase history scrollback buffer
XTerm*saveLines: 4096

! Selections are available via the standard clipboard
XTerm*selectToClipboard: false

! Fix backspace behavior
XTerm*vt100.backarrowKey: false

! Custom Key Bindings for copy and paste
XTerm*vt100*translations:      #override \n\
Shift <Key>Insert:  insert-selection(CLIPBOARD) \n\
Ctrl <Key>Insert:   copy-selection(CLIPBOARD) \n\
Ctrl Shift <Key>C:  copy-selection(CLIPBOARD) \n\
Ctrl Shift <Key>V:  insert-selection(CLIPBOARD)

(原本我將 XTerm*selectToClipboard 設為 true,這樣只要選取文字就會自動複製到 clipboard。 不過後來我決定採取更手動的方式,所以使用 custom key bindings 的方式,設定 Ctrl+Insert 用來複製文字; 並且加入 Shfit+Ctrl+C 與 Shfit+Ctrl+V 這組按鍵。)

如果要立即生效,使用下列的指令:

xrdb -merge ~/.Xresources

XTerm 讀取環境變數 SHELL 作為執行命令時的命令列介面程式,如果需要使用指定的 SHELL, 可以設定環境變數 SHELL 以後再執行 xterm:

SHELL=/usr/bin/tcsh xterm

Mozilla Firefox

Firefox 支援佈景主題 (Themes) 與內建 PDF.js。下面是我目前有在使用的套件:

  • uBlock Origin: 高效率的廣告攔截工具
  • Decentraleyes: 用於保護使用者免遭集中的內容交付網路(CDN)的跟蹤
  • Privacy Badger: 用於阻止那些不遵守 DNT 協定的廣告商跟蹤行為
  • Flagfox: 以旗幟圖示顯示出目前網頁伺服器實際位置的擴充套件
  • Livemarks: Get auto-updated RSS feed bookmark folders

Thunderbird

下面是 gmail 的設定資料,Thunderbird 本身已經有設定資料,只是用來檢查設定是否正確。

內送郵件伺服器 (IMAP)

  • 伺服器名稱 (Host):imap.gmail.com
  • 通訊埠 (Port):993
  • 安全性加密類型:SSL 或 TLS
  • 使用者名稱 (Username):Gmail 電子郵件地址
  • 密碼 (Password):Gmail 密碼或應用程式密碼(若已開啟兩步驟驗證)

外寄郵件伺服器 (SMTP)

  • 伺服器名稱 (Host):smtp.gmail.com
  • 通訊埠 (Port):465(搭配 SSL)
  • 安全性加密類型:TLS 或 SSL
  • 需要驗證:勾選「我的外寄伺服器 (SMTP) 需要驗證」(設定與內送相同)

從 2025 年開始,Google 帳戶已全面不支援僅用「使用者名稱與密碼」登入的低安全性第三方應用程式, 第三方郵件端需改用 OAuth 2.0 或「應用程式密碼」來進行身分驗證。

下面是 Account Settings 要注意的部份。
在 Server Settings 中,不要勾選 Clean up ("Expunge") Inbox on Exit 與 Empty Trash on Exit。
在 Copies & Folders 中,不要勾選 Place a copy in 選項, 在 Drafts and Templates 的 Keep message drafts in: 選項中,選擇 Other, Drafts on [Your Gmail address]。
在 Spam Settings,不要勾選 Enable adaptive junk mail controls for this account。


下面是 hotmail 的設定資料,Thunderbird 本身已經有設定資料,只是用來檢查設定是否正確。

內送郵件伺服器 (IMAP)

  • 伺服器名稱 (Host):outlook.office365.com
  • 通訊埠 (Port):993
  • 加密方法:SSL / TLS
  • 使用者名稱 (Username):Hotmail 電子郵件地址
  • 密碼 (Password):Hotmail 密碼或應用程式密碼(若已開啟兩步驟驗證)

外寄郵件伺服器 (SMTP)

  • 伺服器名稱 (Host):smtp-mail.outlook.com
  • 通訊埠 (Port):587
  • 加密方法:STARTTLS
  • 驗證方式:OAuth2

注意需要啟用 IMAP 功能:登入 Outlook 網頁版,前往 設定 > 郵件 > 轉寄和 IMAP,確認已勾選 開啟 IMAP 並儲存。

下面是 Account Settings 要注意的部份。
在 Copies & Folders 中,在 Place a copy in 選項 選擇 Other 選項。

SciTE

選單 Options > Open User Options File, 然後加入要設定的選項(可以先複製 global options 的內容到此處再設定)。 User Option file 檔案為家目錄下的 .SciTEUser.properties。 下面只是目前修改的結果,主要修改使用者介面、code page 以及字型設定。

# Window sizes and visibility
position.maximize=1
#position.tile=1
#full.screen.hides.menu=1
#minimize.to.tray=1
#icon.busy=1
split.vertical=0
#split.wide=1
#output.horizontal.size=200
#output.vertical.size=60
#output.initial.hide=1
#horizontal.scrollbar=0
#horizontal.scroll.width=10000
#horizontal.scroll.width.tracking=0
#output.horizontal.scrollbar=0
#output.horizontal.scroll.width=10000
#output.horizontal.scroll.width.tracking=0
#output.scroll=0
#error.select.line=1
#end.at.last.line=0
tabbar.visible=1
#tabbar.hide.one=1
#tabbar.hide.index=1
#tabbar.multiline=1
toolbar.visible=1
#toolbar.usestockicons=1
#toolbar.large=1
#menubar.detachable=1
#undo.redo.lazy=1
undo.selection.history=1
statusbar.visible=1

# Sizes and visibility in edit pane
line.margin.visible=1
line.margin.width=2+

view.whitespace=1

check.if.already.open=1
#temp.files.sync.load=1
default.file.ext=.txt
#source.default.extensions=.h|.cxx|.bat
title.full.path=1
open.dialog.in.file.directory=1
save.check.modified.time=1

# Indentation
tabsize=4
indent.size=4
use.tabs=1

# Wrapping of long lines
wrap=1
wrap.style=2

# Behaviour
#eol.mode=LF
eol.auto=1
clear.before.execute=1

# Unicode
code.page=65001
output.code.page=65001

# Give symbolic names to the set of fonts used in the standard styles.
font.base=$(font.monospace)
font.small=font:Noto Sans Mono CJK TC, size:10
font.comment=$(font.monospace)
font.code.comment.box=$(font.monospace)
font.code.comment.line=$(font.monospace)
font.code.comment.doc=$(font.monospace)
font.code.comment.nested=$(font.monospace)
font.text=$(font.monospace)
font.text.comment=$(font.monospace)
font.embedded.base=$(font.monospace)
font.embedded.comment=$(font.monospace)
font.monospace=font:Noto Sans Mono CJK TC, size:12
font.monospace.small=font:Noto Sans Mono CJK TC, size:10
font.vbs=$(font.monospace)

Tips

OpenGL Software render

如果因為 OpenGL 版本的關係, 需要使用 Mesa 的 OpenGL Software render 實作(或者是因為應用程式所使用的 OpenGL 版本的關係),使用下列的環境變數設定:

export __GLX_VENDOR_LIBRARY_NAME=mesa
export LIBGL_ALWAYS_SOFTWARE=1 

加入字型

英文字體分類通常可以分為三類:Serif(襯線體)、Sans-serif(無襯線體)與 Monospace(等寬字體)。 而中文最常用的明體(與宋體)、黑體、仿宋、楷體這四大經典印刷字體,黑體是無襯線體字型, 明體(與宋體) 則是襯線體字型。

因為漢字文字眾多,所以會有缺字的問題, Google Noto 字型已經讓自由軟體環境缺字的情況大幅度減少,已可以滿足大多數的使用情境。 如果要在 openSUSE 使用 zypper 安裝 Google Noto 字型繁體中文的部份:

sudo zypper in google-noto-sans-tc-fonts google-noto-sans-tc-mono-fonts google-noto-serif-tc-fonts

目前就我所知,支援到 Unicode 17.0 全部漢字的字型為 Jigmo(字雲)。 在 Linux 將字型加入個人使用環境的方式如下:

  • 首先把字型複製到 ~/.local/share/fonts/ 目錄下面
  • 執行 fc-cache -v -f

而後使用 fc-list 配合 grep 觀察是否有成功安裝。

Clear the GTK/FreeDesktop History File

使用下列的指令:

rm -f ~/.local/share/recently-used.xbel
touch ~/.local/share/recently-used.xbel

2026/07/28

龍芯

我發覺對中國的事物是真的無知,至少我讀了龙芯,正式进入 PostgreSQL 官方仓库以後,才想要查詢一下目前龍芯的進展。

來自 Google 以後的資訊:
龍芯是由中國科學院計算技術研究所及龍芯中科等機構設計的一系列中國國產通用中央處理器與晶片,核心產品涵蓋龍芯1號(嵌入式)、龍芯2號(工控)與龍芯3號(桌面及伺服器),採用完全自主的「龍架構」(LoongArch)指令集。

雖然說龍芯大致對標國際主流水準,不過實際上仍然是落後的(我知道有些人應該會嘲笑這點,我是覺得大可不必),只是有幾件事值得注意:

  • 龍芯是否可以持續研發
  • 龍芯是否可以由中國國內廠商完全國產(雖然可以找其它地方的代工廠,但是為了避免在極端情況下的問題,中國國內廠商需要有能力可以自行生產)

如果答案都是「是」,那麼目前大致對標國際主流水準而有一些地方落後是可以接受的,只要能夠持續進步,同時中國國內廠商(也就是晶圓代工廠們)可以繼續推進其製程反過來促進龍芯的進步,而龍芯可以切入工控電腦等領域並且有效取代,我是覺得就沒有問題。

另外,龍芯要注意的就是其軟體生態圈是否可以建立,如果可以(最少中國有人使用),或許也是一條中國值得走的路。

2026/07/15

Apache CouchDB

Apache CouchDB 是一個開源資料庫,主要功能使用 Erlang 撰寫。 專注於易用性和成為"完全擁抱web的資料庫"。 它是一個使用 JSON 作為儲存格式,JavaScript 作為查詢語言,MapReduce 和 HTTP 作為 API 的文件導向 NoSQL 資料庫。 其中一個顯著的功能就是多主複製。Apache CouchDB 在 CAP Theorem 中屬於 Eventual Consistency 類型。

使用從 source code 編譯,下面是設定的指令(如果 JavaScript engine 想要使用 QuickJS):

./configure --spidermonkey-version 115 --js-engine=quickjs --disable-spidermonkey

而後將 rel/couchdb 目錄複製到 /opt/couchdb。

建立 couchdb 使用者。

sudo useradd -r -c 'CouchDB Administrator' -d/opt/couchdb -U -M -s/bin/bash couchdb

設定 couchdb 目錄的使用者。

sudo chown -R couchdb:couchdb /opt/couchdb

設定 couchdb 目錄的權限。

sudo find /opt/couchdb -type d -exec chmod 0770 {} \;
sudo chmod 0644 /opt/couchdb/etc/*

第一次執行

sudo -i -u couchdb /opt/couchdb/bin/couchdb

你會發現無法執行,修改 /opt/couchdb/etc/local.ini,加入 admin 帳號。

[admins]
admin = admin

再次啟動 server。如果成功,連線到 http://127.0.0.1:5984/_utils/index.html 並且使用 username = admin, password = admin 登入。 可以建立一個資料庫 my_database,然後使用 http://localhost:5984/_utils/index.html#verifyinstall 檢查目前的情況。

下面是 /opt/couchdb/etc/local.ini 關於使用者認證的部份,加入 cookie authentication 的設定。

[chttpd]
require_valid_user = true
authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {chttpd_auth, default_authentication_handler}

[chttpd_auth]
secret = your_long_secure_shared_secret

SSL

建立 ssl.conf 設定檔

[req]
prompt = no
default_md = sha256
default_bits = 2048
distinguished_name = dn
x509_extensions = v3_req

[dn]
C = TW
ST = Taiwan
L = Taipei
O = Orange Inc.
OU = IT Department
emailAddress = admin@example.com
CN = localhost

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
IP.1 = 127.0.0.1

透過指令建立開發測試用途的自簽憑證

openssl req -x509 -new -nodes -sha256 -utf8 -days 3650 -newkey rsa:2048 \
-keyout couchdb.key -out couchdb.crt -config ssl.conf

將 couchdb.key 與 couchdb.crt 複製到 /opt/couchdb/etc 目錄(需要使用 su 切換到 root 身份或者使用 sudo)。

修改 /opt/couchdb/etc/local.ini

[ssl]
enable = true
port = 6984
cert_file = /opt/couchdb/etc/couchdb.crt
key_file = /opt/couchdb/etc/couchdb.key
;password = somepassword

相關連結

2026/04/25

MariaDB

MariaDB 出垷的原因是因為 MySQL 被賣給了 SUN, 而後 SUN 被 Oracle 併購,所以 MySQL 被 Oracle 所擁有, 這導致一些 MySQL 原本的開發團隊人員對於 MySQL 是否能夠維持開放原始碼產生質疑, 所以複製 MySQL 5.5 原始碼出來維護的分支,並且成為大多數 Linux distribution 的內建選擇。 一開始 Oracle 其實對 MySQL 的管理還不錯,事情變化的源頭為 Oracle 推出 MySQL Heatwave 服務, 並且一些功能只在 MySQL Heatwave 增加,MySQL 社群版或者是企業版都不具備這些在 MySQL Heatwave 增加的功能, 同時 Oracle 也降低了對 MySQL 的開發重視度,這導致了 MySQL 社群版或者是企業版在 MySQL Heatwave 服務推出後其發展開始停滯, 並且遂漸跟不上使用者的需求。

MariaDB 使用與 MySQL 相同的通訊協定,一般而言可以作為 MySQL 的替代,其目標之一就是儘量維持與 MySQL 的相容, 雖然 MariaDB 與 MySQL 隨著二個開發團隊的各自開發而會有小地方的不同,但是目前仍然大多數的 MySQL 工具都可以直接使用。

在 openSUSE 安裝的指令:

sudo zypper in mariadb

使用下列的指令啟動 MariaDB server:

sudo systemctl start mariadb

使用下列的指令查詢 MariaDB server 的狀態:

sudo systemctl status mariadb

使用下列的指令停止 MariaDB server:

sudo systemctl stop mariadb

在安裝後啟動 MariaDB server,再使用下列的指令進行安全性設定:

sudo mysql_secure_installation

使用下列的指令驗證是否安裝正確(如果有設定密碼 password,輸入密碼):

mariadb -u root -p

在 MariaDB 中,若要完整支援 Unicode(包含 Emoji、特殊中日韓字元),應使用 utf8mb4 編碼, 而非舊的 utf8 (即 utf8mb3),因為舊版只支援 3 位元組,而 utf8mb4 支援 4 位元組。

修改 MariaDB 設定檔 /etc/my.cnf

[client]
default-character-set = utf8mb4

[mysql]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
character-set-client-handshake=FALSE

使用下列的指令重新啟動 MariaDB server:

sudo systemctl restart mariadb

重啟 MariaDB 服務後,登入並執行以下指令檢查:

SHOW VARIABLES LIKE 'character_set%';
SHOW VARIABLES LIKE 'collation%';

接下來建立一個新的資料庫以及新的使用者。

CREATE DATABASE `danilo`;

新增一個 MariaDB 資料庫使用者 danilo(Local access only),並將密碼設定為 danilo:

CREATE USER 'danilo'@'localhost' IDENTIFIED BY 'danilo';

給予 danilo 帳號在 danilo 資料庫上面的所有權限,讓 danilo 可以對 danilo 資料庫進行任何操作:

GRANT ALL PRIVILEGES ON danilo.* TO 'danilo'@'localhost';

執行下列的指令,讓修改確定有生效:

FLUSH PRIVILEGES;

檢查是否資料無誤:

SHOW GRANTS FOR 'danilo'@'localhost';

使用 GRANT 設定好帳號的權限後,接著就可以使用新的帳號登入使用:

mariadb -u danilo -p

MariaDB 採用可插拔儲存引擎架構,這意味著同一資料庫中的不同資料表可以使用不同的引擎,每個引擎都針對特定的工作負載進行了最佳化。 預設且最常用的通用引擎是 InnoDB。 MariaDB 可以使用 RocksDB 作為儲存引擎(稱為 MyRocks),只能在 x86_64 下使用,並不支援 32 位元的架構。 要注意的是,如果使用 MyRocks 作為儲存引擎,雖然寫入的速度獲得提升,但是 RocksDB engine 並不支援 FOREIGN KEY!

修改 MariaDB 設定檔 /etc/my.cnf

[mariadb]
plugin-load-add = ha_rocksdb

重啟 MariaDB 服務後,登入並執行以下指令檢查:

SHOW ENGINES;

在啟用後,建立資料表時指定儲存引擎就可以使用 RocksDB 作為儲存引擎。 下面是一個例子:

CREATE TABLE sensor_data (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    timestamp DATETIME NOT NULL,
    sensor_id SMALLINT UNSIGNED NOT NULL,
    value FLOAT NOT NULL
) ENGINE = RocksDB;

也可以先建立資料表,再使用下列的指令指定要使用的儲存引擎

ALTER TABLE sensor_data ENGINE=RocksDB;

如果要讓 RocksDB 成為預設的儲存引擎,需要修改 MariaDB 設定檔 /etc/my.cnf。 注意:在一般的情況下使用預設的 InnoDB 是不錯的主意, 因此需要的時候才在建立資料格的時候設定儲存引擎或者使用 ALTER TABLE 修改是一個不錯的做法。 這裡只是記錄如果要修改預設的儲存引擎應該怎麼做。

[mysqld]
#default-storage-engine=InnoDB
default-storage-engine=rocksdb

重啟 MariaDB 服務後,登入並執行以下指令檢查:

SHOW VARIABLES LIKE 'default_storage_engine';

MariaDB 可以使用 Mroonga 作為儲存引擎, Mroonga 支援包含 Chinese, Japanese, and Korean (CJK) 在內的全文搜尋功能,只能在 x86_64 下使用,並不支援 32 位元的架構。

修改 MariaDB 設定檔 /etc/my.cnf

[mariadb]
plugin-load-add = ha_rocksdb
plugin-load-add = ha_mroonga

也可以使用 SQL 指令啟用:

INSTALL SONAME 'ha_mroonga';

重啟 MariaDB 服務後,登入並執行以下指令檢查:

SHOW ENGINES;

相關連結

2026/04/14

C++ Crow

C++ 並不是網頁開發(Web Development)的首選語言, 但是在對效能十分要求或者是需要在資源略為受限的環境執行時,可以考慮使用 C++。 就目前而言,C++ 較為有名的選擇為效能極高並且支援多項功能的 Drogon, 不用安裝依賴函式庫的 Oat++, 以及設計上較為輕量但是功能也較少的 Crow。 還有一個選擇是 Wt, 但是就我個人而言,我認為 Wt 的策略,也就是使用 C++ 撰寫 UI 然後函式庫再轉譯為 HTML/CSS/JavaScript 的方式並不是一個好的做法。

Crow 是一套 C++ micro web framework,採用 Header Only 的設計,其靈感來自於 Python's Flask, 支援 HTTP 1.1 以及 Websocket,使用 C++ ASIO library 構建,特別適合建立 RESTful API 或 Web 服務。 Crow 的原作者在 2017 年停止維護, 不過之後自由軟體社群有人複製出來一份新的分支接手進行維護,目前仍然持續開發中。

在安裝前需要已經先安裝 ASIO development files,下面是在 openSUSE 的安裝指令:

sudo zypper in asio-devel

我使用 source code 安裝:

git clone https://github.com/CrowCpp/Crow.git
mkdir build; cd build; cmake .. -DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF
sudo make install

(在不編譯範例以及測試程式的情況下,Crow 只會安裝 CMake 相關檔案以及 header files,所以不用執行 make, 只需要使用 make install 安裝)

Crow 預設的靜態檔案資源放置在 static 目錄,但是可以透過巨集設定目錄。接下來寫一個簡單的靜態網頁伺服器驗證可以正確編譯與使用。

main.cpp

#define CROW_STATIC_DIRECTORY "public"
#define CROW_STATIC_ENDPOINT "/<path>"
#include "crow.h"

int main()
{
    crow::SimpleApp app;

    CROW_ROUTE(app, "/")
    ([](const crow::request&, crow::response& res) {
        res.set_static_file_info("public/index.html");
        res.end();
    });

    app.port(18080).run();
    return 0;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(Simple)

set(CMAKE_CXX_STANDARD 17)

# Search for Crow and required dependencies
find_package(Crow REQUIRED)

add_executable(simple main.cpp)

# Link the Crow library to your executable
target_link_libraries(simple PRIVATE Crow::Crow)

Crow 使用 Mustache 作為 template engine language, 接下建立一個簡單的網頁進行測試。 使用 Mustache 撰寫的網頁需要放在 templates 目錄下。

templates/fancypage.html

<!DOCTYPE html>
<html>
  <body>
  <p>Hello {{person}}!</p>
</body>
</html>

main.cpp

#include "crow.h"
// #include "crow_all.h"

int main() {
    crow::SimpleApp app;

    CROW_ROUTE(app, "/<string>")([](std::string name) {
        auto page = crow::mustache::load("fancypage.html");
        crow::mustache::context ctx({{"person", name}});
        return page.render(ctx);
    });

    app.port(18080).multithreaded().run();
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(Simple)

set(CMAKE_CXX_STANDARD 17)

# Search for Crow and required dependencies
find_package(Crow REQUIRED)

add_executable(simple main.cpp)

# Link the Crow library to your executable
target_link_libraries(simple PRIVATE Crow::Crow)

編譯成功後執行,使用瀏覽器瀏覽 http://localhost:18080/Bob 進行測試。

參考連結

2026/02/16

Apache Drill

Apache Drill 使用 Java 撰寫, 它參考了谷歌的 BigQuery 的想法,是一個開放原始碼、可擴展、支援複雜資料的分散式 columnar SQL 查詢引擎, 它可以訪問 Apache Hadoop 的 HDFS,從各種主流文件格式(例如 Parquet、JSON 和 CSV)以及支援的資料庫中讀取數據。 Apache Drill 的優點就是它可以使用 SQL 查詢語言查詢各種不同格式的資料並且與資料互動。

下載程式後解壓縮放在某個目錄,使用 embedded mode 檢查是否可以執行:

bin/drill-embedded

結束程式:

!quit

Distributed Mode 需要 Apache ZooKeeper,並且在 drill-override.conf 設定相關的設定。

drill.exec: {
  cluster-id: "drillbits1",
  zk.connect: "localhost:2181"
}

首先要先啟動 ZooKeeper service。
再來是啟動 Drill server:

bin/drillbit.sh start

停止 server:

bin/drillbit.sh stop

執行 sqlline 驗證可以連線到 Drill server:

bin/sqlline -u jdbc:drill:schema=dfs;zk=localhost

SSL/TLS

使用 keytool 建立 keystroe:

keytool -genkeypair -alias server \
-dname "CN=localhost, OU=IT Department, O=Orange Inc. ,L=Taipei, S=Taiwan,C=TW" \
-ext SAN=DNS:localhost,IP:127.0.0.1 \
-keyalg RSA -keysize 2048 -sigalg SHA256withRSA -storetype PKCS12 \
-validity 3650 \
-keypass password -keystore ./trusted.keystore -storepass password

在 drill-override.conf 設定相關的設定。

drill.exec: {
  cluster-id: "drillbits1",
  zk.connect: "localhost:2181",
  ssl: {
    protocol: "TLSv1.3",
    keyStoreType: "pkcs12",
    keyStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    keyStorePassword: "password",
    trustStoreType: "pkcs12",
    trustStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    trustStorePassword: "password"
  },
  security.user.encryption.ssl: {
    enabled: true,
  },
}

在 drill-override.conf 設定相關的設定,對 WEB UI 允許 SSL/TLS:

drill.exec: {
  cluster-id: "drillbits1",
  zk.connect: "localhost:2181",
  ssl: {
    protocol: "TLSv1.3",
    keyStoreType: "pkcs12",
    keyStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    keyStorePassword: "password",
    trustStoreType: "pkcs12",
    trustStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    trustStorePassword: "password"
  },
  security.user.encryption.ssl: {
    enabled: true,
  },
  http: {
    enabled: true,
    ssl_enabled: true,
  },
}

Plain Security

在 drill-override.conf 設定相關的設定,允許 Plain Security:

drill.exec: {
  cluster-id: "drillbits1",
  zk.connect: "localhost:2181",
  ssl: {
    protocol: "TLSv1.3",
    keyStoreType: "pkcs12",
    keyStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    keyStorePassword: "password",
    trustStoreType: "pkcs12",
    trustStorePath: "/home/danilo/Programs/drill/conf/trusted.keystore",
    trustStorePassword: "password"
  },
  security: {
    auth.mechanisms : ["PLAIN"],
  },
  security.user.auth {
    enabled: true,
    packages += "org.apache.drill.exec.rpc.user.security",
    impl: "pam4j",
    pam_profiles: [ "sudo", "login" ]
  },
  security.user.encryption.ssl: {
    enabled: true,
  },
  http: {
    enabled: true,
    ssl_enabled: true,
    auth: {
      mechanisms: ["FORM"],
    },
  },
}

Apache Drill 支援使用 libpam4j 或者是 jpam 作為 PAM Authenticator。 其中 libpam4j 已被內建,所以只要設定正確就可以使用。

相關連結

2026/02/12

Apache HBase

Apache HBase 是一個開放原始碼、分散式、 列存儲 (Wide column store) 的 NoSQL 資料庫。 它參考了谷歌的 BigTable 論文,實現的程式語言為 Java,建構於 Apache Hadoop HDFS 之上, 其核心架構採用 Master-Slave 模式,主要包含協調服務 ZooKeeper、 管理節點 HMaster、處理資料讀寫的 RegionServers,以及負責儲存資料的 HDFS。 Apache HBase 安裝與 Apache Hadoop 一樣分為三種模式:Standalone, Pseudo-Distributed 與Fully-Distributed。 Fully-Distributed 只能運行在Apache Hadoop 上面。

將下載的 HBase 檔案放到 /home/danilo/Programs/hbase,並且設定好環境變數:

export HBASE_HOME=/home/danilo/Programs/hbase
export PATH=$PATH:$HBASE_HOME/bin

使用 Pseudo-Distributed 與 local file system 安裝模式,修改 hbase-site.xml

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///home/danilo/Programs/hbase</value>
  </property>
  <property>
    <name>hbase.tmp.dir</name>
    <value>./tmp</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>  
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/var/lib/zookeeper</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>localhost</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value>
  </property>  
</configuration>

修改 hbase-env.sh

# Tell HBase whether it should manage it's own instance of ZooKeeper or not.
export HBASE_MANAGES_ZK=false

(HBase 可以設定是否自行管理自己的 ZooKeeper 叢集,這裡選擇使用外部的 ZooKeeper service。)

首先需要啟動 ZooKeeper service。
再來啟動 HBase:

bin/start-hbase.sh

停止 HBase:

bin/stop-hbase.sh

如果要執行 HBase shell:

bin/hbase shell

REST interface

啟動 HBase REST server(前景,使用 -port 指定 port):

bin/hbase rest start -p 8090

啟動 HBase REST server(背景,使用 -port 指定 port):

bin/hbase-daemon.sh start rest -p 8090

停止 HBaseHBase REST server(背景):

bin/hbase-daemon.sh stop rest

SSL/TLS

使用 keytool 建立 keystroe:

keytool -genkeypair -alias server \
-dname "CN=localhost, OU=IT Department, O=Orange Inc. ,L=Taipei, S=Taiwan,C=TW" \
-ext SAN=DNS:localhost,IP:127.0.0.1 \
-keyalg RSA -keysize 2048 -sigalg SHA256withRSA -storetype PKCS12 \
-validity 3650 \
-keypass password -keystore ./trusted.keystore -storepass password

修改 hbase-site.xml

<configuration>
  <property>
    <name>hbase.rootdir</name>
    <value>file:///home/danilo/Programs/hbase</value>
  </property>
  <property>
    <name>hbase.tmp.dir</name>
    <value>./tmp</value>
  </property>
  <property>
    <name>hbase.unsafe.stream.capability.enforce</name>
    <value>false</value>
  </property>
  <property>
    <name>hbase.cluster.distributed</name>
    <value>true</value>
  </property>  
  <property>
    <name>hbase.zookeeper.property.dataDir</name>
    <value>/var/lib/zookeeper</value>
  </property>
  <property>
    <name>hbase.zookeeper.quorum</name>
    <value>localhost</value>
  </property>
  <property>
    <name>hbase.zookeeper.property.clientPort</name>
    <value>2181</value>
  </property>
  <property>
    <name>hbase.rest.ssl.enabled</name>
    <value>true</value>
  </property> 
  <property>
    <name>hbase.rest.ssl.keystore.store</name>
    <value>/home/danilo/Programs/hbase/conf/trusted.keystore</value>
  </property> 
  <property>
    <name>hbase.rest.ssl.keystore.password</name>
    <value>password</value>
  </property> 
  <property>
    <name>hbase.rest.ssl.keystore.type</name>
    <value>pkcs12</value>
  </property>
  <property>
    <name>hbase.rest.ssl.truststore.store</name>
    <value>/home/danilo/Programs/hbase/conf/trusted.keystore</value>
  </property>
  <property>
    <name>hbase.rest.ssl.truststore.password</name>
    <value>password</value>
  </property>
  <property>
    <name>hbase.rest.ssl.truststore.type</name>
    <value>pkcs12</value>
  </property>
</configuration>

再來重新啟動 HBase server 與 HBase REST server 即可。

相關連結

2026/02/08

Apache ZooKeeper

Apache ZooKeeper 是 Apache 軟體基金會的一個軟體專案, 使用 Java 撰寫,它為大型分散式計算提供開源的分散式組態設定服務、同步服務和命名註冊。 ZooKeeper 曾經是 Hadoop 的一個子專案,但現在是一個獨立的頂級專案。

下面為設定 single node (Standalone Operation) 的方式。

將下載的 Apache ZooKeeper 檔案解壓縮以後放到 /opt/zookeeper,並且建立 /var/lib/zookeeper 目錄。

複製 conf/zoo_sample.cfg 為 conf/zoo.cfg,確定有下列的設定:

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181

啟動 server:

sudo bin/zkServer.sh start

如果要停止 server:

sudo bin/zkServer.sh stop

確定可以連線:

bin/zkCli.sh -server localhost:2181

接下來嘗試使用 systedm 管理,在 /usr/lib/systemd/system 目銾下建立 zookeeper.service

[Unit]
Description=ZooKeeper Service
Documentation=http://zookeeper.apache.org
Requires=network.target
After=network.target

[Service]
Type=forking
User=root
Group=root
SuccessExitStatus=143 # For stop service but status code is failed
ExecStart=/opt/zookeeper/bin/zkServer.sh start /opt/zookeeper/conf/zoo.cfg
ExecStop=/opt/zookeeper/bin/zkServer.sh stop /opt/zookeeper/conf/zoo.cfg
ExecReload=/opt/zookeeper/bin/zkServer.sh restart /opt/zookeeper/conf/zoo.cfg
WorkingDirectory=/var/lib/zookeeper
TimeoutSec=30
Restart=on-failure

[Install]
WantedBy=default.target

而後使用 systemd 啟動服務:

sudo systemctl start zookeeper.service

而後使用 systemd 查詢服務狀態:

sudo systemctl status zookeeper.service

而後使用 systemd 停止服務:

sudo systemctl stop zookeeper.service

相關連結

2026/02/04

Apache Geode

簡介

Apache Geode 是一個數據管理平台, 它為廣泛分佈的雲端架構中的資料密集型應用程式提供即時、一致的存取, 一般而言作為 In-Memory Data Grid (IMDG)、快取 (cache) 以及需要即時處理的場合使用。 Apache Geode 提供了 SQL-like 查詢語言,稱為 OQL (Object Query Language), Apache Geode 以 Java object 的方式儲存資料,所以選擇使用 OQL 查詢儲存的資料。

下載 Apache Geode 以後解壓縮放到某個目錄。gfsh 為 Apache Geode 用來管理的 shell tool。

執行 gfsh。下面是在 gfsh 執行的指令,資料來自於 Apache Geode in 15 Minutes or Less 的教學。

Locator 是 Geode 行程 (processes),它告訴新連線的成員正在執行的成員在哪裡,並為伺服器使用提供負載平衡。

start locator --name=locator1

Geode 提供了 web 界面的監控界面,下面是啟動的指令。預設使用者為 admin,密碼為 admin。

start pulse

Geode server 是一個行程 (process),它作為叢集中一個長期運行且可配置的成員而存在。 Geode server 主要用於託管長期運行的資料區域,以及運行標準的 Geode 行程,例如用戶端/伺服器配置中的伺服器。

start server --name=server1 --server-port=40411

Regions 是 Geode 叢集的核心建置模組,用於組織資料。在此練習中建立的 Region 採用複製機制在叢集成員之間複製數據, 並利用持久化機制將資料儲存到磁碟。

create region --name=regionA --type=REPLICATE_PERSISTENT

列出目前的 regions:

list regions

列出 Geode 叢集的成員:

list members

描述 Geode region regionA 的資料:

describe region --name=regionA

下面使用 put 新增資料以及使用 query 查詢資料。

put --region=regionA --key="1" --value="one"
put --region=regionA --key="2" --value="two"
query --query="select * from /regionA"

如果你需要刪除一個 region,可以這樣做:

destroy region --name=regionA

如果要停止 server:

stop server --name=server1

關閉系統,包括 locator。

shutdown --include-locators=true

REST

Geode 讓使用者能夠使用 REST 介面存取資料。

啟動一個 locator。

start locator --name=locator1

並且使用以下的設定:

configure pdx --read-serialized=true --disk-store

然後在啟動 Geode server 時加入 --start-rest-api 選項。

start server --name=server1 --server-port=40411 \
--start-rest-api=true \
--http-service-port=8080 --http-service-bind-address=localhost

使用 curl 驗證是否可以使用:

curl -i http://localhost:8080/geode/v1

SSL

使用 keytool 建立 keystroe:

keytool -genkeypair -alias server \
-dname "CN=localhost, OU=IT Department, O=Orange Inc. ,L=Taipei, S=Taiwan,C=TW" \
-ext SAN=DNS:localhost,IP:127.0.0.1 \
-keyalg RSA -keysize 2048 -sigalg SHA256withRSA -storetype PKCS12 \
-validity 3650 \
-keypass password -keystore ./trusted.keystore -storepass password

在 Geode 的 config 目錄下建立一個新的檔案 gfsecurity.properties。 Apache Geode 使用 ssl-enabled-components 設定不同組件間的通訊是否需要使用 SSL/TLS。 all 表示全部都要使用,這裡設定為 web,表示使用在 REST 介面。

ssl-enabled-components=web
ssl-protocols=TLSv1.2,TLSv1.3
ssl-ciphers=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_256_GCM_SHA384
ssl-keystore=/home/danilo/Programs/geode/config/trusted.keystore
ssl-keystore-password=password
ssl-keystore-type=pkcs12
ssl-truststore=/home/danilo/Programs/geode/config/trusted.keystore
ssl-truststore-password=password
ssl-truststore-type=pkcs12

使用 gfsh 啟動一個 locator。

start locator --name=locator1 --port=12345 \
--security-properties-file=/home/danilo/Programs/geode/config/gfsecurity.properties

並且使用以下的設定:

configure pdx --read-serialized=true --disk-store

使用 gfsh 啟動一個 server。

start server --name=server1 --server-port=40411 \
--start-rest-api=true \
--http-service-port=8080 --http-service-bind-address=localhost \
--security-properties-file=/home/danilo/Programs/geode/config/gfsecurity.properties

使用 curl 驗證是否可以使用:

curl -k -i https://localhost:8080/geode/v1

Authentication

以下的方式在 Java 24/25 以後,因為 SecurityManager 被禁止而無法使用。 In Java 17, the Security Manager was deprecated for removal under JEP 411. With JDK 24, its functionality will be effectively disabled. So you could not setup HTTP Basic Authentication support for Apache Geode by using SecurityManager since JDK 24.

將下列的內容儲存為 security.json,並且放到各個 locator 與 server 的目錄下。

{
  "roles": [
    {
      "name": "cluster",
      "operationsAllowed": [
        "CLUSTER:MANAGE",
        "CLUSTER:WRITE",
        "CLUSTER:READ"
      ]
    },
    {
      "name": "data",
      "operationsAllowed": [
        "DATA:MANAGE",
        "DATA:WRITE",
        "DATA:READ"
      ]
    },
    {
      "name": "region1&2Reader",
      "operationsAllowed": [
        "DATA:READ"
      ],
      "regions": ["region1", "region2"]
    }
  ],
  "users": [
    {
      "name": "super-user",
      "password": "1234567",
      "roles": [
        "cluster",
        "data"
      ]
    },
    {
      "name": "joebloggs",
      "password": "1234567",
      "roles": [
        "data"
      ]
    }
  ]
}

使用 gfsh 啟動一個 locator。

start locator --name=locator1 --port=12345 \
--security-properties-file=/home/danilo/Programs/geode/config/gfsecurity.properties \
--J=-Dgemfire.security-manager=org.apache.geode.examples.security.ExampleSecurityManager \
--classpath=.

連線到 locator 需要驗證:

connect --locator=localhost[12345] --user=super-user --password=1234567

並且使用以下的設定:

configure pdx --read-serialized=true --disk-store

使用 gfsh 啟動一個 server。

start server --name=server1 --locators=localhost[12345] --server-port=40411 \
--start-rest-api=true \
--http-service-port=8080 --http-service-bind-address=localhost \
--security-properties-file=/home/danilo/Programs/geode/config/gfsecurity.properties \
--J=-Dgemfire.security-manager=org.apache.geode.examples.security.ExampleSecurityManager \
--classpath=. --user=super-user --password=1234567

Memcached

Apache Geode 提供了 memcached 協議相容的介面。

使用 gfsh 啟動一個 locator。

start locator --name=locator1

並且在 config 新增或者修改 cache.xml,使用下列的設定:

<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns="http://geode.apache.org/schema/cache" 
       xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
       version="1.0">
  <region name="gemcached">
    <region-attributes refid="PARTITION" />
  </region>
</cache>

使用 gfsh 啟動一個 server。

start server --name=server1 --server-port=40411 \
--memcached-port=11211 --memcached-bind-address=localhost \
--memcached-protocol=BINARY \
--cache-xml-file=/home/danilo/Programs/geode/config/cache.xml

--memcached-protocol 可以設為 ASCII 或者是 BINARY。 ASCII 是 libMemcached 的預設值,如果要使用 BINARY 需要設定。

使用 memcached-for-Tcl 進行驗證。

package require Memcache

memcache server add localhost 11211
memcache behavior MEMCACHED_BEHAVIOR_BINARY_PROTOCOL 1
memcache set moo "cows go moo"
memcache get moo result
puts $result

相關連結