NodeJS 基于 Dapr 构建云原生微服务应用,从 0 到 1 快速上手指南

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。Dapr 确保开发人员专注于编写业务逻辑,不必分神解决分布式系统难题,从而显著提高了生产力。Dapr 降低了构建微服务架构类现代云原生应用的门槛。

image

Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。Dapr 确保开发人员专注于编写业务逻辑,不必分神解决分布式系统难题,从而显著提高了生产力。Dapr 降低了构建微服务架构类现代云原生应用的门槛。

系列

安装 Dapr CLI

MacOS & Dapr 1.8:

sudo curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash

image

Linux/Windows 安装方式:

本地环境中初始化 Dapr

Dapr 初始化包括:

  1. 运行一个用于状态存储和消息代理的 Redis 容器实例
  2. 运行一个用于提供可观察性的 Zipkin 容器实例
  3. 创建具有上述组件定义的默认组件文件夹
  4. 运行用于本地 actor(我们的服务) 支持的 Dapr placement 服务容器实例

运行初始化 CLI 命令

dapr init

验证 Dapr 版本

dapr -v
CLI version: 1.8.0
Runtime version: 1.8.0

验证容器是否正在运行

如前所述,dapr init 命令会启动几个容器,这些容器将帮助您开始使用 Dapr。 验证您有运行 daprio/dapropenzipkin/zipkinredis 映像的容器实例:

image

验证组件目录是否已初始化

dapr init 上,CLI 还会创建一个默认组件文件夹,其中包含几个 YAML 文件,其中包含状态存储、Pub/subZipkin 的定义。Dapr sidecar 将读取这些组件并使用:

  • 用于状态管理和消息传递的 Redis 容器。
  • 用于收集踪迹的 Zipkin 容器。

通过打开您的组件目录进行验证:

  • Windows, 在 %UserProfile%\.dapr
  • Linux/MacOS, 在 ~/.dapr
ls $HOME/.dapr
bin components config.yaml

使用 Dapr API

运行 Dapr sidecar 并试用 state API

运行 Dapr sidecar

dapr run 命令启动一个应用程序,以及一个 sidecar。

启动一个 Dapr sidecar,它将在端口 3500 上侦听名为 myapp 的空白应用程序:

dapr run --app-id myapp --dapr-http-port 3500

由于没有使用上述命令定义自定义组件文件夹,因此 Dapr 使用在 dapr init 流程期间创建的默认组件定义。

保存状态

使用对象更新状态。新状态将如下所示:

[
  {
    "key": "name",
    "value": "Bruce Wayne"
  }
]

请注意,包含在状态中的每个对象都有一个分配有值为 namekey。您将在下一步中使用该 key

使用以下命令保存新的状态对象:

curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne"}]' http://localhost:3500/v1.0/state/statestore

获取状态

使用带有 key 为 name 的状态检索您刚刚存储在 state 中的对象。在同一终端窗口中,运行以下命令:

curl http://localhost:3500/v1.0/state/statestore/name

查看状态如何存储在 Redis 中

docker exec -it dapr_redis redis-cli

列出 Redis 键以查看 Dapr 如何使用您提供给 dapr run 的 app-id 作为 key 的前缀创建键值对:

keys *
"myapp||name"

运行以下命令查看状态值:

hgetall "myapp||name"

1) "data"
2) "\"Bruce Wayne\""
3) "version"
4) "1"

使用以下命令退出 Redis CLI:

exit

删除状态

在同一终端窗口中,从状态存储中删除 name 状态对象。

curl -v -X DELETE -H "Content-Type: application/json" http://localhost:3500/v1.0/state/statestore/name

上手实战指南

所有官方示例笔者均在 MacOS/NodeJs v16.16.0 下实战完成。

1. 服务调用

使用 Dapr 的服务调用构建块,您的应用程序可以与其他应用程序可靠且安全地通信。

image

示例仓库

git clone https://github.com/dapr/quickstarts.git

运行 order-processor 服务

从 quickstarts 的根目录导航到 order-processor 目录。

cd service_invocation/javascript/http/order-processor

安装依赖项:

npm install

与 Dapr sidecar 一起运行 order-processor 服务。

dapr run --app-port 5001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- npm start
app.post('/orders', (req, res) => {
    console.log("Order received:", req.body);
    res.sendStatus(200);
});

运行 checkout 服务

在新的终端窗口中,从 quickstarts 根目录导航到 checkout 目录。

cd service_invocation/javascript/http/checkout

安装依赖项:

npm install

与 Dapr sidecar 一起运行 checkout 服务。

dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 -- npm start

checkout 服务中,您会注意到无需重写您的应用程序代码即可使用 Dapr 的服务调用。您可以通过简单地添加 dapr-app-id header 来启用服务调用,该 header 指定目标服务的 ID。

let axiosConfig = {
  headers: {
      "dapr-app-id": "order-processor"
  }
};
const res = await axios.post(`${DAPR_HOST}:${DAPR_HTTP_PORT}/orders`, order , axiosConfig);
console.log("Order passed: " + res.config.data);

查看服务调用输出

Dapr 在任何 Dapr 实例上调用应用程序。在代码中,sidecar 编程模型鼓励每个应用程序与其自己的 Dapr 实例通信。Dapr 实例随后发现并相互通信。

checkout & order-processor 服务输出:

image

2. 状态管理

image

让我们看一下 Dapr 的状态管理构建块。您将使用 Redis 进行状态存储,来保存、获取和删除你的状态,您也可以将其换成任何一种受 Dapr 支持的状态存储。

操纵服务状态

在终端窗口中,导航到 order-processor 目录。

cd state_management/javascript/sdk/order-processor

安装依赖项,其中将包括 JavaScript SDK 中的 dapr-client 包:

npm install

验证您在服务目录中包含以下文件:

  • package.json
  • package-lock.json

与 Dapr sidecar 一起运行 order-processor 服务。

dapr run --app-id order-processor --components-path ../../../components/ -- npm run start

order-processor 服务将 orderId key/value 写入、读取和删除到 statestore.yaml 组件中定义的 statestore 实例。一旦服务启动,它就会执行一个循环。

  const client = new DaprClient(DAPR_HOST, DAPR_HTTP_PORT);

  // 将 state 保存到 state store 中
  client.state.save(STATE_STORE_NAME, [
      {
          key: orderId.toString(),
          value: order
      }
  ]);
  console.log("Saving Order: ", order);

  // 从 state store 中获取 state
  var result = client.state.get(STATE_STORE_NAME, orderId.toString());
  result.then(function(val) {
      console.log("Getting Order: ", val);
  });

  // 从 state store 中删除 state
  client.state.delete(STATE_STORE_NAME, orderId.toString());    
  result.then(function(val) {
      console.log("Deleting Order: ", val);
  });

查看 order-processor 输出

请注意,正如上面代码中所指定的,代码将应用程序状态保存在 Dapr 状态存储中,读取它,然后将其删除

Order-processor 输出:

image

statestore.yaml 组件文件

当你运行 dapr init 时,Dapr 会创建一个默认的 Redis statestore.yaml 并在你的本地机器上运行一个 Redis 容器,它位于:

  • Windows,%UserProfile%\.dapr\components\statestore.yaml
  • Linux/MacOS ,~/.dapr/components/statestore.yaml

使用 statestore.yaml 组件,您可以轻松切换状态存储,而无需更改代码。

本快速入门包含的 Redis statestore.yaml 文件包含以下内容:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""
  - name: actorStateStore
    value: "true"

在 YAML 文件中:

  • metadata/name 是您的应用程序与组件对话的方式(在代码示例中称为 DAPR_STORE_NAME)。
  • spec/metadata 定义到组件使用的 Redis 实例的连接。

3. 发布和订阅

image

开始使用 Dapr 的发布和订阅构建块

让我们看一下 Dapr 的发布和订阅 (Pub/sub) 构建块。您将运行发布者微服务和订阅者微服务,以演示 Dapr 如何启用发布/订阅模式。

  1. 使用发布服务,开发人员可以重复发布消息到 topic。
  2. Pub/sub 组件对这些消息进行排队或代理。我们下面的示例使用 Redis,您可以使用 RabbitMQ、Kafka 等。
  3. 该 topic 的订阅者从队列中提取消息并处理它们。

订阅 topic

在终端窗口中,从 quickstarts 根目录导航到 order-processor 目录。

cd pub_sub/javascript/sdk/order-processor

安装依赖项,其中将包括 JavaScript SDK 中的 dapr-client 包:

npm install

验证您在服务目录中包含以下文件:

  • package.json
  • package-lock.json

与 Dapr sidecar 一起运行 order-processor subscriber 服务。

dapr run --app-port 5001 --app-id order-processing --app-protocol http --dapr-http-port 3501 --components-path ../../../components -- npm run start

在 order-processor 订阅者中,我们订阅名为 order_pub_sub 的 Redis 实例(如 pubsub.yaml 组件中所定义)和 topic orders。这使您的应用程序代码能够通过 Dapr sidecar 与 Redis 组件实例通信。

server.pubsub.subscribe("order_pub_sub", "orders", (data) => console.log("Subscriber received: " + JSON.stringify(data)));

发布 topic

在新的终端窗口中,从 Quickstarts 克隆目录的根目录导航到 checkout 目录。

cd pub_sub/javascript/sdk/checkout

安装依赖项,其中将包括 JavaScript SDK 中的 dapr-client 包:

npm install

验证您在服务目录中包含以下文件:

  • package.json
  • package-lock.json

与 Dapr sidecar 一起运行 checkout 发布者服务。

dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 --components-path ../../../components -- npm run start

checkout 发布者服务中,我们将 orderId 消息发布到名为 order_pub_sub 的 Redis 实例(在 pubsub.yaml 组件中定义)和 topic orders。服务一启动,就会循环发布:

const client = new DaprClient(DAPR_HOST, DAPR_HTTP_PORT);

await client.pubsub.publish(PUBSUB_NAME, PUBSUB_TOPIC, order);
   console.log("Published data: " + JSON.stringify(order));

查看发布/订阅输出

请注意,正如上面代码中所指定的,发布者将一个随机数推送到 Dapr sidecar,而订阅者接收它。

发布者 & 订阅者输出:

image

pubsub.yaml 组件文件

当你运行 dapr init 时,Dapr 会创建一个默认的 Redis pubsub.yaml 并在你的本地机器上运行一个 Redis 容器,它位于:

  • 在 Windows 上,在 %UserProfile%\.dapr\components\pubsub.yaml
  • 在 Linux/MacOS 上,在 ~/.dapr/components/pubsub.yaml

使用 pubsub.yaml 组件,您可以轻松更换底层组件,而无需更改应用程序代码。

本快速入门包含的 Redis pubsub.yaml 文件包含以下内容:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: order_pub_sub
spec:
  type: pubsub.redis
  version: v1
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: ""

在 YAML 文件中:

  • metadata/name 是您的应用程序与组件对话的方式。
  • spec/metadata 定义与组件实例的连接。
  • scopes 指定哪个应用程序可以使用该组件。

4. 输入和输出绑定

image

开始使用 Dapr 的 Binding 构建块

让我们看一下 Dapr 的 Bindings 构建块。使用绑定,您可以:

  • 使用来自外部系统的事件触发您的应用程序。
  • 与外部系统的接口。

接下来您将使用输入 Cron binding 安排批处理脚本每 10 秒运行一次。该脚本使用 PostgreSQL Dapr binding 处理 JSON 文件并将数据输出到 SQL 数据库。

在本地运行 PostgreSQL Docker 容器

在您机器上的 Docker 容器中本地运行 PostgreSQL 实例。示例包含一个 Docker Compose 文件,用于在本地自定义、构建、运行和初始化带有默认 orders 表的 postgres 容器。

在终端窗口中,从 quickstarts 根目录导航到 bindings/db 目录。

cd bindings/db

运行以下命令来设置容器:

docker compose up

image

安排一个 Cron job 并写入数据库

在新的终端窗口中,导航到 SDK 目录。

cd bindings/javascript/sdk/batch

安装依赖项:

npm install

与 Dapr sidecar 一起运行 batch-sdk 服务。

dapr run --app-id batch-sdk --app-port 5002 --dapr-http-port 3500 --components-path ../../../components -- node index.js 

process_batch 函数内的代码每 10 秒执行一次(在 components 目录的 binding-cron.yaml 中定义)。绑定触发器在 Dapr sidecar 的 Flask 应用程序中查找通过 HTTP POST 调用的路由。

async function start() {
    await server.binding.receive(cronBindingName,processBatch);
    await server.start();
}

batch-sdk 服务使用 binding-postgres.yaml 组件中定义的 PostgreSQL 输出绑定将 OrderId、Customer 和 Price 记录插入到 orders 表中。

async function processBatch(){
    const loc = '../../orders.json';
    fs.readFile(loc, 'utf8', (err, data) => {
        const orders = JSON.parse(data).orders;
        orders.forEach(order => {
            let sqlCmd = `insert into orders (orderid, customer, price) values (${order.orderid}, '${order.customer}', ${order.price});`;
            let payload = `{  "sql": "${sqlCmd}" } `;
            console.log(payload);
            client.binding.send(postgresBindingName, "exec", "", JSON.parse(payload));
        });
        console.log('Finished processing batch');
      });
    return 0;
}

查看 job 的输出

请注意,如上所述,代码使用 OrderId、Customer 和 Price 作为 payload 调用输出绑定。

你的输出绑定的 print 语句输出:

image

在新终端中,验证是否已将相同的数据插入到数据库中。

cd bindings/db

启动交互式 Postgres CLI:

docker exec -i -t postgres psql --username postgres  -p 5432 -h localhost --no-password

admin=# 提示符下,更改为 orders 表:

\c orders;

orders=# 提示符下,选择所有行:

select * from orders;

输出应如下所示:

image

components\binding-cron.yaml 组件文件

当您执行 dapr run 命令并指定组件路径时,Dapr sidecar:

  • 启动 Cron 绑定构建块
  • 每 10 秒调用一次绑定端点(批处理)

binding-cron.yaml 文件包含以下内容:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: cron
  namespace: quickstarts
spec:
  type: bindings.cron
  version: v1
  metadata:
  - name: schedule
    value: "@every 10s"

注意:binding-cron.yaml 的元数据部分包含一个 Cron 表达式,用于指定调用绑定的频率。

component\binding-postgres.yaml 组件文件

当您执行 dapr run 命令并指定组件路径时,Dapr sidecar:

  • 启动 PostgreSQL 绑定构建块
  • 使用 binding-postgres.yaml 文件中指定的设置连接到 PostgreSQL

使用 binding-postgres.yaml 组件,您可以轻松换出后端数据库绑定,而无需更改代码。

本快速入门包含的 PostgreSQL binding-postgres.yaml 文件包含以下内容:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: sqldb
  namespace: quickstarts
spec:
  type: bindings.postgres
  version: v1
  metadata:
  - name: url
    value: "user=postgres password=docker host=localhost port=5432 dbname=orders pool_min_conns=1 pool_max_conns=10"

在 YAML 文件中:

  • spec/type 指定 PostgreSQL 用于此绑定。
  • spec/metadata 定义到组件使用的 PostgreSQL 实例的连接。

5. Secrets 管理

开始使用 Dapr 的 Secrets Management 构建块

Dapr 提供了一个专用的 secrets API,允许开发人员从 secrets store 中检索 secrets。接下来:

  1. 运行带有 secret 存储组件的微服务。
  2. 在应用程序代码中使用 Dapr secrets API 检索 secrets。

检索 secrets

在终端窗口中,导航到 order-processor 目录。

cd secrets_management/javascript/sdk/order-processor

安装依赖项:

npm install

与 Dapr sidecar 一起运行 order-processor 服务。

dapr run --app-id order-processor --components-path ../../../components/ -- npm start

在幕后

order-processor 服务

请注意下面的 order-processor 服务如何指向:

  • 在 local-secret-store.yaml 组件中定义的 DAPR_SECRET_STORE。
  • 在 secrets.json 中定义的 secret。
// index.js
const DAPR_SECRET_STORE = "localsecretstore";
const SECRET_NAME = "secret";

async function main() {
    // ...
    const secret = await client.secret.get(DAPR_SECRET_STORE, SECRET_NAME);
    console.log("Fetched Secret: " + JSON.stringify(secret));
}

local-secret-store.yaml 组件

DAPR_SECRET_STORE 定义在 local-secret-store.yaml 组件文件中,位于 secrets_management/components 中:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: localsecretstore
  namespace: default
spec:
  type: secretstores.local.file
  version: v1
  metadata:
  - name: secretsFile
    value: secrets.json
  - name: nestedSeparator
    value: ":"

在 YAML 文件中:

  • metadata/name 是您的应用程序引用组件的方式(在代码示例中称为 DAPR_SECRET_STORE)。
  • spec/metadata 定义与组件使用的 secret 的连接。

secrets.json 文件

SECRET_NAME 在位于 secrets_management/javascript/sdk/order-processorsecrets.json 文件中定义:

{
    "secret": "YourPasskeyHere"
}

查看 order-processor 输出

正如上面的应用程序代码中所指定的,order-processor 服务通过 Dapr secret 存储检索 secret 并将其显示在控制台中。

image

6. 官方示例仓库(源码)

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3天前
|
运维 Kubernetes Cloud Native
云原生技术:容器化与微服务架构的完美结合
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术以其灵活性和高效性成为企业的新宠。本文将深入探讨云原生的核心概念,包括容器化技术和微服务架构,以及它们如何共同推动现代应用的发展。我们将通过实际代码示例,展示如何在Kubernetes集群上部署一个简单的微服务,揭示云原生技术的强大能力和未来潜力。
|
5天前
|
运维 Kubernetes Docker
利用Docker和Kubernetes构建微服务架构
利用Docker和Kubernetes构建微服务架构
|
1天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
15 5
|
2天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
14 5
|
2天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####
|
2天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
2天前
|
Cloud Native API 持续交付
云原生之旅:从容器到微服务的演进之路
【10月更文挑战第39天】在这篇文章中,我们将一起探索云原生技术的奥秘。通过浅显易懂的语言和生动的比喻,我们将了解云原生技术如何改变软件开发的世界。文章将带领读者从容器的基本概念出发,逐步深入到微服务架构的实践,揭示这些技术如何助力现代应用的快速迭代与可靠部署。准备好,让我们启程进入云原生的精彩世界吧!
|
2天前
|
JSON JavaScript API
深入浅出Node.js:从零开始构建RESTful API
【10月更文挑战第39天】 在数字化时代的浪潮中,API(应用程序编程接口)已成为连接不同软件应用的桥梁。本文将带领读者从零基础出发,逐步深入Node.js的世界,最终实现一个功能完备的RESTful API。通过实践,我们将探索如何利用Node.js的异步特性和强大的生态系统来构建高效、可扩展的服务。准备好迎接代码和概念的碰撞,一起解锁后端开发的新篇章。
|
5天前
|
Kubernetes Cloud Native Ubuntu
庆祝 .NET 9 正式版发布与 Dapr 从 CNCF 毕业:构建高效云原生应用的最佳实践
2024年11月13日,.NET 9 正式版发布,Dapr 从 CNCF 毕业,标志着云原生技术的成熟。本文介绍如何使用 .NET 9 Aspire、Dapr 1.14.4、Kubernetes 1.31.0/Containerd 1.7.14、Ubuntu Server 24.04 LTS 和 Podman 5.3.0-rc3 构建高效、可靠的云原生应用。涵盖环境准备、应用开发、Dapr 集成、容器化和 Kubernetes 部署等内容。
27 5
|
4天前
|
Kubernetes Cloud Native Docker
云原生技术探索:容器化与微服务的实践之道
【10月更文挑战第36天】在云计算的浪潮中,云原生技术以其高效、灵活和可靠的特性成为企业数字化转型的重要推手。本文将深入探讨云原生的两大核心概念——容器化与微服务架构,并通过实际代码示例,揭示如何通过Docker和Kubernetes实现服务的快速部署和管理。我们将从基础概念入手,逐步引导读者理解并实践云原生技术,最终掌握如何构建和维护一个高效、可扩展的云原生应用。