依赖服务故障怎么办?几百万的项目明天要路演Demo了

简介: 依赖服务故障怎么办?几百万的项目明天要路演Demo了

场景

有时候创业者会开发制作一些项目,比如一些App,去创业园区找大佬展示。


可事不遂人意,App依赖的一些服务出现故障,首屏(首页怎么也登录不进去)。


本来是进入App下单提交结果卡在支付弹窗,进不到下一步,demo肯定没法顺利进行了。


这下可完犊子了,几千万的融资难道就要飞了!


其实这个问题跟:对方服务下线,手上的开发还没有做完,怎么继续进行,是一样的!


下面开始讲解,围绕一个App调用第三方支付服务来讲,请静心阅读。 文末还有博主准备的编程专栏,附送了很多开发学习链接。


我没有创业,不用demo,就不会碰到这个问题了?

以上问题,再泛化,就是搞开发的同学经常会碰到一个问题:对接方的接口还没有准备好,老板还在一边一再催促,甚至压第二,第三个项目了!


或者是,对方的网站挂,手上的项目还得进行怎么办?


所以,这个问题不管是前端,还是后端,App端,只要你的系统有其他系统依赖,通常非本应用进程的其他进程调用,WebAPI调用,前端跨域调用等,都可以统一归结为此类调用事件。


下面谈如何入手解决。


思路

修改自己App的代码

这种就是在自己的代码添加开关位(toggle pattern),开发某个调试的时候把它打开!如下图所示,一个开关切换调用或者请求到自己的模拟数据服务。

image.png

如果别人服务对你的应用影响很小,那么可以使用下面的代码来进行。

雷学委演示时间:如何加开关/Toggle

现有的App项目内的代码:

//雷学委CSDN Demo代码:
//这个方法调用其他公司(第三方)的接口
function callOtherServiceFromExternalCompany(){
    axios.get('http:///a-legacy-company-that-provide-unstable-api/api/v1/godBlessYouGetData').then(resp = >{
            handleOnData(resp.data);
        });
}
// handleOnData函数: 是当前app用来接收其他服务数据的
function handleOnData(data){
     //省略,这里是我的服务拿到别人公司数据后的后续处理。
     //省略N行代码。
}

上面的代码,很直观,调用第三方服务之后,触发调用本应用内的handleOnData。

这可以是第三方支付平台,自己应用获取支付结果再进入下一步的订单物流安排等等。(或者是App也可以是那别人的数据触发重新计算绘制界面)

改造后应用内的代码:

//雷学委CSDN Demo代码:
var flag = process.env.NODE_ENV //从环境变量获取NODE_ENV,根据这个变量来切换代码调用的分支。
function callOtherServiceFromExternalCompany() {
    if (flag) { //这是我们加的开关位
        var mockData = generateMockData() //生成服务需要的模拟数据
        handleOnData(mockData)
    } else {
        axios.get('http:///a-legacy-company-that-provide-unstable-api/api/v1/godBlessYouGetData').then(resp = >{
            handleOnData(resp.data);
        });
    }
}
//这里是自己项目的代码不需要做任何修改。
// handleOnData函数: 是当前app用来接收其他服务数据的
function handleOnData(data){
     //省略,这里是我的服务拿到别人公司数据后的后续处理。
     //省略N行代码。
}

就这样解决了,flag的具体取值在环境变量设置了。

image.png

这种方式可以解决小量少量依赖问题。

通常系统与系统之间不单单有一个接口调用!多了可是会让这代码看起来很凌乱!

调用越多的第三方服务,代码里面出现了很多开关代码,看起来就像层层套娃。(开关串联内部再串联)

最后你的系统看起来就像下面的图片那样,无法维护!

image.png

(图片来自:https://www.sohu.com/a/162197488_813379


你让后面的同学如何接手?自己想必也不太敢修改代码!


下面说说第二种。


镜像复制第三方站点接口

什么意思?


类比一下就是,家里原来的路由网络名字为:雷学委Wifi,路由器坏了,那买一个新的路由器把网络名也设置为:雷学委Wifi,一样的密码。那么我们的手机电脑都能正常链接了。


就像黑客钓鱼一样,仿造了高仿的服务接口,界面让你的服务无感知继续正常使用。


image.png

(图片来自网络:https://m.sohu.com/a/256230090_100248097


这个聊的是通过技术手段把依赖服务代理了,把调用都转到自己开发的模拟服务器上。有些小白可能不明白,这里的第三方是别人的服务。


这种方式是可以尽量不修改自己的应用代码或者少修改(不在代码加分支跳转的),通常就是配置网关或者配置修改成调用一个备用服务(或者自己模拟的第三方服务)。


如果有第三方备用服务,理论上只需要把原来调用的站点配置修改成备用站点,不需要有任何代码修改。


我们这里会更多讨论的是没有备用站点/服务的情况。这里稍微有两个做法,当然本质是一样的。


局部镜像模拟对方接口

局部镜像模拟对方接口,当对方有上千个接口被本系统调用的时候,又没有提供一个复制完整测试环境的方法。


只能采用这个策略,先把接口从入口调用先mock(模拟处理)

这样起码登录界面能登进去了,这样起码公司的demo还能做起来。


然后挑选重点的接口进行快速复制!这种方式也适用于第三方服务是一个大站点,他有某个子服务挂掉的情况。


雷学委演示时间:如何局部模拟

好,这里我们还是拿之前的UI服务来展示,代码后面会贴链接。


直接启动UI服务,因为后台产品服务没有启动所以这里显示:后端服务已下线!


image.png

编写局部镜像(Mock)

//雷学委-CSDN-代码Demo
const express = require('express');
const cors = require('cors');
const { createProxyMiddleware } = require('http-proxy-middleware');
//雷学委-CSDN-代码Demo:这里创建一个web服务
const app = express();
app.use(cors());
//01 我们拦截模拟了局部的接口
app.use('/products',function(req,res){
    console.log('雷学委:这里调用了我们代理接口:',req.originalUrl)
    res.status(200).send({}); // 这里随便整点啥都行
}) 
//02 其他调用仍然走这个网站http://a-legacy-company-that-provide-unstable-api
// 这里通过代理把对/otherApi的请求转发到原站点。
app.use('/otherApi', createProxyMiddleware({ 
  target: 'http:///a-legacy-company-that-provide-unstable-api/api/v1/godBlessYouGetData', 
  changeOrigin: true 
}));
app.listen(8081);

这里我们看到01代码段:把所有/products的请求拦截在当前模拟服务内进行简单处理(直接send发送一个空的数据{})。


实际上,第三方服务只是暂时不能用,我们要关注的只是把接口(WebAPI对应的处理)进行快速模拟,方便我们开发调试。


当项目开发到差不多,以后还是得切换到正真的服务进行联合调试的!这点需要记住,不可恋战!


启动局部代理服务, 刷新右边的UI服务,UI服务显示第三方服务上线了(绿色的)并打印了服务数据。


复制上述代码保存位proxy8081.js, 安装下图运行。

看看效果,虽然数据不完整,但是UI服务能够正常使用了。

image.png

全站镜像模拟别人服务接口

快速全站模拟对方服务

这种情况,如果对方已经下线,但是提供了代码,而且能跑起来,那直接跑起来,配置网络host mapping(主机映射站点:a-legacy-company-that-provide-unstable-api 到本机ip)

image.png

看,现在本机能够访问站点的接口:http://a-legacy-company-that-provide-unstable-api:8081/products

image.png

读者也可以拿上面的proxy8081.js 稍微调整就是全站镜像模式了,但是需要把第三方服务的所有接口都写上。

const express = require('express');
const cors = require('cors');
const { createProxyMiddleware } = require('http-proxy-middleware');
//雷学委-CSDN-代码Demo
const app = express();
app.use(cors());
//01 需要代理接口一
app.use('/products',function(req,res){
    console.log('雷学委:这里调用了我们代理接口:',req.originalUrl)
    res.status(200).send({}); // 这里随便整点啥都行
}) 
//02 需要代理接口二
app.use('/api02',function(req,res){
    console.log('雷学委:这里调用了我们代理接口:',req.originalUrl)
    res.status(200).send({}); // 这里随便整点啥都行
}) 
//省略一万行代码实现多个接口代理。
// 代理了第N个接口
app.use('/lastApi',function(req,res){
    console.log('雷学委:这里调用了我们代理接口:',req.originalUrl)
    res.status(200).send({}); // 这里随便整点啥都行
}) 
app.listen(8081);

从这里看,你是否感觉全站镜像,有提供第三方服务完整代码的时候,是很快就办到的。


但是很多时候,别人给的第三方服务的代码未必可以跑。那么这个全站代理/镜像,就需要进行很大量的代码,基本上是快速实现整个第三方站点的后台接口。


好,这里先停一停,看看代理的原理展示:


没加代理的架构:


image.png

加了代理的架构:

中间多了一个代理层,也就是我们写的代理代码或者也能理解为网络映射层。

image.png

那么,全站代理这么复杂,有什么用?

没有后台代码/依赖服务代理的唯一选择

当我们拿到一个项目没有后台代码或者后台服务时候,只能硬刚了。


这个是很有用的,可以快速的把项目跑起来!如果是一个有价值的UI或者App项目,那可以很快跑起来,通过查看运行效果,了解其他优秀应用的原理和业务流程。


你拿到的是一个App,或者一个打包好的项目

你没有环境也没有足够知识去加toggle并重新编译。

这时候,可以发动人海战术,看看App用了多少的接口,分配好接口快速开发,让这个App运行起来。


这个懂的读者就知道,这里只是场景举例,很多逆向工程的也是会这样做。


总结

本文讲述了几种模拟第三方服务的方法,也是几种重定向请求(流量)到模拟测试服务的方法。


相信所有开发者都会遇到类似的问题。


我们必须保持清醒,选择合适的模拟方法!事半功倍。

好了,对NodeJS或者对编程感兴趣的同学可以来看:雷学委的NodeJS系列


另外,推荐一下优秀的Nginx:https://www.nginx.com/ & https://www.nginx.cn/doc/


Nginx可以通过配置快速实现网站代理,也挺简单的,本文只拿少量代码来做展示。


这篇文章能够让你掌握解决依赖和逆向服务端推演的思路。


目录
相关文章
|
2月前
|
监控 安全 测试技术
从开发到测试再到发布,全方位解析项目上线的完美路程!
从开发到测试再到发布,全方位解析项目上线的完美路程!
151 0
|
JavaScript 测试技术 Python
低成本、快速造测试数据,这个造数工具我后悔推荐晚了!
没有测试数据,所谓的功能测试和性能测试全都是无米之炊。但我发现一个蛮诡异的事情,就是行业内很少会有人去强调测试数据的重要性,甚至市面上都没有人在做测试数据这门生意。
低成本、快速造测试数据,这个造数工具我后悔推荐晚了!
|
2月前
|
算法 前端开发 定位技术
从新建文件夹到承接猫晚——夜间版淘宝首页的发展
从新建文件夹到承接猫晚——夜间版淘宝首页的发展
70 0
|
2月前
|
JavaScript 前端开发 Java
开题报告-基于SpringBoot手办周边系统的设计与实现
开题报告-基于SpringBoot手办周边系统的设计与实现
|
2月前
|
数据采集 开发框架 搜索推荐
开题报告-基于SpringBoot的“遇见”婚恋交友平台的设计与实现
开题报告-基于SpringBoot的“遇见”婚恋交友平台的设计与实现
305 0
|
2月前
|
缓存 小程序 前端开发
开题报告--基于SpringBoot的外卖系统
开题报告--基于SpringBoot的外卖系统
136 0
|
前端开发 Shell 程序员
🙊整活向:定期给老板推送同事的代码量
总有领导想把公司往倒闭里整。但是每天推送每个人的代码量倒是挺有趣的,git log本身就自带这个功能,不来看看吗?
123 0
🙊整活向:定期给老板推送同事的代码量
|
缓存 监控 NoSQL
公司新入职一位大佬,把SpringBoot项目启动时间从7分钟降到了40秒!
公司新入职一位大佬,把SpringBoot项目启动时间从7分钟降到了40秒!
|
NoSQL JavaScript 前端开发
P0级事故,项目组慌的一批! 上
P0级事故,项目组慌的一批! 上
|
消息中间件 NoSQL JavaScript
P0级事故,项目组慌的一批! 下
P0级事故,项目组慌的一批! 下