Node js 微服务架构:如何构建灵活的应用程序
由于对现代和可扩展应用程序的需求激增,微服务的流行也获得了同样的动力。这一切都归功于使之成为可能的高效编程语言。一些组织已经利用Node js 微服务来构建应用程序,例如 Netflix、沃尔玛、PayPal 和 Trello。
现在,为什么这些组织选择使用 Node.js 的微服务,以及它如何使您受益,本文将助您一臂之力。
此博客展示了使用 NodeJs 为您的应用程序构建微服务的好处。在进入 node js 微服务教程之前,让我们先了解一下微服务。
了解 Node js 微服务架构及其工作原理
微服务是一种应用程序架构,可将复杂的应用程序分解为单一的、可管理的服务。它是一种软件架构方法,其中独立的组件相互通信以提供高效的功能。
每个服务都通过定义明确的 API 与其他服务交互。每个微服务都与使构建和管理应用程序更易于访问的明确目的松散耦合。
微服务允许敏捷地开发、测试和部署服务,使每个服务独立运行。
NodeJs 中的单体服务与微服务
此外,微服务作为旧的单体系统的解决方案出现。单体系统与微服务相反,因为它是一个具有所有功能的单元。简单来说,它是一个单一的程序,负责执行应用程序的所有部分和服务。
因此,单体应用程序修改起来既费时又复杂,而微服务可以轻松修改。
在开发强大的应用程序时,Node js 通常是一个不错的选择。NodeJs 是一个事件驱动的 JavaScript 框架,旨在处理异步 I/O 和管理大量流量。
通过集成Node.js 微服务架构,您可以创建快速、易于管理且灵活的动态应用程序。
为什么在 Node.js 中使用微服务?
Node Js 的快速、响应能力和弹性使其成为构建需要快速响应请求和处理错误的微服务的绝佳选择。此外,通过利用微服务和 Node js 的优势,您可以有效地匹配您的用户和业务需求。
使用 Node js 和微服务的好处
以下是将 Nodejs 微服务架构用于软件或应用程序开发服务的众多好处。
🟠 增强的可扩展性
使用微服务 NodeJs 通过将应用程序分解为小而独立的组件来提高应用程序的可扩展性。Node js 是一种理想的技术,因为它是事件驱动架构和非阻塞 I/O 模型。使用 Nodejs 中的微服务,您可以同时管理大量大型请求。
🟠 多样化的技术
微服务架构允许高效的技术多样性,从而为复杂应用程序的构建和管理增加价值。在 Node Js 中使用微服务,您可以通过实现不同的服务和方法来进行快速更改。通过不同的技术和小组件,它更容易与其他系统集成。
🟠 Increase Resilience
微服务可以独立开发和部署,因此您可以修改和更新单个服务而不会影响应用程序的其余部分。此外,每个服务都会处理故障并立即恢复。Nodejs 具有内置的错误处理机制,有助于开发更具弹性的微服务。
🟠 资源分配
使用 Node js 微服务,您可以根据项目或服务的特定要求轻松分配资源。例如,如果服务需要更多的处理内存或进程,您可以在那个时候分配它。此外,这将有助于节省资源、优化资源并降低成本。
🟠 更好的性能
通过分解和使用强大的技术,您可以为应用程序利用高效的性能。在不影响其余应用程序的情况下,更容易推出更改、修复错误和更快地优化服务。达到特定要求将改善整体响应时间和应用程序性能。
带有 Node.js 示例的微服务
在此演示应用程序中,我们将使用连接到外部 API 的 NodeJS 构建微服务。
该应用程序将提供三种服务:Book、Customer 和 Order 服务。每个服务都将有单独的服务器在不同的端口上运行。这些服务将通过 REST API 相互通信。我们都知道,如果不是微服务架构,我们将只有一台服务器在运行。但是,在微服务架构中,情况有所不同。
所以,这就是我们在本教程中构建的内容,让我们从编码部分开始吧。
准备好简化您的运营并提高您的底线了吗?
立即联系我们聘请 Node js 开发人员,开始构建能够处理最繁忙工作负载的微服务。
在 Node.js 中构建微服务
第 1 步:初始设置
确保安装了 Node.js。如果您的系统没有 Node.js,请访问Nodejs.org下载最新的 Node 版本。
跑步npm 初始化在项目根文件夹中。这将创建一个 package.json 文件,该文件将创建有关包的某些问题,如果您不确定如何响应,可以使用默认值。
我们将使用四个包,Express、mongoose、axios 和 dotenv,它们可以按如下方式安装:
$ npm install express mongoose axios dotenv --save
项目结构
项目结构请参考下图。结构因人而异。
第 2 步:创建数据库连接
让我们从建立数据库连接的基本步骤开始。在db文件夹下,创建一个db.js来编码连接数据库。这只是一个小的演示应用程序,但大型复杂的应用程序也有用于各个服务的不同数据库。
// 数据库.js
const mongoose = require('猫鼬');mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
使用统一拓扑:真,
使用查找和修改:错误,
使用创建索引:true}).then(() => {
console.log('连接成功!');}).catch((e) => {
console.log('连接失败!');})
在db.js中,我们需要一个mongoose包来连接 MongoDB 数据库。
函数connect()将接受两个参数—— uri 和 options。
第 3 步:创建图书服务
为 Book 服务创建一个 Book 文件夹,在 Book 文件夹中,我们将创建Book.js来创建 Book 模型。
// 图书.js
const mongoose = require('猫鼬');const bookSchema = mongoose.Schema({
标题: {
类型:字符串,
要求:真实
},
作者: {
类型:字符串,
要求:真实
},
页数:{
类型:数字,
要求:假
},
出版商:{
类型:字符串,
要求:假
}})const Book = mongoose.model("book", bookSchema);module.exports = 书;
现在我们需要为 Book 服务创建一个服务器。
为图书服务创建服务器
在 Book 文件夹中创建books.js 。由于我们正在学习构建微服务,因此我们将拥有不同的服务服务器。
// 书籍.js
要求(“dotenv”).config();const express = require('快递');// 连接要求('../db/db');const Book = require('./Book');const app = express();常量端口= 3000;app.use(express.json())app.post('/book', (req, res) => {
const newBook = new Book({...req.body});
newBook.save().then(() => {
res.send('新书添加成功!')
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
})})app.get('/books', (req, res) => {
Book.find().then((books) => {
如果(书籍。长度!== 0){
res.json(书籍)
} 别的 {
res.status(404).send('找不到书');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.get('/book/:id', (req, res) => {
Book.findById(req.params.id).then((book) => {
如果(书){
res.json(书籍)
} 别的 {
res.status(404).send('找不到书');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.delete('/book/:id', (req, res) => {
Book.findOneAndRemove(req.params.id).then((book) => {
如果(书){
res.json('图书删除成功!')
} 别的 {
res.status(404).send('找不到书!');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});});app.listen(端口, () => {
console.log(`在端口 ${port} 上启动并运行 - 这是图书服务`);})
我们已经使用 express 来创建服务器,制作了连接数据库所需的 db 文件,以及 Book 模型来存储数据以提高Node 性能。
图书服务有四种路线:
添加书籍
从数据库中获取所有书籍
得到一本特定的书
删除一本书
在3000 端口运行 book 服务。
第 4 步:创建客户服务
为客户服务创建一个 Customer 文件夹,在 Customer 文件夹中,我们将有Customer.js作为模型,就像我们在上一节中为 Book 服务所做的那样。
// 客户.js
const mongoose = require('猫鼬');const CustomerSchema = mongoose.Schema({
姓名: {
类型:字符串,
要求:真实
},
年龄: {
类型:数字,
要求:真实
},
地址: {
类型:字符串,
要求:真实
}})const Customer = mongoose.model("客户", CustomerSchema);module.exports = 客户;
现在我们需要为客户服务创建一个服务器。
为客户服务创建服务器
我们还将为客户服务提供单独的服务器。创建一个名为customer.js的文件。
// 客户.js
要求(“dotenv”).config();const express = require('快递');// 连接要求('../db/db');const Customer = require('./Customer');const app = express();常量端口= 5000;app.use(express.json())app.post('/customer', (req, res) => {
const newCustomer = new Customer({...req.body});
newCustomer.save().then(() => {
res.send('新客户创建成功!');
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
})})app.get('/customers', (req, res) => {
Customer.find().then((客户) => {
如果(客户){
res.json(客户)
} 别的 {
res.status(404).send('未找到客户');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.get('/customer/:id', (req, res) => {
Customer.findById(req.params.id).then((客户)=>{
如果(客户){
res.json(客户)
} 别的 {
res.status(404).send('未找到客户');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.delete('/customer/:id', (req, res) => {Customer.findByIdAndRemove(req.params.id).then((customer) => {
如果(客户){
res.json('客户删除成功!')
} 别的 {
res.status(404).send('找不到客户!');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});});app.listen(端口, () => {
console.log(`在端口 ${port} 上启动并运行 - 这是客户服务`);})
为客户服务创建与我们为图书服务所做的相同的四个路由
在端口 5000运行客户服务。
第五步:创建订单服务
在模型的 Order 文件夹中创建一个Order.js 文件,就像我们为 Book 和 Customer service 所做的那样。
// 订单.js
const mongoose = require('猫鼬');const orderSchema = mongoose.Schema({
客户ID: {
类型:mongoose.SchemaTypes.ObjectId,
要求:真实
},
书号:{
类型:mongoose.SchemaTypes.ObjectId,
要求:真实
},
初始日期:{
类型:日期,
要求:真实
},
交货日期: {
类型:日期,
要求:假
}})const Order = mongoose.model("order", orderSchema);module.exports = 订单;
现在我们需要为订单服务创建一个服务器。
为订单服务创建服务器
在 Order 文件夹中创建 order.js。
// 订单.js
要求(“dotenv”).config();const express = require('快递');const mongoose = require("猫鼬");const axios = require('axios');// 连接要求('../db/db');const Order = require('./Order');const app = express();常量端口= 9000;app.use(express.json())app.post('/order', (req, res) => {
const newOrder = 新订单({
customerID: mongoose.Types.ObjectId(req.body.customerID),
bookID: mongoose.Types.ObjectId(req.body.bookID),
初始日期:req.body.initialDate,
交货日期:req.body.deliveryDate});newOrder.save().then(() => {
res.send('新订单添加成功!')
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
})})app.get('/订单', (req, res) => {
Order.find().then((订单) => {
如果(订单){
res.json(订单)
} 别的 {
res.status(404).send('未找到订单');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.get('/order/:id', (req, res) => {
Order.findById(req.params.id).then((order) => {
如果(订单){
axios.get(`http://localhost:5000/customer/${order.customerID}`).then((response) => {
让 orderObject = {
客户名称:response.data.name,
书名: ''
}
axios.get(`http://localhost:3000/book/${order.bookID}`).then((response) => {
orderObject.BookTitle = response.data.title
res.json(orderObject);
})
})
} 别的 {
res.status(404).send('未找到订单');
}
}).catch((错误) => {
res.status(500).send('内部服务器错误!');
});})app.listen(端口, () => {
console.log(`在端口 ${port} 上启动并运行 - 这是订单服务`);})
在端口 9000运行客户服务。
我们将在订单服务中创建三个路由:
添加订单。您需要为其传递bookId、customerId、initialDate 和 deliveryDate 。
从数据库中获取所有订单
获取特定订单的客户和预订详细信息。
要运行最后一条路线,请确保所有服务都在后台运行。因为我们也从图书服务和客户服务中获取详细信息。
因此,这是使用 Node.js 构建微服务的分步指南。完整的源代码可以在这里找到:nodejs-microservices-example
结论
因此,NodeJ 中的微服务非常适合开发应用程序。此外,它是理想的,因为两者具有相同的方法和目的:增长更快和更具可扩展性的应用程序。
在微服务中使用 Node js 允许您以多种方法和技术开发软件应用程序。在微服务中使用 Nodejs,您可以修改和更新任何更改,而不会影响任何进程。
我们希望您访问本教程的目的达到了您的预期。如果您想在下一个项目中利用 Nodejs 微服务的优势,您可以聘请 Nodejs 开发人员来开发灵活的应用程序。