Process test
Node Containerashsummary假設你的電腦完全沒有安裝 Node.js,但你想要測試 Node 20 的行為
以前可能會想「那我是不是要去官網下載 Node?還要處理版本管理?裝錯版本怎麼辦?」
用 Docker 的話,可以直接這樣做
123456## -i :--interactive 啟動互動模式,保持標準輸入的開放## -t : --tty 讓 Docker 分配一個虛擬終端機(pseudo-TTY),並且綁定到容器的標準輸出上## node:20 : 啟動這個 container 所依據的 image## /bin/bash:容器啟動後要執行的命令## bash 啟動就是一個 shell 程式 Bash 是一個「命令解譯器」。它會等待你的輸入,解析指令,執行指令,顯示結果。類似 powershelldocker container run -it node:20 /bin/bash
這時候我們已經不在我們原本的環境中了,而是「進入」了 container 中,可以在這裡執行 node -v 指令,會發現這個環境中已經安裝了 node,且版本是 20.5.1 ...
Blue-Green Deployment — Step 1 實作
流程圖劇本、工具、程式碼、設定、憑證、執行環境Copy ArtifactCake這段流程慢在哪Step 1 的核心是 平行跑兩條線:A 線部署第一台測試機、B 線同步把 Green group 的機器準備起來,兩者同時進行互不等待,全部完成才進入 Step 2
flowchart TD
J1[⚙️ Jenkins 啟動] --> J2[載入 Jenkinsfile / Shared Library]
J2 --> J3[Checkout WebStore master]
J3 --> J4[Copy HK Prod 設定檔]
J4 --> S1[進入 Step 1]
S1 --> PAR{⚡ 平行執行}
PAR --> A1
PAR --> B1
subgraph A["🔴 A 線:Prepare First Machine"]
direction TB
A1[發 Slack:第一步開始] --> A2[下載 WebAPI / MobileWebMall\nartifact]
...
Blue-Green Deployment — 設計概念
意義角色切流量平行跑兩條線machine steps 說明準備兩套幾乎一樣的正式環境,一套持續服務使用者,另一套靜默部署新版,確認無誤後再把流量切過去
不在使用者正在踩的地板上施工,而是先把隔壁房間裝潢好、確認能住,再把人帶過去
部署流程flowchart TD
A[👤 使用者流量] --> B[🔵 Blue 環境\n舊版持續服務]
C[🟢 Green 環境] --> D[靜默部署新版]
D --> E{健康檢查}
E -->|✅ 通過| F[切流量至 Green]
E -->|❌ 失敗| G[保持 Blue 上線\n放棄本次部署]
F --> H[Blue 降為備援\n隨時可切回]
藍綠 vs 金絲雀兩者常被混淆,但著重點不同:
藍綠佈署
金絲雀佈署
重點
架構(兩套環境)
放量策略
流量方式
一次全切或漸進
先少量真實流量驗證,再逐步擴大
適合情境
需要快速回滾保底
需要低風險漸進驗收
藍綠佈署搭配 weighted target group,同樣可以做到漸進放量,兼顧兩種策略的優點
AL ...
Artifact
Artifact前端 Node.js 生態系的 build 流程Artifact 跟 Docker Image 的關係ASP.NET Core Web API 專案ASP.NET Core Web API 專案Artifact 就是「程式碼經過建置後產生、可以被保存與交付的成品」,讓後面的部署流程不用重新猜你的程式怎麼變成可執行狀態
假設有一個 React 專案
12345678my-app/ src/ App.tsx main.tsx package.json package-lock.json vite.config.ts
轉成某種「可以被執行或部署的結果」Pipeline 會執行
1234567891011121314151617181920212223## 根據 package.json 安裝專案需要的套件, 執行後會產生或更新 node_modules/ package-lock.json## node_modules/ 實際下載回來的套件## package-lock.json 紀錄這次安裝到的精確版本npm install ## OR ...
Helm
Helmhelm 實例Helm 與 KubernetesHelm chartvalues.yamltemplateshelm upgrade --installkubectl apply整條 pipelineSummaryHelm 是 Kubernetes 的「部署打包工具」,它把一堆 Kubernetes YAML 模板,加上環境的設定值,組成真正可以部署的 Kubernetes 資源。也就是,Kubernetes 真正看得懂的是 Deployment、Service、Ingress、ConfigMap 這些 YAML,而 Helm 幫我們產生這些 YAML
Helm 是為了避免每個環境都手刻一大堆 Kubernetes YAML;它讓你用同一套部署模板,搭配不同 values,部署到 QA、Prod、TW、HK 等不同地方。可以把 Helm 想成 template + values = Kubernetes YAML,也就是說 部署模板 + 環境設定 = 真正要丟給 Kubernetes 的部署檔
假設沒有 Helm,要部署一個 API 到 Kubernetes,可能要自己寫很多 ...
NMQ 並發 Race Condition 導致訂單子單轉單遺失分析
事件摘要一筆 HK 市場訂單(TradesOrderGroupId: 2708256)的兩筆子單中,只有一筆成功轉單至 ERP,另一筆(TradesOrderSlaveId: 8877652)轉單失敗,導致 WebStore 的 OrderSlaveFlow 狀態永久卡在 WaitingToTrans,且 ERPDB 中完全沒有該子單的資料。
現象觀察查詢 WebStore 的 OrderSlaveFlow,同一筆訂單的兩筆子單狀態截然不同:
OrderSlaveFlow_Id
TradesOrderSlaveId
StatusDef
TransToERPDateTime
SalesOrderSlaveId
8877547
8877653
WaitingToShipping
2026-05-07 08:16:38
8875983
8877546
8877652
WaitingToTrans
NULL
NULL
8877653 ✅ 正常轉單,有 SalesOrderSlaveId,狀態已推進至 WaitingToShipping
8877652 ❌ 轉單失敗,無任 ...
資料庫存 UTC 嗎
策略 : 資料存 UTC, 顯示才轉時區夏令時間 DST 的陷阱Unix Timestampsummary資料庫存的是「世界上真正發生的那一刻」,畫面顯示才是「這個使用者看到的當地時間」
假設有一個訂單建立時間:2026-05-04 10:00:00,若我們直接存「台灣時間 10:00」,問題是資料庫只看到:2026-05-04 10:00:00,它不知道這是台灣時間、日本時間、紐約時間,還是倫敦時間,因此實際我們會這樣設計
使用者在台灣建立訂單,時間 2026-05-04 10:00:00 GMT+8
轉成 UTC 2026-05-04 02:00:00 UTC
資料庫存 created_at = 2026-05-04T02:00:00Z,其中 Z 代表 UTC
美國使用者查看這筆訂單,假設他在紐約,當地時間是 UTC-4,資料庫拿出 2026-05-04T02:00:00Z
前端轉成紐約時間 2026-05-03 22:00:00
台灣使用者看到 2026-05-04 10:00,而紐約使用者看到 2026-05-03 22:00,兩個人看到的時間不同,但指向的是同一 ...
Docker for Dotnet and share
建立專案Dockerfilewhy multi stage建立 Image、 push Docker hub123456789101112131415## 建立專案dotnet new mvc -n MyMvcApp## or 指定版本dotnet new mvc -n MyMvcApp --framework net8.0cd .\MyMvcApp\## 觀察結構tree /F## 測試dotnet run一開始怎麼知道要這樣寫?首先,我們要從這個問題開始:我的程式要跑起來,需要哪些步驟?
1234dotnet restoredotnet builddotnet publish -c Release -o ./publishdotnet ./publish/MyMvcApp.dll
而其實 Dockerfile 只是把這些步驟搬進 container 裡,並且我們可以一段一段作
本機 dotnet run 成功
本機 dotnet publish 成功
本機 dotnet ./publish/MyMvcApp.dll 成功
寫 SDK-only Docke ...
EF Core 樂觀鎖的假象:BulkExtensions 讓 Rowversion 形同虛設
前言你有沒有遇過這樣的情況:
DB 有 Rowversion 欄位
EF Core Model 設定了 IsRowVersion().IsConcurrencyToken()
但實際測試發現並發更新時,完全沒有任何衝突偵測?
這篇文章從一個真實的促購活動加價購功能出發,完整拆解這個坑是怎麼形成的。
案例背景系統有一張 PromotionEngineSpecialPrice(活動價格表),記錄加價購活動下每個 SKU 的加購價格。
業務流程是:
SCMAPIV2(後台 API)接收營運人員的批次更新請求
驗證通過後,呼叫 PromotionWebAPI 的 POST /api/cart-extra-purchase/batch-update
PromotionWebAPI 查詢現有價格記錄,再批次更新價格與排序
這個流程看起來合理,但有一個隱藏的並發問題。
問題一:Lost Update(更新遺失)情境兩個請求 A、B 同時針對同一個活動的相同 SKU 發起更新:
123456T=0 A 查詢 DB → specialPrice { TypeValue: 100, ...
Autofac - 舊框架注入使用案例
AutofacEFHookReadWrite / ReadOnly一個整合範例summary今天我們的研究專案是是背景 Worker,它不像 Web 專案有 ASP.NET 內建 DI 容器,因此需要自己建立,Autofac 是當時 .NET Framework 生態系中最成熟的選擇
那他怎麼管理?完整生命週期是這樣
123456789101112131415161718程式啟動 ↓BatchUploadProcess.InitContainerBuilder() ↓new ContainerBuilder() ↓builder.RegisterModule(new DAModule()) ← 每個 DB 各一個 ↓builder.RegisterModule(new ServiceModule()) ← BL 層 ↓builder.Build() → IContainer ↓每次 Task 執行時container.BeginLifetimeScope() → ILifetimeScope ↓scope.Resolve<ISales ...






