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://joyjs.cn/archives/4789

(0)
Walker的头像Walker
上一篇 2025年11月24日 00:00
下一篇 2025年11月25日 14:00

相关推荐

  • Go工程师体系课 007【学习笔记】

    商品微服务 实体结构说明 本模块包含以下核心实体: 商品(Goods) 商品分类(Category) 品牌(Brands) 轮播图(Banner) 品牌分类(GoodsCategoryBrand) 1. 商品(Goods) 描述平台中实际展示和销售的商品信息。 字段说明 字段名 类型 说明 name String 商品名称,必填 brand Pointer …

    个人 2025年11月25日
    17500
  • 【开篇】

    我是Walker,生于八十年代初,代码与生活的旅者。全栈开发工程师,游走于前端与后端的边界,执着于技术与艺术的交汇点。 代码,是我编织梦想的语言;项目,是我刻画未来的画布。在键盘的敲击声中,我探索技术的无尽可能,让灵感在代码里永恒绽放。 深度咖啡爱好者,迷恋每一杯手冲的诗意与仪式感。在咖啡的醇香与苦涩中,寻找专注与灵感,亦如在开发的世界中追求极致与平衡。 骑…

    2025年2月6日 个人
    2.1K00
  • 深入理解ES6 006【学习笔记】

    Symbol和Symbol属性 第6种原始数据类型:Symbol。私有名称原本是为了让开发者们创建非字符串属性名称而设计的,但是一般的技术无法检测这些属性的私有名称 创建Symbol let firstName = Symbol(); let person = {} person[firstName] = "Nicholas"; cons…

    个人 2025年3月8日
    1.2K00
  • 深入理解ES6 011【学习笔记】

    Promise与异步编程 因为执行引擎是单线程的,所以需要跟踪即将运行的代码,那些代码被放在一个任务队列中,每当一段代码准备执行时,都会被添加到任务队列中,每当引擎中的一段代码结束执行,事件循环会执行队列中的一下个任务。 Promise相当于异步操作结果占位符,它不会去订阅一个事件,也不会传递一个回调函数给目标函数,而是让函数返回一个Promise,就像这样…

    个人 2025年3月8日
    1.1K00
  • Go工程师体系课 004【学习笔记】

    需求分析 后台管理系统 商品管理 商品列表 商品分类 品牌管理 品牌分类 订单管理 订单列表 用户信息管理 用户列表 用户地址 用户留言 轮播图管理 电商系统 登录页面 首页 商品搜索 商品分类导航 轮播图展示 推荐商品展示 商品详情页 商品图片展示 商品描述 商品规格选择 加入购物车 购物车 商品列表 数量调整 删除商品 结算功能 用户中心 订单中心 我的…

    个人 2025年11月25日
    17700

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信
欢迎🌹 Coding never stops, keep learning! 💡💻 光临🌹