当前位置: 首页 > news >正文

Nestjs 微服务实战 - 动态微服务创建链接

所有的微服务都需要做服务治理

服务治理包括(配置中心、服务发现、注册服务等等),常见的包括 Java 的 Nacos,这里不关注与服务治理,只说明,如何用 nest 网关,并且在网关层动态实现微服务注入

nestjs 官网的案例明显是偏向于手动注册微服务的,例如:

/** Model */
@Module({imports: [/** Model 中使用并注册 */ ClientsModule.register([{ name: 'MATH_SERVICE', transport: Transport.TCP },]),]...
});/** service / controller 使用 */
constructor(/** 通过 @Inject 装饰器只能挨个进行倒入,有多少服务倒入多少 */@Inject('MATH_SERVICE') private client: ClientProxy,
) {}

以上属于官网列出的例子,对于真正的微服务开发肯定是不够用的,因为服务并没有根据配置中心的配置进行动态变更倒入,这种情况下,假如某个服务很占用 CPU、内存导致荡机了,也无法进行动态扩展,只能去重启服务手动更改配置,而我需要的是完全动态,每个服务部署都独立部署出来,对于高CPU的服务进行动态扩展服务器,进行自动切换 ip 端口线路。

首先所有的服务都不要在 Model 中进行注册,建议全丢在 service / controller 中使用,我这里以 controller 为例:

import { All, Controller, Req, Res } from '@nestjs/common';
import { ClientProxyFactory, Transport } from '@nestjs/microservices';
import { createProxyServer } from 'http-proxy';/** 动态数组,这里后面要通过定时任务去配置中心拉取 */
const serviceList = [{name: 'user-center',host: '127.0.0.1',port: 65531,},
];@Controller()
export class AppController {/** 首先所有路由不管任何请求方式全部代理到这个方法上 */@All('*')async root(@Req() req, @Res() res): Promise<any> {/** 获取所有可获取的参数 */const { method, originalUrl, query, body, headers } = req;/** 根据 url 字符串切割一下获取,主要获取第一级和第二级路由 */const list = originalUrl.split('?')[0].split('/').filter((item: string) => item !== '');/** 所有,开头为 /api 的参数,并且路由大于并且等于 2 级以上的,基本都可以调用微服务 */if (list.length >= 2 && list[0] === 'api') {/** 微服务真正的地址,是三级路径 */const path = `/${list.slice(2).join('/')}`;/** 服务名称是二级目录 */const service = list[1];/** 查找服务名称是否存在 */const server = serviceList.find((item) => item.name === service);/** 服务存在 */if (server) {/** 错误执行 */const errorNext = (err: string) => {/** 地址错误 */if (err === 'There is no matching message handler defined in the remote service.') {/** 手动关闭服务链接 */this[service].close();/** 清楚链接,下次链接如果服务可用就触发重新链接 */this[service] = undefined;res.status(404);res.send({code: -1,msg: '地址错误',});} else {console.log(`其他错误: ${err}`);}};/** 当前 class 中找不到服务,需要创建服务 */if (!this[service]) {/** 动态创建服务链接 */this[service] = ClientProxyFactory.create({transport: Transport.TCP,options: {host: server.host,port: server.port,},});try {/** 链接服务 */await this[service].connect();/** 发送消息*/const data = this[service].send(/** 服务的接口地址是 { method = 请求方法, path = 等于相对路径 }  */{ method, path },/** 把所有 http 的参数全部传递过去,让那边服务自己判断处理 */{ query, body, headers },);/** 接受流消息 */data.subscribe({/** 成功执行 next */next: (_res_: any) => {res.status(200);res.send(_res_);},/** 失败吧错误信息丢个 errorNext */error: (err: any) => errorNext(err),});} /** 服务存在,但是可能荡机了,又或者服务正在重启过程中 */ catch (err) {/** 手动关闭服务链接 */this[service].close();/** 清楚链接,下次链接如果服务可用就触发重新链接 */this[service] = undefined;res.status(503);res.send({code: -1,msg: '当前服务正在维护中',});}} /** 服务已存在 */ else {/** 发送消息*/const data = this[service].send(/** 服务的接口地址是 { method = 请求方法, path = 等于相对路径 }  */{ method, path },/** 把所有 http 的参数全部传递过去,让那边服务自己判断处理 */{ query, body, headers },);/** 接受流消息 */data.subscribe({/** 成功执行 next */next: (_res_: any) => {res.status(200);res.send(_res_);},/** 失败吧错误信息丢个 errorNext */error: (err: any) => errorNext(err),});}} /** 未找到服务 */ else {res.status(404);res.send({code: -1,msg: '未找到对应的服务',});}} /** 反向代理到 admin 地址 */ else if (list.length >= 2 && list[0] === 'admin') {const proxy = createProxyServer({target: 'http://127.0.0.1:4000',changeOrigin: true,});proxy.on('error', () => {res.status(503);res.send({code: -1,msg: '当前服务正在维护中',});});proxy.web(req, res);} /** 反向代理到 nuxt ssr 前端页面地址 */ else {const proxy = createProxyServer({target: 'http://127.0.0.1:5000',changeOrigin: true,});proxy.on('error', () => {res.status(503);res.send({code: -1,msg: '当前服务正在维护中',});});proxy.web(req, res);}}
}

以上是我的核心逻辑部分,主要逻辑应该是一下步骤,

/** 1、创建服务 */
const proxy = ClientProxyFactory.create({transport: Transport.TCP,options: {host: '127.0.0.1',port: 65531,},
});/** 2、服务连接 */
await proxy.connect();/** 3、发送消息 */
const data = this[service].send(消息接口,附加数据,
);/** 4、接受流消息 */
data.subscribe({/** 成功消息 */next: (_res_: any) => {res.status(200);res.send(_res_);},/** 排错 */error: (err: any) => {},
});

相关文章:

Nestjs 微服务实战 - 动态微服务创建链接

所有的微服务都需要做服务治理 服务治理包括&#xff08;配置中心、服务发现、注册服务等等&#xff09;&#xff0c;常见的包括 Java 的 Nacos&#xff0c;这里不关注与服务治理&#xff0c;只说明&#xff0c;如何用 nest 网关&#xff0c;并且在网关层动态实现微服务注入 …...

K8S部署pod状态CreateContainerConfigError问题解决

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

PyTorch 简单易懂的实现 CosineSimilarity 和 PairwiseDistance - 距离度量的操作

目录 torch.nn子模块Distance Functions解析 nn.CosineSimilarity 功能 主要参数 输入和输出的形状 使用示例 nn.PairwiseDistance 功能 主要参数 输入和输出的形状 使用示例 总结 torch.nn子模块​​​​​​​Distance Functions解析 nn.CosineSimilarity torc…...

app加载不到aar中的so库

如何将so文件打入到aar包中 1 在main下面新建jniLibs目录并将so放进去 2 在android{}中添加 sourceSets {main {jniLibs.srcDir file(jni/)}}app引用不到aar中的so文件(巨坑&#xff0c;不去查谁知道啊) 在aar 的manifeset application标签中中添加 android:extractNativeLi…...

vue-springboot基于java的实验室安全考试系统

本系统为用户而设计制作实验室安全考试系统&#xff0c;旨在实现实验室安全考试智能化、现代化管理。本实验室安全考试管理自动化系统的开发和研制的最终目的是将实验室安全考试的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的…...

mysql+关掉密码过期

mysql关掉密码过期 要在MySQL中关闭密码过期功能&#xff0c;可以按照以下步骤进行操作&#xff1a; 登录到MySQL服务器。 使用管理员账户&#xff08;如root&#xff09;连接到数据库。 mysql -uroot -ppassword 运行以下命令来查看当前的密码过期设置&#xff1a; SHOW…...

实际项目中的环形缓冲区

在实际项目中&#xff0c;环形缓冲区的设计要比之前讲到的原型稍微复杂一些&#xff0c;需要一些接口函数来实现数据结构封装。GitHub上有个大帅哥写了一个轻量的环形缓冲区库&#xff0c;可以学习参考&#xff0c;也可以直接集成到自己的项目中&#xff0c;功能已经非常完善。…...

输出回文数-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第23讲。 输出回文数&#…...

内存溢出会导致模块测试正常,植入系统失败

前些天&#xff0c;遇到了一个问题&#xff1a;需要在系统中添加一个小功能&#xff0c;单独测试&#xff0c;然后植入系统。 代码使用了从网上下载的函数&#xff0c;模块单独运行&#xff0c;没有问题&#xff0c;但是放在系统中运行就会出问题。 不得已的情况下&#xff0c…...

【taro react】 ---- QRCode 二维码生成

1. 需求分析 需要将输入的值转换为图片资源;由于只是单纯的展示,所以不需要很多比如加 logo 等复杂功能;不需要后端生成,直接前端操作;使用的第三方库尽可能小,功能单一;最后选择使用 qrcode-generator 库,只有 40kb。2. 使用第三方库 qrcode-generator 3. 转换 base…...

rk3566 armbian修复usb2.0并挂载U盘

文章目录 usb接口修复一 执行命令二 修改rk3566-panther-x2.dts⽂件三 查看是否识别 U盘格式化、挂载一 U盘格式化1.1 查看U盘1.2 查看U盘文件系统类型1.3 格式化为ext4系统 二 挂载U盘2.1 手动挂载2.2 自动挂载&#xff08;可选&#xff09; usb接口修复 一 执行命令 将位于…...

猫头虎博主第9期赠书活动:《YOLO目标检测》计算机AI视觉实战YOLO人工智能目标检测与跟踪图像处理深度学习图像检测书籍

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…...

python 如何将英语单词翻译成中文

要将英语单词翻译成中文&#xff0c;可以使用 Python 的第三方库 googletrans。该库使用 Google Translate 提供的 API 来进行翻译。 首先&#xff0c;需要安装 googletrans 库。可以使用以下命令在终端或命令提示符中安装&#xff1a; pip install googletrans4.0.0-rc1然后…...

Linux_CentOS_7.9_MySQL_5.7配置数据库服务开机自启动之简易记录

前言&#xff1a; 作为运维保障&#xff0c;都无法准确预估硬件宕机的突发阶段&#xff0c;其生产数据实时在产出&#xff0c;那作为dba数据库服务的其重要性、必要性就突显而出。这里拿虚拟机试验做个配置记录&#xff0c;便于大家学习参考。 # 如出现服务器重启后登入报错无…...

js实现拖动盒子查看内容 内容拖动

一.分析实现过程 1.鼠标拖动的操作是&#xff0c;按下鼠标不松&#xff0c;拖动鼠标&#xff0c;就需要监听鼠标点击事件(onmousedown),鼠标拖动事件(onmousemove) 2.鼠标拖动事件的监听时机&#xff0c;是在按下鼠标之后监听的&#xff0c;所以鼠标拖动事件需要放在鼠标按下事…...

[C#]winform利用seetaface6实现C#人脸检测活体检测口罩检测年龄预测性别判断眼睛状态检测

【官方框架地址】 https://github.com/ViewFaceCore/ViewFaceCore 【算法介绍】 SeetaFace6是由中国科技公司自主研发的一款人脸识别技术&#xff0c;它基于深度学习算法&#xff0c;能够快速、准确地识别出人脸&#xff0c;并且支持多种应用场景&#xff0c;如门禁系统、移动…...

c++ execl 执行 重定向

#include <unistd.h>int main() {pid_t childPid fork(); // 创建子进程if (childPid 0) {// 子进程// 关闭标准输入、输出和错误流close(STDIN_FILENO);close(STDOUT_FILENO);close(STDERR_FILENO);// 打开要写入的文件int fd open("output.txt", O_WRONLY…...

uni-app中实现元素拖动

uni-app中实现元素拖动 1、代码示例 <template><movable-area class"music-layout"><movable-view class"img-layout" :x"x" :y"y" direction"all"><img :src"musicDetail.bgUrl" :class&…...

Java系列-Class.forName和ClassLoader.loadClass的区别

Class.forName 和 ClassLoader.loadClass 是 Java 中两种加载类的方式&#xff0c;它们的主要区别在于加载类的时机和对异常的处理。 1.Class.forName Class.forName 是一个静态方法&#xff0c;用于在运行时加载类。它返回一个 Class 对象&#xff0c;但在加载类的过程中&am…...

找不到模块 “path“ 或其相对应的类型声明

src别名的配置 在开发项目的时候文件与文件关系可能很复杂&#xff0c;因此我们需要给src文件夹配置一个别名 // vite.config.ts import {defineConfig} from vite import vue from vitejs/plugin-vue import path from path export default defineConfig({plugins: [vue()],r…...

厘米级无感定位 + 毫秒级动态重建,镜像视界破解智造虚实脱节难题

厘米级无感定位 毫秒级动态重建&#xff0c;镜像视界破解智造虚实脱节难题植根数字孪生与视频孪生核心赛道&#xff0c;镜像视界&#xff08;浙江&#xff09;科技有限公司依托自研视频原生空间智能技术体系&#xff0c;以厘米级无感定位与毫秒级动态重建两大核心技术能力&…...

机器学习在资产管理中的应用:从数据到投资组合的端到端框架

1. 项目概述&#xff1a;当机器学习遇见资产管理如果你在资产管理行业待过&#xff0c;或者对量化投资感兴趣&#xff0c;那你肯定不止一次想过&#xff1a;那些复杂的市场数据、财报、新闻&#xff0c;能不能让机器来帮我们分析&#xff0c;甚至做出决策&#xff1f;firmai/ma…...

射频非线性建模:从S参数到X参数与NVNA的工程实践

1. 非线性星期三&#xff1a;一场射频工程师的“大信号”狂欢如果你是一名射频或微波电路设计工程师&#xff0c;对S参数、负载牵引、谐波失真这些词感到既熟悉又头疼&#xff0c;那么十多年前在巴尔的摩举行的国际微波研讨会&#xff08;IMS 2011&#xff09;上&#xff0c;有…...

OnmyojiAutoScript:阴阳师自动化脚本终极指南,20+日常任务一键托管解放双手

OnmyojiAutoScript&#xff1a;阴阳师自动化脚本终极指南&#xff0c;20日常任务一键托管解放双手 【免费下载链接】OnmyojiAutoScript Onmyoji Auto Script | 阴阳师脚本 项目地址: https://gitcode.com/gh_mirrors/on/OnmyojiAutoScript 还在为阴阳师中重复繁琐的日常…...

LLM长文本处理实战:模块化分割策略与向量化预处理指南

1. 项目概述&#xff1a;一个为LLM打造的文本处理中心如果你和我一样&#xff0c;经常和大型语言模型打交道&#xff0c;无论是用它来总结文档、分析代码&#xff0c;还是处理客服对话&#xff0c;那你肯定遇到过这个痛点&#xff1a;喂给模型的文本太长了怎么办&#xff1f;模…...

【最新版】Windows 环境OpenClaw 本地 AI 智能体搭建指南

OpenClaw&#xff08;小龙虾&#xff09;Windows 一键部署保姆级教程&#xff5c;10 分钟搭建数字员工 在开源 AI 智能体快速普及的当下&#xff0c;OpenClaw&#xff08;小龙虾&#xff09;凭借本地运行 零代码操控 自动执行任务的能力&#xff0c;收获大量用户关注&#x…...

从亚投行高大幕墙钢架设计谈幕墙结构变形设计

从亚投行高大幕墙钢架设计谈幕墙结构变形设计 【摘 要】   幕墙变形设计是幕墙设计时一个非常重要的考虑要素,它是决定幕墙结构设计质量的关键因素。本文以亚洲基础建设投资银行总部大楼项目南北中厅立面高大幕墙钢架设计为例,从宏观、中观和微观三个维度分析与其连接的主…...

工程师的调试礼仪:如何避免一次问候毁掉两小时工作成果

1. 项目概述&#xff1a;一次关于“Bug礼仪”的职场博弈在硬件开发的深水区&#xff0c;尤其是在产品临近交付的冲刺阶段&#xff0c;工程师与管理者之间的互动&#xff0c;往往比电路板上的信号完整性更考验“设计”。这不是一个关于具体芯片型号或调试命令的技术教程&#xf…...

利用Taotoken模型广场为不同AI应用场景挑选合适模型

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 利用Taotoken模型广场为不同AI应用场景挑选合适模型 面对文本生成、代码审查、智能对话、翻译等多样化的AI应用场景&#xff0c;如…...

BioClaw:基于自然语言对话的生物信息学智能分析平台

1. 项目概述&#xff1a;BioClaw&#xff0c;一个能聊天的生物信息学工具箱 如果你是一名生物医学领域的研究者&#xff0c;我猜你对下面这个场景一定不陌生&#xff1a;你刚拿到一批测序数据&#xff0c;需要先跑个FastQC看看质量&#xff1b;同时&#xff0c;实验室的师弟在…...