首页 > 其他分享 >TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用

TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用

时间:2024-05-25 21:34:30浏览次数:14  
标签:TypeScript 架构 res app req 笔记 user const id

TypeScript 学习笔记(十一):TypeScript 与微服务架构的结合应用

1. 引言

在前几篇学习笔记中,我们探讨了 TypeScript 的基础知识、前后端框架的结合应用、测试与调试技巧、数据库以及 GraphQL 的结合应用。本篇将重点介绍 TypeScript 与微服务架构的结合应用,包括如何使用 TypeScript 构建和管理微服务,以及如何确保微服务之间的通信和数据一致性。

2. 什么是微服务架构

微服务架构是一种软件架构风格,将一个大而复杂的应用程序分解为多个小的、独立的服务。这些服务可以独立部署和扩展,并通过轻量级的通信协议(通常是 HTTP/REST 或消息队列)进行通信。微服务架构有助于提高系统的灵活性、可扩展性和可维护性。

3. 使用 TypeScript 构建微服务

TypeScript 可以用于构建和管理微服务,使得代码更加类型安全和可维护。以下是一个使用 TypeScript 构建微服务的示例。

3.1 安装必要的依赖

首先,安装必要的依赖,包括 Express、TypeScript 以及其他相关库。

npm install express body-parser
npm install typescript ts-node @types/express @types/node --save-dev
3.2 配置 TypeScript

在项目根目录下创建 tsconfig.json 文件,配置 TypeScript。

{
  "compilerOptions": {
    "target": "ES6",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./dist"
  },
  "include": ["src"]
}
3.3 创建微服务

创建一个简单的用户微服务,包括用户的 CRUD 操作。

// src/index.ts
import express from 'express';
import bodyParser from 'body-parser';

const app = express();
app.use(bodyParser.json());

interface User {
  id: number;
  name: string;
  email: string;
}

let users: User[] = [];
let nextId = 1;

app.get('/users', (req, res) => {
  res.json(users);
});

app.get('/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (user) {
    res.json(user);
  } else {
    res.status(404).send('User not found');
  }
});

app.post('/users', (req, res) => {
  const newUser: User = {
    id: nextId++,
    name: req.body.name,
    email: req.body.email,
  };
  users.push(newUser);
  res.status(201).json(newUser);
});

app.put('/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (user) {
    user.name = req.body.name;
    user.email = req.body.email;
    res.json(user);
  } else {
    res.status(404).send('User not found');
  }
});

app.delete('/users/:id', (req, res) => {
  users = users.filter(u => u.id !== parseInt(req.params.id));
  res.status(204).send();
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`User service running on port ${PORT}`);
});
3.4 运行微服务

使用 ts-node 运行 TypeScript 代码。

npx ts-node src/index.ts

4. 微服务之间的通信

微服务通常通过 HTTP/REST、消息队列或 gRPC 进行通信。以下是一个使用 HTTP/REST 和消息队列的示例。

4.1 使用 HTTP/REST 进行通信

我们可以创建另一个微服务,例如订单服务,通过 HTTP/REST 与用户服务进行通信。

// src/orderService.ts
import express from 'express';
import bodyParser from 'body-parser';
import axios from 'axios';

const app = express();
app.use(bodyParser.json());

interface Order {
  id: number;
  userId: number;
  product: string;
  quantity: number;
}

let orders: Order[] = [];
let nextOrderId = 1;

app.get('/orders', (req, res) => {
  res.json(orders);
});

app.post('/orders', async (req, res) => {
  const userId = req.body.userId;
  try {
    const userResponse = await axios.get(`http://localhost:3000/users/${userId}`);
    if (userResponse.status === 200) {
      const newOrder: Order = {
        id: nextOrderId++,
        userId,
        product: req.body.product,
        quantity: req.body.quantity,
      };
      orders.push(newOrder);
      res.status(201).json(newOrder);
    } else {
      res.status(400).send('Invalid user ID');
    }
  } catch (error) {
    res.status(500).send('Error communicating with user service');
  }
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Order service running on port ${PORT}`);
});
4.2 使用消息队列进行通信

消息队列(如 RabbitMQ、Kafka)是另一种常见的微服务通信方式。以下是一个使用 RabbitMQ 的示例。

4.2.1 安装 RabbitMQ 客户端

首先,安装 RabbitMQ 客户端库 amqplib

npm install amqplib
4.2.2 发布和订阅消息

在用户服务中发布消息,在订单服务中订阅消息。

// src/userService.ts
import express from 'express';
import bodyParser from 'body-parser';
import amqp from 'amqplib/callback_api';

const app = express();
app.use(bodyParser.json());

interface User {
  id: number;
  name: string;
  email: string;
}

let users: User[] = [];
let nextId = 1;

app.post('/users', (req, res) => {
  const newUser: User = {
    id: nextId++,
    name: req.body.name,
    email: req.body.email,
  };
  users.push(newUser);
  amqp.connect('amqp://localhost', (error0, connection) => {
    if (error0) {
      throw error0;
    }
    connection.createChannel((error1, channel) => {
      if (error1) {
        throw error1;
      }
      const queue = 'user_created';
      const msg = JSON.stringify(newUser);

      channel.assertQueue(queue, {
        durable: false
      });
      channel.sendToQueue(queue, Buffer.from(msg));
      console.log(" [x] Sent %s", msg);
    });
  });
  res.status(201).json(newUser);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`User service running on port ${PORT}`);
});
// src/orderService.ts
import express from 'express';
import bodyParser from 'body-parser';
import amqp from 'amqplib/callback_api';

const app = express();
app.use(bodyParser.json());

interface Order {
  id: number;
  userId: number;
  product: string;
  quantity: number;
}

let orders: Order[] = [];
let nextOrderId = 1;

amqp.connect('amqp://localhost', (error0, connection) => {
  if (error0) {
    throw error0;
  }
  connection.createChannel((error1, channel) => {
    if (error1) {
      throw error1;
    }
    const queue = 'user_created';

    channel.assertQueue(queue, {
      durable: false
    });
    console.log(" [*] Waiting for messages in %s", queue);

    channel.consume(queue, (msg) => {
      if (msg !== null) {
        const user = JSON.parse(msg.content.toString());
        console.log(" [x] Received %s", user);
        // Handle the user created event
        // For example, create a welcome order
        const newOrder: Order = {
          id: nextOrderId++,
          userId: user.id,
          product: 'Welcome Kit',
          quantity: 1,
        };
        orders.push(newOrder);
        console.log(" [x] Created welcome order for user %s", user.id);
      }
    }, {
      noAck: true
    });
  });
});

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
  console.log(`Order service running on port ${PORT}`);
});

5. 服务发现与负载均衡

在微服务架构中,服务发现与负载均衡是重要的组件,帮助管理服务实例的动态注册和流量分发。

5.1 服务发现

服务发现用于动态注册和发现服务实例,常用的工具有 Consul、etcd 和 Eureka。

5.1.1 安装 Consul

安装 Consul 并启动服务。

brew install consul
consul agent -dev
5.1.2 注册服务

在微服务中注册到 Cons

ul。

// src/userService.ts
import consul from 'consul';

const consulClient = new consul();
const serviceId = 'user-service-' + process.pid;

consulClient.agent.service.register({
  id: serviceId,
  name: 'user-service',
  address: 'localhost',
  port: 3000,
  check: {
    http: 'http://localhost:3000/health',
    interval: '10s'
  }
}, (err) => {
  if (err) {
    console.error('Failed to register service:', err);
  } else {
    console.log('Service registered with Consul');
  }
});

// 健康检查
app.get('/health', (req, res) => {
  res.send('OK');
});
5.2 负载均衡

负载均衡可以使用 Nginx、HAProxy 等工具来分发请求流量。

6. 结论

在本篇学习笔记中,我们探讨了 TypeScript 与微服务架构的结合应用,包括如何使用 TypeScript 构建微服务、微服务之间的通信、服务发现与负载均衡。通过掌握这些知识,你可以在实际项目中更好地利用 TypeScript 构建和管理微服务架构,提升系统的灵活性和可维护性。

下一篇学习笔记将介绍 TypeScript 与 DevOps 的结合应用,包括持续集成、持续交付和部署,希望你能继续关注本系列的学习笔记,进一步提升 TypeScript 编程技能。

标签:TypeScript,架构,res,app,req,笔记,user,const,id
From: https://blog.csdn.net/u010986241/article/details/139186984

相关文章

  • TypeScript 学习笔记(十二):TypeScript 与 DevOps 的结合应用
    TypeScript学习笔记(十二):TypeScript与DevOps的结合应用1.引言在前几篇学习笔记中,我们探讨了TypeScript的基础知识、前后端框架的结合应用、测试与调试技巧、数据库、GraphQL以及微服务架构的结合应用。本篇将重点介绍TypeScript与DevOps的结合应用,包括如何在D......
  • [论文笔记] Conversing with Copilot: Exploring Prompt Engineering for Solving CS1
    Abstract:Copilot及其他辅助编程的人工智能模型被广泛使用,这篇文章探索了Copilot在哪些任务上表现不佳,prompt在过程中的作用等几个问题。Introduction:Question1:Copilot在CS1programmingproblems上的表现如何?Question2:当Copilot最初失败后,prompt的修改如何......
  • 【计算理论】【《计算理论导引(原书第3版)》笔记】第〇章:绪论
    文章目录@[toc]第〇章:绪论0.1|自动机、可计算性与复杂性计算复杂性理论可计算性理论自动机理论0.2|数学概念和术语集合关系等价关系图简单路径连通图圈强连通图字符串和语言字母表上的字符串空串......
  • 论文笔记:Inf-DiT: Upsampling Any-Resolution Image with Memory-Efficient Diffusion
    论文链接:[2405.04312]Inf-DiT:UpsamplingAny-ResolutionImagewithMemory-EfficientDiffusionTransformer(arxiv.org)论文代码:THUDM/Inf-DiT:OfficialimplementationofInf-DiT:UpsamplingAny-ResolutionImagewithMemory-EfficientDiffusionTransformer(gi......
  • Vue3实战笔记(43)—Vue3组合式API下封装可复用ECharts图表组件
    文章目录前言一、封装echart图标钩子二、使用步骤总结前言接上文,已经安装好了ECharts,开始封装组件方便使用。一、封装echart图标钩子首先应用我们之前学习的钩子方式,在hooks目录下创建一个名为useECharts.js的文件,用于封装ECharts的逻辑:import{ref,onMo......
  • 英语学习笔记25——Mrs. Smith‘s kitchen
    Mrs.Smith’skitchen史密斯太太的厨房词汇VocabularyMrs.夫人【已婚】复习:Mr.先生+全名/姓Mrs.夫人+全名/丈夫的姓Miss小姐(未婚)+全名/姓Ms.女士+全名/姓查看婚姻状况,可以观察对方戒指。kitchenn.厨房发音类似:chicken......
  • 第二周 架构
    第二周总结各系统版本的zabbix安装。常用安装:包安装、二进制安装、源码编译安装、docker容器安装如果需要中文建议现在linux安装中文包:#CentOS安装中文包,再修改语言,否则无法选择[root@zabbix-server~]#yum-yinstalllangpacks-zh_CN#Ubuntu安装下面中文包[root@zabb......
  • 第三周 架构
    第三周1、在两台服务器上安装kvm虚拟化,把其中一台的虚拟机迁移到另一台。冷迁移虚拟机:将一个宿主机的处于关机状态的虚拟机迁移到另一台宿主机,注意:不支持Ubuntu和Rocky8宿主机之间迁移#在一台目标宿主机安装相关虚拟化软件[root@ubuntu2004~]#aptupdate[root@ubuntu2004......
  • 《拯救大学生课设不挂科第二期之Windows11下安装VC6.0(VC++6.0)与跑通Hello World C语言
    背景与目标人群:大学第一次学C语言的时候,大部分老师会选择VC6这个编辑器。但由于很多人是新手,第一次上大学学C语言。老师要求VC6.0(VC++6.0)写C语言跑程序可能很多人还是第一次接触电脑。需要安装VC6这个编辑器并且编译C语言程序,但是不怎么会装。博主结合自己当时学习与现在......
  • STM32F103C8T6独立看门狗学习笔记
    /*------------操作说明-------------------键寄存器IWDG_PR寄存器地址0x40003000初始值0X000000000X00005555解除对IWDG_PR、IWDG_RLR和IWDG_WINR寄存器的写入访问保护0X0000CCCC启动独立看门狗0X0000AAAA喂狗......