Online Boutique 云原生微服务 Demo 架构剖析与 GKE 部署实战指南
2026/9/13 23:19:30 网站建设 项目流程

Online Boutique 云原生微服务 Demo 架构剖析与 GKE 部署实战指南

【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo

Online Boutique 是 Google 开源的一套cloud-first(云优先)微服务演示应用:一个完整的 Web 电商系统,用户可以在其中浏览商品、加入购物车并完成购买。整个应用由 11 个使用不同语言编写的微服务组成,服务间通过gRPC通信,可运行在任何 Kubernetes 集群之上。本指南以仓库根目录的 README.md 为骨架,结合 protos/demo.proto 等源码,带你系统理解其架构设计,并完整走通GKE 快速部署Kustomize 变体定制的实战流程。

Online Boutique 的 11 个微服务及它们之间的调用关系(图片来自 docs/img/architecture-diagram.png)

项目概览:为什么值得研究这套 Demo

Online Boutique 的价值在于它不是玩具代码,而是一套面向企业现代化改造演示的完整样例:它刻意使用 Go、C#、Node.js、Python、Java 五种语言编写不同的微服务,覆盖了 gRPC 接口定义、状态存储、异步消息、流量注入等真实生产场景,并且被 Google 官方用来演示 GKE、Cloud Service Mesh、Spanner、Memorystore、AlloyDB、Gemini 等云产品的集成方式。

从源码结构看,仓库布局非常清晰:

  • protos/demo.proto:所有微服务共享的 gRPC 协议定义;
  • src/:11 个微服务的源码、Dockerfile 与测试;
  • kubernetes-manifests/ 与 release/kubernetes-manifests.yaml:可直接应用的 Kubernetes 清单;
  • kustomize/:基于 Kustomize 的部署变体定制体系;
  • helm-chart/:Helm Chart 打包方式;
  • terraform/:Terraform 一键部署;
  • docs/:本地开发、产品需求、发布等补充文档。

架构总览:11 个微服务与 gRPC 通信

Online Boutique 由 11 个微服务组成,它们通过 gRPC 相互调用(前端对外暴露 HTTP)。README 中的服务清单完整如下:

服务语言说明
frontendGo对外提供 HTTP 服务器来渲染网站页面;无需注册/登录,自动为所有用户生成会话 ID
cartserviceC#将用户购物车中的商品存入 Redis 并可读取
productcatalogserviceGo从 JSON 文件提供商品列表,支持商品搜索与单品查询
currencyserviceNode.js将金额在不同币种间转换,汇率数据取自欧洲央行;是 QPS 最高的服务
paymentserviceNode.js对给定信用卡信息(mock)按金额扣款,并返回交易 ID
shippingserviceGo根据购物车内容给出运费估算,并向给定地址发货(mock)
emailservicePython向用户发送订单确认邮件(mock)
checkoutserviceGo读取用户购物车、准备订单,并编排支付、发货和邮件通知
recommendationservicePython根据购物车中的商品推荐其他产品
adserviceJava根据上下文关键词提供文本广告
loadgeneratorPython/Locust持续发送模拟真实用户购物流程的请求到前端

gRPC 协议定义:protos/demo.proto

所有服务间的接口契约都集中在 protos/demo.proto(packagehipstershop),这是理解整套系统调用关系的核心文件。其中定义了 9 个 gRPC service:

  • CartServiceAddItemGetCartEmptyCart,以user_id+CartItemproduct_id+quantity)操作购物车;
  • RecommendationServiceListRecommendations,根据user_id与购物车中的product_ids返回推荐商品;
  • ProductCatalogServiceListProductsGetProductSearchProductsProduct消息包含idnamedescriptionpictureprice_usd(Money 类型)和categories分类标签;
  • ShippingServiceGetQuote返回Money运费,ShipOrder返回tracking_id
  • CurrencyServiceGetSupportedCurrenciesConvert
  • PaymentServiceCharge,入参是Money金额 +CreditCardInfo信用卡信息,出参是transaction_id
  • EmailServiceSendOrderConfirmation,携带OrderResult(含order_idshipping_tracking_idshipping_costshipping_address与订单明细);
  • CheckoutServicePlaceOrder,统一接收user_iduser_currencyAddressemailCreditCardInfo,返回OrderResult
  • AdServiceGetAds,根据页面上下文关键词返回Adredirect_url+text)。

值得注意的细节是Money消息的设计——它采用currency_code(ISO 4217 三位字母码)、units(整数部分)和nanos(10^-9 精度的小数部分)三段式表示,以避免浮点误差。该类型被 checkoutservice、currencyservice 等多个服务复用,其运算逻辑实现在 src/checkoutservice/money/money.go 中,并有 money_test.go 配套单元测试。

一次下单的完整调用链:以 checkoutservice 为例

从源码看,一次PlaceOrder(src/checkoutservice/main.go)会依次编排多个下游服务:

  1. 生成订单 UUID(uuid.NewUUID());
  2. prepareOrderItemsAndShippingQuoteFromCart:先调cartservice取购物车、调productcatalogservice获取商品信息、调currencyservice将价格换算为用户币种、调shippingservice获取运费报价;
  3. 累加商品总价与运费后调用paymentserviceCharge扣款(mock);
  4. 调用shippingserviceShipOrder生成物流单号;
  5. 清空用户购物车(emptyUserCart);
  6. 最后调用emailservice发送订单确认邮件。

这条链路充分展示了 gRPC 微服务编排的典型模式:一个聚合服务(checkout)依赖多个下游服务完成一笔业务,同时每个服务都暴露Check/Watch健康检查接口(基于grpc_health_v1),供 Kubernetes 探针使用。

快速开始:在 GKE 上部署 Online Boutique

README 提供了标准的 GKE 快速部署流程,共 9 步,下面完整展开。

前提条件

  • 一个 Google Cloud 项目;
  • 安装了gcloudgitkubectl的 Shell 环境。

步骤 1:克隆仓库

git clone --depth 1 --branch v0 https://github.com/GoogleCloudPlatform/microservices-demo.git cd microservices-demo/

--depth 1用于跳过 git 历史,加快克隆速度。

步骤 2:配置项目与启用 GKE API

export PROJECT_ID=<PROJECT_ID> export REGION=us-central1 gcloud services enable container.googleapis.com \ --project=${PROJECT_ID}

<PROJECT_ID>替换为你自己的 Google Cloud 项目 ID,REGION可按需修改。

步骤 3:创建 GKE Autopilot 集群并获取凭证

gcloud container clusters create-auto online-boutique \ --project=${PROJECT_ID} --region=${REGION}

create-auto创建的是 GKE Autopilot 集群(无需手动管理节点池),创建过程通常需要几分钟。

步骤 4:部署应用

仓库根目录提供了由所有服务清单合并生成、可直接应用的发布文件:

kubectl apply -f ./release/kubernetes-manifests.yaml

该文件由 release/kubernetes-manifests.yaml 提供,内部包含 frontend、cartservice、checkoutservice、currencyservice、emailservice、loadgenerator、paymentservice、productcatalogservice、recommendationservice、shippingservice 以及配套的redis-cart数据库等全部资源。

步骤 5:等待 Pod 就绪

kubectl get pods

几分钟后所有 Pod 应处于Running状态,输出类似:

NAME READY STATUS RESTARTS AGE adservice-76bdd69666-ckc5j 1/1 Running 0 2m58s cartservice-66d497c6b7-dp5jr 1/1 Running 0 2m59s checkoutservice-666c784bd6-4jd22 1/1 Running 0 3m1s currencyservice-5d5d496984-4jmd7 1/1 Running 0 2m59s emailservice-667457d9d6-75jcq 1/1 Running 0 3m2s frontend-6b8d69b9fb-wjqdg 1/1 Running 0 3m1s loadgenerator-665b5cd444-gwqdq 1/1 Running 0 3m paymentservice-68596d6dd6-bf6bv 1/1 Running 0 3m productcatalogservice-557d474574-888kr 1/1 Running 0 3m recommendationservice-69c56b74d4-7z8r5 1/1 Running 0 3m1s redis-cart-5f59546cdd-5jnqf 1/1 Running 0 2m58s shippingservice-6ccc89f8fd-v686r 1/1 Running 0 2m58s

步骤 6:通过前端外部 IP 访问

kubectl get service frontend-external | awk '{print $4}'

在浏览器访问http://EXTERNAL_IP即可打开 Online Boutique 页面(如果输出<pending>,说明云负载均衡器仍在创建,稍等几分钟后重试)。

部署成功后的商店首页运行效果(图片来源 docs/img/online-boutique-frontend-1.png)

步骤 7:清理集群

实验完成后删除 GKE 集群(同样需要几分钟):

gcloud container clusters delete online-boutique \ --project=${PROJECT_ID} --region=${REGION}

部署变体:Kustomize 定制体系

默认部署只是起点。README 指出,可以通过 kustomize/ 目录下的组件体系部署不同变体(如启用 Cloud Operations 链路追踪、接入 Istio 服务网格等)。这些变体以Kustomize component的形式组织,可以像搭积木一样自由组合,详见 kustomize/README.md。

Kustomize 基础用法

进入kustomize/目录后,先预览默认配置生成的清单(不会实际部署):

kubectl kustomize .

确认无误后应用:

kubectl apply -k .

同样等待所有 Pod 变为Running,然后用kubectl get service frontend-external | awk '{print $4}'获取访问地址。

官方提供的部署变体

kustomize/components/ 下已经实现了一批开箱即用的组件:

  • cymbal-branding:把整套 UI 换成 Google Cloud 虚拟公司 Cymbal Shops 的品牌,为frontend增加CYMBAL_BRANDING环境变量;
  • google-cloud-operations:为各服务启用 Monitoring/Tracing/Profiler(设置ENABLE_STATSENABLE_TRACING等环境变量),并附带 otel-collector.yaml 采集器配置;
  • memorystore:将购物车存储从集群内redis-cart换成 Google Cloud Memorystore(Redis),直接影响cartservice
  • spanner:将购物车存储换成 Cloud Spanner,同样影响cartservice
  • alloydb:将购物车存储换成 AlloyDB(PostgreSQL 兼容);
  • network-policies:为各服务部署细粒度的 NetworkPolicy,例如 network-policy-deny-all.yaml;
  • container-images-registry / container-images-tag / container-images-tag-suffix:批量改写镜像仓库名、镜像 tag 或追加 tag 后缀;
  • non-public-frontend:不对外暴露frontend
  • single-shared-session:让frontend只维护一个共享会话;
  • service-mesh-istio:部署 Istio 服务网格相关资源(网关、VirtualService 等);
  • shopping-assistant:接入 Gemini 驱动的 AI 购物助手,根据图片推荐商品,相关说明见 kustomize/components/shopping-assistant/README.md;
  • without-loadgenerator:去掉流量注入器。

如何组合变体

kustomize/目录下使用kustomize edit add component即可把组件加入 kustomize/kustomization.yaml,例如加入 Cymbal 品牌组件:

kustomize edit add component components/cymbal-branding

也可以手动编辑kustomization.yaml,在components:字段下追加组件路径。基础资源定义在 kustomize/base/kustomization.yaml,其中默认注释掉了loadgenerator(本地开发时由 skaffold 注入),并预留了全部可选组件的注释示例。仓库还提供了三种“全家桶”组合参考:kustomize/tests/memorystore-with-all-components/、kustomize/tests/service-mesh-istio-with-all-components/ 和 kustomize/tests/spanner-with-all-components/。

源码级深入:前端、商品目录与购物车存储

frontend:HTTP 网关与会话管理

src/frontend/main.go 是整套系统的入口:它监听 8080 端口,使用gorilla/mux注册路由(//product/{id}/cart/cart/checkout/setCurrency/logout/assistant/_healthz等),并通过mustMapEnv读取PRODUCT_CATALOG_SERVICE_ADDRCURRENCY_SERVICE_ADDRCART_SERVICE_ADDRRECOMMENDATION_SERVICE_ADDRSHIPPING_SERVICE_ADDRCHECKOUT_SERVICE_ADDRAD_SERVICE_ADDR等环境变量来发现各 gRPC 后端地址(即 Kubernetes 集群内的 Service DNS 名)。关键实现细节:

  • 会话机制:前端不要求注册登录,通过ensureSessionID中间件为每个用户自动生成shop_session-idcookie(有效期 48 小时),并支持shop_currencycookie 切换币种;
  • 探针支持/_healthz返回ok,kustomize/base/frontend.yaml 中为其配置了 readiness/liveness 探针,并携带shop_session-idCookie 以模拟真实请求;
  • 可观测性ENABLE_TRACING=1时通过 OpenTelemetry OTLP gRPC exporter 将 trace 上报到COLLECTOR_SERVICE_ADDRENABLE_PROFILER=1时启动 Cloud Profiler;
  • 路由中间件链logHandlerensureSessionIDotelhttp.NewHandler,依次完成日志、会话与追踪注入。

frontend-externalService 类型为LoadBalancer,对外暴露 80 端口并映射到容器的 8080。

productcatalogservice:JSON 商品目录

商品数据存放在 src/productcatalogservice/products.json,由 src/productcatalogservice/product_catalog.go 加载到内存。product_catalog.go 中ListProductsGetProduct(按 ID 精确匹配,查不到返回NotFound状态码)与SearchProducts(关键词大小写不敏感匹配)三个 RPC 均会注入extraLatency模拟网络延迟;配套测试见 product_catalog_test.go。

cartservice:可插拔的购物车存储

src/cartservice/src/cartstore/ 目录通过ICartStore接口抽象了购物车存储后端,目前内置三种实现:

  • RedisCartStore.cs:默认方案,对应部署中的redis-cart
  • SpannerCartStore.cs:对应 kustomize 的 spanner 组件;
  • AlloyDBCartStore.cs:对应 kustomize 的 alloydb 组件。

这正是 Online Boutique “演示云产品集成”的核心体现:同一个服务,通过切换存储实现即可对接不同托管数据库。服务入口见 src/cartservice/src/Program.cs,测试见 src/cartservice/tests/CartServiceTests.cs。

其他部署方式与文档

Terraform 部署

想要用基础设施即代码的方式部署,可参考 terraform/README.md。terraform/main.tf 定义了集群与应用资源,memorystore.tf 演示了如何同时创建 Memorystore 实例,其余变量定义在 variables.tf。

Istio / Cloud Service Mesh

接入 Istio 服务网格的完整说明见 kustomize/components/service-mesh-istio/README.md,网格资源(Gateway、VirtualService)位于 istio-manifests/ 与 kustomize/components/service-mesh-istio/,发布合并文件为 release/istio-manifests.yaml。

非 GKE 集群(Minikube、Kind 等)

本地或非 GKE 环境(如 Minikube、Kind)的部署与开发流程见 docs/development-guide.md,其中包含skaffold run等本地迭代方式(仓库根目录提供 skaffold.yaml);从零理解产品需求的背景可阅读 docs/product-requirements.md。

Gemini AI 购物助手

仓库还包含一个基于 Gemini 的可选微服务 shoppingassistantservice(源码在 src/shoppingassistantservice/),部署与使用方式见 kustomize/components/shopping-assistant/README.md。

小结

Online Boutique 用一个 11 微服务、5 种语言的电商应用,完整示范了gRPC 服务契约设计、Kubernetes 清单组织、Kustomize 组合式部署定制以及可插拔云数据库集成等现代云原生实践。无论你是想快速部署一套演示环境、学习微服务架构设计,还是研究 Istio/可观测性/托管数据库的接入方式,都可以以 README.md 为入口、以 protos/demo.proto 为地图,逐层深入这套质量极高的开源样例。

【免费下载链接】microservices-demoSample cloud-first application with 10 microservices showcasing Kubernetes, Istio, and gRPC.项目地址: https://gitcode.com/GitHub_Trending/mi/microservices-demo

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询