nodejs 中间件 反向代理 接口转发
背景
随着后端业务系统的增加,纵向需求不断扩展,一个业务系统已经无法满足需求了,衍生出多个业务系统,对外暴露的ip、端口就可能有多个,此时不方便外部接口调用,有些特殊行业客户出于安全性考虑不发提供多个对外端口,对外只能提供一个IP一个端口。
这时中间件就产生了!
概念
中间件是一种独立的系统软件服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源,中间件位于客户机服务器的操作系统之上,管理计算资源和网络通信。
一个统一过滤请求的中间层,这就是中间件。
用途
中间件常见的用途有:
- IP过滤
- 防爬虫
- 解析请求
- 合并接口
- 合并端口
- cookie处理
- 参数校验
- 权限校验
- 异常处理
- 负载均衡
- 反向代理
这样业务系统就可以关注点集中在业务层,隔离这些基础设施,让开发者专注于业务以提高开发效率。
技术选型
- 高并发
- 传输快
- 非阻塞(NIO)
常用的有nodejs、netty、go
案例demo
这里以nodejs为例,实现接口反向代理和合并端口功能
功能描述:
有两个业务系统:财务系统(financeSys)、用户系统(userSys),
分别部署到:
财务系统(financeSys):http://192.168.0.2/find
用户系统(userSys):http://192.168.0.3/login
对外暴露的接口分别是:
http://www.xxx.com/financeSys/find
http://www.xxx.com/userSys/login
对外暴露的接口格式为:http://www.xxx.com/系统名/业务URL,中间件系统根据请求地址的系统名来转发到对应的业务系统中
这时在www.xxx.com这个服务器上部署一个中间件,
收到http://www.xxx.com/financeSys/find的请求时转发到财务系统(financeSys)http://192.168.0.2/find
收到http://www.xxx.com/userSys/login的请求时转发到用户系统(userSys)http://192.168.0.3/login
架构图
Nodejs项目分析
- 使用的第三方框架
koa: 网络框架,用来搭建服务
koa2-proxy-middleware:反向代理处理框架
log4js:日志框架 - 配置转发的关系的映射文件
{"RequestLog": true, // 是否打印请求日志"ResponseLog": true, // 是否打印响应日志"ServerPort": 80, // 中间件服务端口,即对外暴露的接口端口"financeSys": "http://192.168.0.2", // 财务系统(financeSys)的转发地址"userSys": "http://192.168.0.3" // 用户系统(userSys)的转发地址
}
- 根据url中的系统名找到映射文件中配置的业务系统
如:/financeSys/find -> http://192.168.0.2
router: function(req) {const path = req.url;let pathArray = path.split("/");let projectContext = pathArray[1];// let suffix = path.substring(projectContext.length + 1, path.length);let serverUrl = config[projectContext];if (serverUrl != undefined && serverUrl != null) { // 配置文件已经配置转发路由let proxyServer = serverUrl;return proxyServer;} else { // 没有配置路由转发if (config.RequestLog) {logger.info("No Proxy Server!! path:" + path);}return {protocol: req.protocol,host: req.host,port: config.ServerPort};}}
- 重写业务url
如:/financeSys/find -> /find
pathRewrite: function(path, req) {let pathArray = path.split("/");let projectContext = pathArray[1];let suffix = path.substring(projectContext.length + 1, path.length);return suffix;}
- 打印请求/响应日志
onProxyReq: async function(proxyReq, req, res) {// 禁用缓存proxyReq.setHeader('Cache-Control', 'no-cache');// 标示接口赖在中间件proxyReq.setHeader('Interface-From', 'Middleware');if (config.RequestLog) {logger.info("---------------------------- Request ----------------------------");logger.info('URL:' + req.url);logger.info('Method:' + req.method);logger.info('Headers:' + JSON.stringify(req.headers));const responseBodyStr = await getBody(req)logger.info("Body:" + responseBodyStr);}},onProxyRes: async function(proxyRes, req, res) {if (config.ResponseLog) {logger.info("---------------------------- Response ----------------------------");logger.info("URL:" + req.url);const responseBodyStr = await getBody(proxyRes)logger.info("Body:" + responseBodyStr);}}
- 过滤某些请求不转发
app.use(async (ctx, next) => {let url = ctx.originalUrl;if (url != '/favicon.ico') {await next();} else {let resStr = JSON.stringify({})ctx.response.body = resStr;}
});
项目运行打包
- 安装nodejs,可以参考官网教程或菜鸟教程(https://www.runoob.com/nodejs/nodejs-tutorial.html)
- 下载源码解压
- 安装依赖,进入项目根目录,执行命令npm install
npm install
- 本地调试,可以使用Visual Studio/Visual Studio Code/WebStorm等ide打开,运行命令npm run start
npm run start
- 打包,运行命令npm run build,会在dist文件夹生成一个index.js文件
- 运行,在安装有nodejs环境的机器上运行打包生成的index.js文件,运行命令node index.js
node index.js
项目源码:https://codechina.csdn.net/it1/project-middleware.git
如果觉得可以就点个👍吧,欢迎粉丝收藏,土豪打赏,您的关注就是我们创作的动力!
读者有什么想看的相关技术篇章,欢迎评论留言!
QQ交流群:908058499
相关文章:

oneinstack
https://oneinstack.com/转载于:https://www.cnblogs.com/diyunpeng/p/9740895.html

最近在做托盘时,发现 CnTrayIcon1的OnClick 事件,不能被其它按钮来执行,蛋疼。...
比如: procedure TForm1.Button1Click(Sender: TObject);begin CnTrayIcon1.OnClick ; // 这句就是不能通过!!end; 有过路的高手,指点学生一下。谢谢转载于:https://www.cnblogs.com/hahy8008/p/6783614.html

Linux02-帮助手册
目录 一、man手册 1.1 man的基本使用 1.2 mandb更新文档 二、/usr/share/doc 三、access.redhat.com 门户 一、man手册 1.1 man的基本使用 man就是mannual的缩写,手册的意思。Linux的命令很多,参数选项更多,人脑一般是记不住的&…

ORB_SLAM2中Tracking线程
Tracking线程是ORB_SLAM2的主线程。在System.cc中,使用构造函数进行了初始化,开启了三个线程。 可执行程序—>System构造函数(初始化三个线程)—>处理输入的帧(TrackMonocular)—>调用Tracking线程…

selenium的基础知识点
from selenium import webdriver from scrapy.selector import Selector#模拟登陆 browser webdriver.Chrome(executable_pathChromedriver.exe) #路径是Chromedriver.exe的存放位置,windows下只要配置好这个环境就不需要了browser.get(http://w) #需要登陆的那个网…

iOS 直播专题2-音视频采集
从设备(手机)的摄像头、MIC中采集音频、视频的原始数据ios的音视频采集可以从AVFoundation框架里采集 视频采集 这里我们选取GPUImage来采集视频,因为这个框架集成了很多视频滤镜,例如美颜 采集流程: 摄像头采集视频代码 GPUImageVideoCamera.m // 从前摄像头或后摄像头…

bzoj 4871: [Shoi2017]摧毁“树状图”
4871: [Shoi2017]摧毁“树状图” Time Limit: 25 Sec Memory Limit: 512 MBSubmit: 53 Solved: 9[Submit][Status][Discuss]Description 自从上次神刀手帮助蚯蚓国增添了上千万人口(蚯口?),蚯蚓国发展得越来越繁荣了!…

Linux03-本地账户和组
目录 一、本地账户/etc/passwd 二、本地组/etc/group 三、切换账户su - 四、增删改本地账户useradd、userdel、usermod 五、账户默认配置文件/etc/login.defs 六、设置密码passwd(5)命令 七、增删改组groupadd、groupdel和groupmod 八、通过sudo以root身份运行命令 九…

ORB_SLAM2单目初始化策略
基本流程 单目初始化程序存储在Initializer.cc中 需要注意,对于双目/RGB-D相机,初始化时,由于可以直接获得相机的深度信息,因此无需求H/F,直接作为关键帧插入就行。 使用RANSACDLT求解H,RANSAC八点…

Powerdesigner逆向工程64位Oracle数据库
Powerdesigner老版本不支持64位Client,新版本弄不到破解码 解决方法,用Powerdesigner32位Oracle Clent访问64位Oracle Server 遇到的坑分享下 安装完64位的Oracle Server ,32位的 Oracle Clent默认的listener.ora文件有PROGRAM和ENVS这两个节点 Plsql(3…

运行jsp时,报错404
The origin server did not find a current reprsentation for the target resource or is not willing to disclose that one exists. 解决: 1. web.xml文件位置是否放错,应该放在WebContent/WEB-INF文件夹中 2. web.xml文件中是否有拼写错误࿰…

iOS 直播专题3-前置处理
前置处理 对视频添加美颜、水印、滤镜等对音频进行混音、消除环境音、声音特效等上一篇iOS 直播专题2-音视频采集提到视频采集采用的是GPUImage框架,这个框架集成了很多滤镜效果 这里主要介绍美颜、水印处理 处理流程: 美颜 这里的美颜效果用的是GPUImageBeautyFilter 功…

ORA-10873解决办法
今天,发现SAP系统的oracle数据库宕掉了。报错ORA-10873,经过查证解决该问题。记录一下,备忘。 一、问题 Oracle版本为12.1.0.2.0,在启动服务器后启动数据库startup,报错ORA-10873。 二、查证 到SAP Support Portal上…

ORB_SLAM2局部建图线程
局部建图线程入口:可执行程序在初始化三个线程的时候,在System.cc的构造函数中进入局部建图线程 mpLocalMapper new LocalMapping(mpMap, //指定使iomanipmSensorMONOCULAR); // TODO 为什么这个要设置成为MONOCULAR??&#…

十一连测day1
这次测试,是福建第三中学的某同学出的,感觉难度还行吧,今天我就浅谈一下这场比赛的时间分配与心得 打开题目,看到了T1,这题是一道计数题吧,感觉心态一下子就崩了,100%的数据点应该是组合数学容斥…

iOS 直播专题5-推流
常用的推流协议有: 协议内容RTP实时流传输协议,但不保证服务质量RTCPRTP数据流协议的一个姐妹协议,为RTP提供服务质量反馈SRTP & SRTCPRTP和RTCP的安全版本,提供数据加密、消息认证功能RTSP控制声音或影像的多媒体数据串流协议RTMPADOBE公司播放器与服务器之间多媒体数…

centos6.5-vsftp搭建
我的机子是默认是没有的vsftp。 yum install -y vsftp 创建账户专为ftp而生。useradd ftp01 更改账户不可登录系统。usermod -s /sbin/nologin ftp01 vsftp默认是可以匿名登录的,也是默认的端口,这些不安全选项都要修改! anonymous_enableYES…

Linux04-文件系统权限与ACL权限
目录 一、文件系统权限 1.1、认识文件系统权限 1.2、管理文件系统权限 1.3、特殊权限 1.4、默认权限 二、ACL权限 2.1、ACL本质是文件系统的一个挂载选项 2.2、更改文件的ACL权限 2.3、设置文件和目录的默认ACL权限 Linux中的权限管理分为两种类型 用户自主访问控制&…

ORB_SLAM2帧Frame
在追踪线程的一开始就会创建一个帧 cv::Mat Tracking::GrabImageMonocular(const cv::Mat &im,const double ×tamp)构造函数 在构造函数中,会对特征点进行提取。 ExtractORB(0,imGray);特征点分配至网格 将图像划分为48*64的网格,然后将…

Servlet的基本架构
Servlet的基本架构: package test;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Serv…

ORACLE 用户权限管理
Oracle创建用户的语法: CREATE USER username IDENTIFIED BY password OR IDENTIFIED EXETERNALLY OR IDENTIFIED GLOBALLY AS CNuser [DEFAULT TABLESPACE tablespace] [TEMPORARY TABLESPACE temptablespace] [QUOTA [integer K[M] ] [UNLIMITED] ] ON tables…

iOS 直播专题6-流媒体服务器
常用的流媒体服务器有: nginx、SRS、BMS 这里主要介绍nginx、SRS 这里都用docker来运行流媒体服务器 docker 安装 下载Mac版docker stable 直接安装 注册一个docer账号直接登录SRS 安装 SRS guthub地址:https://github.com/ossrs/srs/ 启动上面安装的docker软件后,打开终端…

Linux05-进程管理
目录 一、进程 1.1、进程ID 1.2、列出进程 1.3、进程前后台 二、使用信号控制进程 三、以管理员身份注销用户(踢掉在线用户) 四、监控进程活动 4.1、负载平均值 4.2、实时进程监控 进程是已启动的可执行程序的运行中的实力。它由以下部分组成&a…

Mat常用赋值方式
参考https://blog.csdn.net/wanggao_1990/article/details/53264753 #include <iostream> #include <opencv2/opencv.hpp> #include <unordered_map> using namespace std; using namespace cv; int main(int argc,char** argv) {// 1Mat mat (Mat_<flo…

java modbus协议
概念 Modbus是一种串行通信协议,Modbus协议目前存在用于串口、以太网以及其他支持互联网协议的网络的版本。 大多数Modbus设备通信通过串口EIA-485物理层进行。 通讯格式 地址域功能码数据CRC校验(低字节在前)1字节1字节N字节2字节 在单片机硬件通讯串口行业&…

layui栅格布局问题
在使用layer.open弹出到窗口中,使用布局一直不起作用。 开始到写法如下, 目的是一行分成左右两块,比例为8:4等分。 <div class"layui-fluid"><div class"layui-row layui-col-space10"><div class"layui-col-md…

Unity3d载入外部图片文件
unity里的图片在生成时会压缩成资源文件,有时客户想自己放一些图片用unity显示,就必须载入外部图片。 大体思路:用Application.streamingAssetsPath或Application.dataPath来指定存放图片的相对路径。用DirectoryInfo获得目录。遍历后FileInf…

Linux06-服务、守护进程和systemd
目录 一、简介systemd 二、使用systemd 2.1、systemctl命令与systemd单元 2.2、控制系统服务 一、简介systemd RHEL6及以前,系统启动和服务器进程是由第一个进程 init 管理,init按顺序启动、启动慢。 RHEL7以后系统启动和服务器进程由 systemd系统和…

ORB_SLAM2回环检测
词典是特征点的描述子的集合,属于同一类特征的特征点的描述子组成单词。 在局部建图线程中,处理完一个关键帧后,会将其放入回环检测线程 在使用关键帧数据库搜索候选关键帧组(DetectLoopCandidates)的时候&…

nginx 启动 + uwsgi + django
https://www.cnblogs.com/chenice/p/6921727.html https://blog.csdn.net/Aaroun/article/details/78218131转载于:https://www.cnblogs.com/pythonClub/p/9746866.html