<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>部署应用 on Apache Dubbo</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/</link><description>Recent content in 部署应用 on Apache Dubbo</description><generator>Hugo</generator><language>zh-cn</language><atom:link href="https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/index.xml" rel="self" type="application/rss+xml"/><item><title>部署 Istio 环境</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/istio/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/istio/</guid><description>&lt;p>相关示例：&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/mesh" target="_blank">dubbo-go-samples/mesh&lt;/a>。&lt;/p>
&lt;h2 id="1-准备工作">1. 准备工作&lt;/h2>
&lt;ul>
&lt;li>docker、helm、kubectl 环境已安装。&lt;/li>
&lt;li>已安装 &lt;code>dubbogo-cli&lt;/code> 及相关依赖工具。&lt;code>dubbogo-cli&lt;/code> 请从 dubbo-go 主仓库
&lt;a href="../../../tools/dubbogo-cli/">&lt;code>tools/dubbogo-cli&lt;/code>&lt;/a> 安装。&lt;/li>
&lt;/ul>
&lt;h2 id="2-部署-istio-环境">2. 部署 Istio 环境&lt;/h2>
&lt;ol>
&lt;li>使用helm 安装 istio 基础 CRD 和 istiod 组件。也可以参考 &lt;a href="https://istio.io/">Istio 文档&lt;/a> 使用 istioctl 安装。&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ helm repo add istio https://istio-release.storage.googleapis.com/charts
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ kubectl create namespace istio-system
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ helm install istio-base istio/base -n istio-system
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ helm install istiod istio/istiod --namespace istio-system
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ol start="2">
&lt;li>
&lt;p>删除istio 水平扩展资源&lt;/p>
&lt;p>*目前 dubbo-go 依赖单个 istiod 实例进行服务发现。&lt;/p>
&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ kubectl delete hpa istiod -n istio-system
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>安装完成后，可以在 istio-system 命名空间下看到一个 istiod pod 在正常运行。&lt;/p></description></item><item><title>Istio 环境部署 Dubbo-go 应用</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/deploy/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/deploy/</guid><description>&lt;p>在本章节中，我们将使用应用模板快速创建一组 Dubbo-go Server和 Client 端应用，部署在 Istio 集群中；观察、调试和验证服务发现和调用成功。&lt;/p>
&lt;p>对应的 mesh 示例见
&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/mesh" target="_blank">dubbo-go-samples/mesh&lt;/a>。&lt;/p>
&lt;h2 id="1-准备工作">1. 准备工作&lt;/h2>
&lt;ul>
&lt;li>已安装 &lt;code>dubbogo-cli&lt;/code> 及相关依赖工具。&lt;code>dubbogo-cli&lt;/code> 请从 dubbo-go 主仓库
&lt;a href="../../../tools/dubbogo-cli/">&lt;code>tools/dubbogo-cli&lt;/code>&lt;/a> 安装；&lt;code>grpc_cli&lt;/code> 仅在本地调试时需要。&lt;/li>
&lt;li>docker、helm、kubectl 环境已安装。（arm 机器需支持 docker buildx）&lt;/li>
&lt;li>&lt;a href="../istio/">任务【istio 环境部署】&lt;/a> 已完成&lt;/li>
&lt;/ul>
&lt;h2 id="2-开发-server-端-dubbo-go-应用">2. 开发 server 端 Dubbo-go 应用&lt;/h2>
&lt;h3 id="21-使用-dubbogo-cli-创建项目模板">2.1 使用 dubbogo-cli 创建项目模板&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-plain" data-lang="plain">&lt;span style="display:flex;">&lt;span>$ mkdir mesh-app-server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ cd mesh-app-server
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ dubbogo-cli newApp . 
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ tree .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>.
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── Makefile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── api
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── api.proto
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── build
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── Dockerfile
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── chart
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── app
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ ├── Chart.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ ├── templates
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ │ ├── _helpers.tpl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ │ ├── deployment.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ │ ├── service.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ │ └── serviceaccount.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ └── values.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── nacos_env
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── Chart.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ ├── templates
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ ├── _helpers.tpl
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ ├── deployment.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ │ └── service.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── values.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── cmd
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── app.go
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── conf
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>│ └── dubbogo.yaml
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── go.mod
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>├── go.sum
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>└── pkg
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> └── service
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> └── service.go
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>dubbogo-cli&lt;/code> 现在维护在 dubbo-go 主仓库的 &lt;code>tools/dubbogo-cli&lt;/code> 目录下，本文后续步骤都基于它生成的模板展开。&lt;/p></description></item><item><title>流量管理</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/traffic_management/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/traffic_management/</guid><description>&lt;p>在本节中，我们将延续上一个任务&lt;a href="../deploy/">【在 Istio 环境部署 Dubbo-go 应用】&lt;/a>。&lt;/p>
&lt;p>在之前的任务中，我们在集群中部署了一组 Dubbo-go Server和 Client 端应用，验证了服务发现和调用成功。在本节中，我们将创建新版本的 Server 端应用。通过配置 VirtualService 和 DestinationRule ，实现路由管理，和流量转移能力&lt;/p>
&lt;p>对应的流量治理部署清单见
&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/mesh/deploy/traffic" target="_blank">dubbo-go-samples/mesh/deploy/traffic&lt;/a>。&lt;/p>
&lt;h2 id="1-准备工作">1. 准备工作&lt;/h2>
&lt;ul>
&lt;li>已安装 &lt;code>dubbogo-cli&lt;/code> 及相关依赖工具。&lt;code>dubbogo-cli&lt;/code> 请从 dubbo-go 主仓库
&lt;a href="../../../tools/dubbogo-cli/">&lt;code>tools/dubbogo-cli&lt;/code>&lt;/a> 安装；&lt;code>grpc_cli&lt;/code> 仅在本地调试时需要。&lt;/li>
&lt;li>docker、helm、kubectl 环境已安装。（arm 机器需支持 docker buildx）&lt;/li>
&lt;li>任务&lt;a href="../deploy/">【在 Istio 环境部署 Dubbo-go 应用】&lt;/a>已完成&lt;/li>
&lt;/ul>
&lt;h2 id="2-开发多版本dubbo-go-应用">2. 开发多版本Dubbo-go 应用。&lt;/h2>
&lt;h3 id="21-使用-dubbogo-cli-创建另一个项目模板">2.1 使用 dubbogo-cli 创建另一个项目模板&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-bash" data-lang="bash">&lt;span style="display:flex;">&lt;span>$ dubbogo-cli newApp . 
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="22-开发和部署客户端-dubbo-go-应用-v2">2.2 开发和部署客户端 Dubbo-go 应用 v2：&lt;/h3>
&lt;h4 id="编写业务逻辑">编写业务逻辑&lt;/h4>
&lt;ul>
&lt;li>修改 package/service/service.go 的实现方法，返回版本号为 v2.0.0&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#93a1a1;background-color:#002b36;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-go" data-lang="go">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#268bd2">func&lt;/span> (s &lt;span style="color:#719e07">*&lt;/span>GreeterServerImpl) &lt;span style="color:#268bd2">SayHello&lt;/span>(ctx context.Context, in &lt;span style="color:#719e07">*&lt;/span>api.HelloRequest) (&lt;span style="color:#719e07">*&lt;/span>api.User, &lt;span style="color:#dc322f">error&lt;/span>) {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>	&lt;span style="color:#719e07">return&lt;/span> &lt;span style="color:#719e07">&amp;amp;&lt;/span>api.User{Name: &lt;span style="color:#2aa198">&amp;#34;Hello &amp;#34;&lt;/span> &lt;span style="color:#719e07">+&lt;/span> in.Name, Id: &lt;span style="color:#2aa198">&amp;#34;v2.0.0&amp;#34;&lt;/span>}, &lt;span style="color:#cb4b16">nil&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;ul>
&lt;li>
&lt;p>修改如下配置文件，使用xds协议作为注册中心，加载名为 GreeterServerImpl 的服务结构。&lt;/p></description></item><item><title>无代理服务网格</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/proxyless_service_mesh/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/proxyless_service_mesh/</guid><description>&lt;p>示例源码：&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/mesh" target="_blank">dubbo-go-samples/mesh&lt;/a>。&lt;/p>
&lt;h2 id="1-什么是-proxyless-service-mesh-无代理服务网格-">1. 什么是 Proxyless Service-Mesh (无代理服务网格) ?&lt;/h2>
&lt;h3 id="11-service-mesh-简析">1.1 Service Mesh 简析&lt;/h3>
&lt;p>Istio 是当今最流行的开源服务网格。它由控制平面和数据平面构成，其架构如下，图片摘自 &lt;a href="https://istio.io/">istio官网&lt;/a>&lt;/p>
&lt;p>&lt;img alt="使用 Istio 后" src="https://deploy-preview-3229--dubbo.netlify.app/imgs/docs3-v2/golang-sdk/concept/mesh/proxyless_service_mesh/service-mesh.svg">&lt;/p>
&lt;p>位于图中下半部分的控制平面负责配置、服务信息、证书等资源的下发。位于上半部分的数据平面关注业务之间的通信流量；传统服务网格通过代理的方式拦截所有的业务网络流量，代理需要感知到控制平面下发的配置资源，从而按照要求控制网络流量的走向。&lt;/p>
&lt;p>在 Istiod 环境中，其控制平面是一个名为 istiod 的进程，网络代理是 envoy 。istiod 通过监听 K8S 资源 例如Service、Endpoint 等，获取服务信息，并将这些资源统一通过 XDS 协议下发给位于数据平面的网络代理。envoy 是一个独立的进程，以 sidecar（边车）的形式伴随业务应用 Pod 运行，他与应用进程共用同一个主机网络，并通过修改路由表的方式，劫持业务应用的网络流量。&lt;/p>
&lt;p>Service Mesh 可以解决微服务场景下的众多问题，随着集群规模的扩大与业务复杂度的增长，基于原生 k8s 的容器编排方案将会难以应付，开发人员不得不面对巨大的服务治理挑战。而 Service Mesh 很好地解决了这一问题，它将服务治理需求封装在了控制平面与代理中，业务开发人员只需要关注于业务逻辑。在应用部署之后，只需要运维人员通过修改配置，即可实现例如故障恢复、负载均衡、灰度发布等功能，这极大地提高了研发和迭代效率。&lt;/p>
&lt;p>Istio 的 sidecar 通过容器注入的形式伴随业务应用进程的整个生命周期，对于业务应用是毫无侵入的，这解决了业务应用可迁移、多语言、基础架构耦合等问题。但这也带来了高资源消耗、请求时延增长的问题。&lt;/p>
&lt;p>Service 为服务治理提供了一个很好的思路，将基础架构与业务逻辑解耦，让应用开发人员只需关注业务。另一方面，由于 sidecar 的弊端，我们可以考虑使用 sdk 的形式，来替代 sidecar 支撑起数据平面。&lt;/p>
&lt;h3 id="12-proxyless-service-mesh">1.2 Proxyless Service-Mesh&lt;/h3>
&lt;p>无代理服务网格，是近几年提出的一个新的概念，isito、gRPC、brpc 等开源社区都在这一方向进行了探索和实践。无代理服务网格框架以 SDK 的形式被业务应用引入，负责服务之间的通信、治理。来自控制平面的配置直接下发至服务框架，由服务框架代替上述 sidecar 的功能。&lt;/p>
&lt;p>&lt;img alt="img" src="https://deploy-preview-3229--dubbo.netlify.app/imgs/docs3-v2/golang-sdk/concept/mesh/proxyless_service_mesh/894c0e52-9d34-4490-b49b-24973ef4aabc.png">&lt;/p>
&lt;p>服务框架（SDK）的主要能力可以概括为以下三点：&lt;/p>
&lt;ol>
&lt;li>对接控制平面，监听配置资源。&lt;/li>
&lt;li>对接应用，为开发者提供方便的接口。&lt;/li>
&lt;li>对接网络，根据资源变动，响应流量规则。&lt;/li>
&lt;/ol>
&lt;h3 id="13-proxyless-的优缺点">1.3 Proxyless 的优缺点&lt;/h3>
&lt;p>优点：&lt;/p></description></item><item><title>优雅停机</title><link>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/graceful_shutdown/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://deploy-preview-3229--dubbo.netlify.app/zh-cn/overview/mannual/golang-sdk/tutorial/deployment/graceful_shutdown/</guid><description>&lt;h1 id="优雅停机">优雅停机&lt;/h1>
&lt;p>示例源码：&lt;a href="https://github.com/apache/dubbo-go-samples/tree/main/graceful_shutdown" target="_blank">dubbo-go-samples/graceful_shutdown&lt;/a>。&lt;/p>
&lt;h2 id="1-背景">1. 背景&lt;/h2>
&lt;p>在发布新版本、扩缩容或迁移节点时，Kubernetes、systemd 或运维平台会终止旧实例并启动新实例。如果旧实例直接退出，注册中心、客户端连接池和上游流量之间会出现短暂的不一致：注册中心可能还没有推送摘除事件，上游请求也可能仍在处理中。对于高流量服务，这会带来连接断开、请求失败、超时重试和告警放大。&lt;/p>
&lt;p>Dubbo-go 的优雅停机用于在进程退出前完成摘流和请求排空，尽量保证：&lt;/p>
&lt;ul>
&lt;li>Provider 不再接收新的业务请求之前，先从注册中心反注册并通知长连接 Consumer。&lt;/li>
&lt;li>已经进入 Provider 的请求可以在超时时间内完成。&lt;/li>
&lt;li>Consumer 本身正在发出的下游调用可以在退出前拿到响应。&lt;/li>
&lt;li>资源销毁、端口释放和用户自定义回调按顺序执行。&lt;/li>
&lt;/ul>
&lt;h2 id="2-工作机制">2. 工作机制&lt;/h2>
&lt;p>一次 Dubbo-go 调用链路中，某个服务实例通常既是 Provider，也是 Consumer。因此优雅停机会同时处理服务提供端和服务消费端。&lt;/p>
&lt;h3 id="21-触发停机">2.1 触发停机&lt;/h3>
&lt;p>当应用收到 &lt;code>SIGTERM&lt;/code>、&lt;code>SIGINT&lt;/code> 等退出信号时，如果 &lt;code>dubbo.shutdown.internal-signal&lt;/code> 为 &lt;code>true&lt;/code>，Dubbo-go 会进入内置优雅停机流程。Kubernetes 删除 Pod、滚动发布、&lt;code>kubectl delete pod&lt;/code>、&lt;code>kill -TERM &amp;lt;pid&amp;gt;&lt;/code> 和终端 &lt;code>Ctrl+C&lt;/code> 都属于典型触发方式。&lt;/p>
&lt;blockquote>
&lt;p>不要使用 &lt;code>kill -9&lt;/code> 触发停机。&lt;code>SIGKILL&lt;/code> 无法被进程捕获，Dubbo-go 没有机会执行优雅停机流程。&lt;/p>
&lt;/blockquote>
&lt;h3 id="22-provider-侧流程">2.2 Provider 侧流程&lt;/h3>
&lt;p>Provider 侧目标是先摘流，再等待正在执行的请求完成。&lt;/p>
&lt;ol>
&lt;li>从注册中心反注册当前实例，触发 Consumer 端服务列表更新。&lt;/li>
&lt;li>对 Triple 长连接 Consumer 发送关闭通知，使 Consumer 可以尽快避开正在关闭的 Invoker。&lt;/li>
&lt;li>在 &lt;code>consumer-update-wait-time&lt;/code> 时间内继续接收请求，给客户端和注册中心事件传播留出窗口。&lt;/li>
&lt;li>在开启拒绝新请求前，在 &lt;code>step-timeout&lt;/code> 和 &lt;code>offline-request-window-timeout&lt;/code> 约束下等待 Provider 侧活跃请求数归零。&lt;/li>
&lt;li>进入拒绝新请求阶段，后续新请求会被拒绝或由自定义 &lt;code>reject-handler&lt;/code> 处理。&lt;/li>
&lt;li>销毁协议、关闭监听端口并释放资源。&lt;/li>
&lt;/ol>
&lt;p>&lt;code>offline-request-window-timeout&lt;/code> 主要用于高流量场景：当活跃请求暂时归零后，再观察一个短窗口。如果窗口内没有新的请求进入，就可以更安全地继续销毁资源。&lt;/p></description></item></channel></rss>