Go工程師體系課 018

API 網關與持續部署入門(Kong & Jenkins)

對應資料目錄《第 2 章 Jenkins 入門》《第 3 章 通過 Jenkins 部署服務》,整理 Kong 與 Jenkins 在企業級持續交付中的實戰路徑。即便零基礎,也能順著步驟搭建出自己的網關 + 持續部署流水線。

課前導覽:什麼是 API 網關

API 網關位於客戶端與後端微服務之間,相當於系統的“統一入口”。它負責接收外部請求、根據配置路由到不同的後端服務,並在入口層完成一系列通用能力(認證、鑑權、限流、監控、協議轉換等),從而簡化客戶端調用流程、降低服務之間的耦合。

graph LR
    ClientA[Web 客戶端] --> APIGateway[API Gateway]
    ClientB[移動端] --> APIGateway
    ClientC[第三方合作方] --> APIGateway
    APIGateway -->|路由/聚合| ServiceA[用戶服務]
    APIGateway -->|協議轉換| ServiceB[訂單服務]
    APIGateway -->|安全控制| ServiceC[支付服務]

核心職責

  • 統一入口與路由:所有請求先到網關,再按照路徑、域名、Header 等規則轉發。
  • 安全防護:集中處理認證、鑑權、限流、IP 白名單、WAF 等安全策略。
  • 協議與格式轉換:支持 REST、gRPC、GraphQL 等,將多種協議對外統一。
  • 可觀測與運維:收集日誌、指標、Tracing,提供熔斷、重試、緩存等彈性措施。
  • 聚合與編排:組合多個後端接口,返回定製化響應,降低客戶端調用複雜度。

爲什麼需要 API 網關

  • 微服務數量增長:客戶端不必關心每個服務的地址和認證方式,由網關統一暴露。
  • 治理策略集中化:限流、熔斷、監控等策略在網關層統一實施,避免各服務重複實現。
  • 便於演進與灰度:通過路由規則實現灰度發佈、A/B 測試和版本切換。
  • 提升安全合規性:統一入口便於審計與風險控制。
sequenceDiagram
    participant Client as 客戶端
    participant Gateway as API 網關
    participant Auth as 身份驗證服務
    participant Order as 訂單服務
    participant Billing as 計費服務

    Client->>Gateway: 請求 /v1/order
    Gateway->>Auth: 校驗 Token
    Auth-->>Gateway: 返回用戶信息
    Gateway->>Order: 調用訂單詳情
    Gateway->>Billing: 查詢支付狀態
    Gateway-->>Client: 聚合後的訂單響應

常見產品:Nginx + Lua、Kong、Tyk、APISIX、AWS API Gateway、Spring Cloud Gateway 等。

第 2 章:Kong 實戰入門

結合 2-1 ~ 2-6 視頻,掌握從安裝到安全加固的常見操作。

2-1 Kong 的 8001、8000 和 1337 端口號

Kong 默認開放多個端口,每個端口承載不同職責。先弄清楚它們的作用,更容易排查問題。

端口 協議 角色 常見操作
8000 HTTP 對外代理入口 業務請求走這裏
8443 HTTPS 代理入口(TLS) 暴露 HTTPS 服務
8001 HTTP Admin API 新建 Service/Route、查看狀態
8444 HTTPS Admin API(TLS) 在生產環境更安全
1337 HTTP Dev Portal/Manager 可視化配置(Docker 快速體驗)
graph TD
    subgraph 業務面
        Client[客戶端流量] --> Proxy[8000/8443 Proxy]
        Proxy --> UpstreamPool[上游服務]
    end
    subgraph 運維面
        AdminAPI[8001/8444 Admin API] --> KongCore[Kong 核心]
        Portal[1337 Manager] --> KongCore
    end
    KongCore --> Metrics[日誌/指標輸出]

快速自檢命令:

# 確認端口監聽狀態
docker exec kong netstat -tnlp | grep 800
# 用 Admin API 獲取節點信息
curl http://localhost:8001/

2-2 基本的路由轉發配置

入門最先做的事情是讓一個 URL 能正確轉發到後端服務。

  1. 註冊 Service:定義上游地址與協議。
  2. 創建 Route:決定哪些請求命中上述 Service。
  3. 驗證轉發:通過 curl 或瀏覽器訪問代理入口。
# 1. 註冊服務
curl -X POST http://localhost:8001/services \
  --data "name=user-service" \
  --data "url=http://mockbin.org"

# 2. 綁定路由
curl -X POST http://localhost:8001/services/user-service/routes \
  --data "paths[]=/users" \
  --data "strip_path=true"

# 3. 訪問 Kong 代理
curl -i http://localhost:8000/users

常見坑:hostspathsmethods 是“與”關係,匹配條件越多,命中概率越低;務必確保客戶端 Host Header 與路由配置一致。

2-3 Kong 的 Service、Route、Upstream

Service、Route、Upstream 構成 Kong 的核心抽象,理解它們之間的關係能幫助你靈活組合流量策略。

  • Service:描述後端應用(協議、域名、端口、超時)。
  • Route:定義如何把請求匹配到某個 Service。
  • Upstream:爲 Service 提供“實例池”,支持負載均衡、健康檢查。
  • Target:Upstream 中的具體實例(IP:Port)。
graph TD
    Client --> Route[Route: hosts/paths]
    Route --> Service[Service: http://orders.internal]
    Service --> Upstream[Upstream: order-upstream]
    Upstream --> TargetA[10.0.1.10:9000]
    Upstream --> TargetB[10.0.1.11:9000]
    Route -- Plugin 鏈 --> Plugins[認證/限流/日誌]

最佳實踐:

  • 爲每個上游服務創建獨立 Upstream,方便後續滾動升級。
  • 插件既可以掛在 Route,也可以掛在 Service 或全局,全局策略優先級最低。
  • 使用標籤(Tags)對資源分組,便於運維搜索。

2-4 Kong 集成 Consul 實現服務發現和健康檢查

當後端實例經常變化時,把健康檢查託付給 Consul 能減輕人工維護壓力。

  1. 準備 Consul:啓動 Consul Agent,並註冊你的應用實例(可使用 service.json 文件)。
  2. 配置 Service Discovery:在 Kong 的 Service 中新增 hostservice.consul 形式,同時在 KONG_DATABASEkong.conf 中開啓 service_discovery
  3. 聲明 Upstream 使用 Consul
curl -X POST http://localhost:8001/upstreams \
  --data "name=order.consul" \
  --data "service=orders" \
  --data "healthchecks.active.type=http"
  1. Consul 維護實例:當實例上下線時,Consul 自動同步,Kong 讀取最新健康狀態。
graph LR
    Consul -->|服務健康| KongUpstream
    Jenkins -->|部署後註冊| Consul
    KongProxy --> KongUpstream --> BackendPods[訂單服務實例]

提示:確保 Kong 與 Consul 網絡可達,並在 Consul 中開啓 TTL 或 HTTP 健康檢查。

2-5 Kong 配置 JWT 實現登錄校驗

JWT 插件讓 Kong 成爲統一認證入口。典型流程如下。

  1. 啓用插件並創建消費者
# 添加一個消費者
curl -X POST http://localhost:8001/consumers \
  --data "username=mobile-app"

# 爲消費者生成密鑰對
curl -X POST http://localhost:8001/consumers/mobile-app/jwt
  1. 在 Route 或 Service 上啓用 JWT 插件
curl -X POST http://localhost:8001/services/user-service/plugins \
  --data "name=jwt" \
  --data "config.claims_to_verify=exp"
  1. 客戶端構造並帶上 Token
curl http://localhost:8000/users \
  -H "Host: api.example.com" \
  -H "Authorization: Bearer <簽名後的JWT>"
sequenceDiagram
    participant Client as 客戶端
    participant Kong as Kong 網關
    participant JWT as JWT 插件
    participant Upstream as 上游服務

    Client->>Kong: 帶 Authorization 的請求
    Kong->>JWT: 校驗簽名、過期時間
    JWT-->>Kong: 校驗通過/失敗
    opt 校驗通過
        Kong->>Upstream: 轉發請求
        Upstream-->>Kong: 返回業務響應
        Kong-->>Client: 200 OK
    end
    opt 校驗失敗
        Kong-->>Client: 401 未授權
    end

小貼士:結合 key-authrate-limiting 插件可以進一步區分不同終端的訪問權限與頻率。

2-6 Kong 配置反爬蟲 IP 黑名單

對抗惡意請求的常見手段是“白名單 + 黑名單 + 速率限制”。

# 開啓 IP 限制插件
curl -X POST http://localhost:8001/services/user-service/plugins \
  --data "name=ip-restriction" \
  --data "config.deny[]=192.168.1.100" \
  --data "config.deny[]=203.0.113.0/24"

結合思路:

  • 黑名單:發現惡意 IP 立即加入 deny 列表。
  • 白名單:對於管理後臺、BFF 接口可設置 allow 列表,默認拒絕其他來源。
  • 限速:搭配 rate-limitingbot-detection 插件削峯。
  • 審計:將 Kong 日誌投遞到 ELK/Loki,識別異常 UA、Referer。
graph TD
    ClientReq[請求] --> IPCheck[IP 限制插件]
    IPCheck -->|黑名單| Block[返回 403]
    IPCheck -->|通過| RateLimit[限流插件]
    RateLimit --> Backend[上游服務]

通過 Jenkins 部署服務

對應 3-1 ~ 3-11 視頻,帶你從 Jenkins 安裝、插件選擇到 Pipeline 編排與發佈自動化。

3-1 敏捷開發中的持續集成痛點

  • 代碼合併頻繁,人工打包、手動發版效率低。
  • 不同環境依賴差異大,容易出現“在我電腦能跑”。
  • 缺少統一的質量門檻,測試遺漏導致線上回滾。
  • 部署結果缺乏追溯,無法快速定位失敗節點。

敏捷開發:我們也不知道到底要開發啥,走一步看一步吧
用戶故事:老闆說明天要上這個功能,怎麼實現我不管
快速迭代:上次做的功能點擊率太低,把廣告改成全屏
用戶痛點:昨天用戶投訴了,把廣告調整下
擁抱變化:老闆天天都有新想法,大家要適應(不要怪我)
持續交付:每個版本都有問題,總是持續交給測試,交付間隔10分鐘
結對開發:bug太多了,直接去測試妹子的工位邊測邊改
代碼評審:這個代碼是你審的,將來出了問題你是要負責任的
彈性工作:不限定下班時間,修完bug才能走
四個會議:(Scrum Meeting)每天早上9:00開始,想上班遲到沒門

上面這段“段子體”調侃了業界常見的敏捷誤區:把敏捷等同於無計劃、把用戶故事當作臨時需求、以“快速迭代”包裝粗糙上線,甚至以持續交付之名忽視質量門檻。真正的敏捷強調的是:

  • 有節奏的計劃:迭代前仍需梳理需求、估算工作量,並對外同步可交付目標。
  • 用戶故事聚焦價值:描述的是用戶角色、場景與收益,幫助團隊理解“爲什麼做”,不是拍腦袋的功能指令。
  • 持續交付的前提是質量:自動化測試、代碼評審、監控告警是基礎保障,頻繁交付是爲了快速驗證價值,而非帶著缺陷不停“扔給測試”。
  • 擁抱變化也要有邊界:通過產品 backlog 和迭代節奏管理變更,必要時調整優先級而非臨時插單。
  • Scrum 四會(計劃會、每日站會、評審會、回顧會)是爲了同步信息、發現風險、持續改進,而不是形式主義的打卡。

理解這些原則,才能把敏捷和持續集成結合起來,讓 Jenkins 流水線服務於“持續交付價值”而不是“持續交付問題”。

3-2 安裝 Jenkins 和關閉防火牆

  1. Docker 安裝最快捷
docker run -d --name jenkins \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts
  1. 初始化嚮導:根據提示輸入解鎖密碼、安裝推薦插件、創建管理員。
  2. 服務器防火牆:若使用 CentOS,可先關閉或放行 8080 端口。
sudo systemctl stop firewalld
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

3-3 Jenkins 構建服務部署流程

sequenceDiagram
    participant Dev as 開發者
    participant Git as 代碼倉庫
    participant Jenkins
    participant Registry as 鏡像倉庫
    participant K8s as Kubernetes
    participant Kong

    Dev->>Git: 提交代碼
    Git-->>Jenkins: Webhook/輪詢觸發
    Jenkins->>Jenkins: 編譯 + 測試
    Jenkins->>Registry: 推送鏡像/製品
    Jenkins->>K8s: 滾動更新
    Jenkins->>Kong: 調用 Admin API 刷新路由
    Jenkins-->>Dev: 通知結果(釘釘/郵件)

流程關鍵點:

  • 用憑證(Credentials)保存 Git、Registry、Kubernetes 的訪問密鑰。
  • 在失敗階段及時 emailext 或機器人提醒,方便第一時間處理。
  • 通過 post 塊寫明成功與失敗的不同通知動作。

3-4 安裝 Jenkins 常用插件

  • Git/Git Parameter:支持多倉庫、多分支構建。
  • Pipeline + Blue Ocean:聲明式流水線與可視化展示。
  • Credentials Binding:將敏感憑證注入環境變量。
  • Kubernetes / Docker:容器化構建能力。
  • Email Extension、釘釘/企業微信插件:構建通知。
  • Config File Provider:集中管理 Maven settings、Kubeconfig 等文件。

3-5 通過 Freestyle Style 構建項目

  1. 新建 Freestyle project,配置描述幫助團隊理解用途。
  2. Source Code Management 中填入 Git 地址和憑證。
  3. Build Triggers 勾選 GitHub hook triggerPoll SCM
  4. Build 步驟添加 Shell,例如:
go test ./...
go build -o bin/order-service ./cmd/order
  1. Post-build Actions 可歸檔二進制、發佈通知。

適用於簡單項目或快速 PoC,後續可遷移到 Pipeline。

3-6 將構建服務器上的代碼上傳到運行環境

常見做法:

  • SCP/RSYNC:把編譯產物推送到目標主機。
scp bin/order-service deploy@10.0.0.12:/srv/apps/order/
ssh deploy@10.0.0.12 "systemctl restart order.service"
  • Artifactory/Nexus:上傳構建物,部署機再拉取。
  • Docker Registry:構建鏡像後用 kubectldocker stack 部署。

記得在 Jenkins 中配置 SSH 憑證,並限制執行節點的權限。

3-7 通過 Pipeline 實現持續集成

聲明式 Pipeline 能把流程寫成代碼,便於複用與審查。

pipeline {
  agent any
  environment {
    REGISTRY = "registry.example.com"
    APP = "order-service"
  }
  stages {
    stage('Checkout') {
      steps { git url: 'https://github.com/demo/order-service.git', branch: 'main' }
    }
    stage('Test') {
      steps { sh 'go test ./...' }
    }
    stage('Build Image') {
      steps { sh 'docker build -t $REGISTRY/$APP:$BUILD_NUMBER .' }
    }
    stage('Push Image') {
      steps { sh 'docker push $REGISTRY/$APP:$BUILD_NUMBER' }
    }
    stage('Deploy') {
      steps {
        sh '''
        kubectl set image deploy/order-service order=$REGISTRY/$APP:$BUILD_NUMBER
        kubectl rollout status deploy/order-service
        '''
      }
    }
    stage('Notify Kong') {
      steps { sh 'curl -X POST http://kong-admin:8001/services/order-service/reload' }
    }
  }
  post {
    success { emailext subject: "Order Service #${BUILD_NUMBER} 成功", to: "team@example.com" }
    failure { emailext subject: "Order Service #${BUILD_NUMBER} 失敗", to: "devops@example.com" }
  }
}

3-8 通過 Jenkinsfile 管理構建 Pipeline

  • Jenkinsfile 存放在代碼倉庫根目錄,版本化構建流程。
  • 代碼評審不僅看業務代碼,也要審查流水線改動。
  • 可以創建多分支 Pipeline,讓 Jenkins 自動發現新分支的 Jenkinsfile。

目錄示例:

.
├── Jenkinsfile
├── cmd/
├── deploy/
└── infra/helm/

3-9 通過遠程和其他工程觸發構建

  • 遠程觸發:在 Job 設置 Trigger builds remotely,生成 Token,使用 curl 調用。
curl "http://jenkins.example.com/job/order-service/build?token=deploy"
  • 上游工程觸發:在 Build Triggers 勾選 Build after other projects are built,實現流水線串聯。
  • 通過腳本觸發:利用 Jenkins CLI 或 REST API 與 ChatOps 機器人聯動。

3-10 定時構建和輪詢 SCM 構建

  • Poll SCM:輸入 Cron 表達式,例如 H/5 * * * * 表示每 5 分鐘檢查一次 Git 是否有新提交。
  • Build periodically:無需代碼變更也定時執行,例如夜間運行安全掃描。
  • Cron 小技巧:使用 H 讓 Jenkins 爲不同作業自動分散執行時間,避免任務扎堆。

3-11 參數化 Pipeline 構建項目

參數化讓流水線更加靈活,常見用於選擇分支、版本或部署環境。

pipeline {
  agent any
  parameters {
    choice(name: 'ENV', choices: ['dev', 'staging', 'prod'], description: '部署環境')
    string(name: 'IMAGE_TAG', defaultValue: 'latest', description: '鏡像版本')
    booleanParam(name: 'SKIP_TEST', defaultValue: false, description: '是否跳過測試')
  }
  stages {
    stage('Checkout') {
      steps { git branch: params.ENV == 'prod' ? 'main' : params.ENV, url: 'https://github.com/demo/order-service.git' }
    }
    stage('Test') {
      when { expression { return !params.SKIP_TEST } }
      steps { sh 'go test ./...' }
    }
    stage('Deploy') {
      steps { sh "kubectl set image deploy/order-service order=${params.IMAGE_TAG}" }
    }
  }
}

常見用法:一份 Pipeline 覆蓋多個環境,或爲手動回滾提供快捷入口。


複習與練習清單

  • 畫出公司內的 API 網關拓撲,標註 Service、Route、Plugin 的關係和流量來源。
  • 用 Docker 啓動 Kong,復現 2-1 ~ 2-6 的端口檢查、路由、JWT、黑名單配置。
  • 在測試環境部署 Jenkins,完成一條 Freestyle 與一條 Pipeline 流水線,並打通到 Kong 的熱更新。
  • 將 Jenkinsfile 納入代碼評審流程,嘗試爲主要分支增加參數化發佈。
  • 使用 deckdecK 導出 Kong 配置,結合 Git 管理,實現“配置即代碼”。

主題測試文章,只做測試使用。發佈者:Walker,轉轉請注明出處:https://walker-learn.xyz/archives/6784

(0)
Walker的頭像Walker
上一篇 12小時前
下一篇 1天前

相關推薦

  • 編程基礎 0005_錯誤處理進階

    Go 錯誤處理進階 目錄 Go 錯誤處理哲學 error 接口本質 自定義錯誤類型 fmt.Errorf 與 %w 包裝錯誤 errors.Is 和 errors.As 哨兵錯誤模式 錯誤處理最佳實踐 實際項目中的錯誤處理模式 1. Go 錯誤處理哲學 1.1 與 try-catch 的根本區別 在 Java、Python、C++ 等語言中,異常處理依賴 t…

    後端開發 16小時前
    800
  • Go工程師體系課 013

    訂單事務 先扣庫存 後扣庫存 都會對庫存和訂單都會有影響, 所以要使用分佈式事務 業務(下單不對付)業務問題 支付成功再扣減(下單了,支付時沒庫存了) 訂單扣減,不支付(訂單超時歸還)【常用方式】 事務和分佈式事務 1. 什麼是事務? 事務(Transaction)是數據庫管理系統中的一個重要概念,它是一組數據庫操作的集合,這些操作要麼全部成功執行,要麼全部…

  • 編程基礎 0010_Go底層原理與源碼精華

    Go 底層原理與源碼精華 基於《Go 源碼剖析》(雨痕, 第五版下冊)、《Go 1.4 runtime》、《Go 學習筆記 第四版》、《Golang 性能優化》、《Go Execution Modes》等資料整理,並補充現代 Go 版本的變化。 一、Go 編譯器與鏈接器 1.1 編譯流程概覽 Go 的編譯過程分爲以下階段: 源碼 (.go) --> 詞…

    後端開發 19小時前
    500
  • Go工程師體系課 008

    訂單及購物車 先從庫存服務中將 srv 的服務代碼框架複製過來,查找替換對應的名稱(order_srv) 加密技術基礎 對稱加密(Symmetric Encryption) 原理: 使用同一個密鑰進行加密和解密 就像一把鑰匙,既能鎖門也能開門 加密速度快,適合大量數據傳輸 使用場景: 本地文件加密 數據庫內容加密 大量數據傳輸時的內容加密 內部系統間的快速通…

  • Go工程師體系課 004

    需求分析 後臺管理系統 商品管理 商品列表 商品分類 品牌管理 品牌分類 訂單管理 訂單列表 用戶信息管理 用戶列表 用戶地址 用戶留言 輪播圖管理 電商系統 登錄頁面 首頁 商品搜索 商品分類導航 輪播圖展示 推薦商品展示 商品詳情頁 商品圖片展示 商品描述 商品規格選擇 加入購物車 購物車 商品列表 數量調整 刪除商品 結算功能 用戶中心 訂單中心 我的…

    1天前
    100
簡體中文 繁體中文 English