s*****w 发帖数: 1527 | 1 从java往node转,原先有一段blocking call,
send request to 3rd party service, 这个service比较慢,
原先java是用glassfish, 搞1000个thread,
最糟糕的时候就是1000个同时往3rd party service送。
现在用node, 大家觉得怎么办好? 用settimeout() ?
node自己的async的readFile()怎么实现的?
我觉得自己对promise还没有理解透彻。 |
j*****w 发帖数: 1 | 2 我一直用 q,挺好用,不过那是基于 promise 的。
现在听说 bluebird 资源占用更少,可以试试看。 |
s*i 发帖数: 5025 | 3 可以考虑 await Promise.all(...) 一行搞定 |
s*****w 发帖数: 1527 | 4 大概我没说清楚,不是说要等1000个request 全部从3rd party service收到response,
而是node这里可以不间断地发出request.
如果直接copy existing java code, 那个是block call, node只能发一个,等3rd
party service处理结束了再发下一个。
【在 s*i 的大作中提到】 : 可以考虑 await Promise.all(...) 一行搞定
|
c******n 发帖数: 16666 | 5 看了好几遍还是没看懂你的问题描述
第三方慢 为啥还要发这么多去轰炸人家服务器?
还是说你这1000个是积累了很多request 因为对方慢?
最直接的应该是promise.then()或者await,尤其是后者 直接可以抄blocking的逻辑了
另外可以看一下bluebird这个lib来做promise 有几个比较有用的附加功能
1. 限流 限制同时发起多少个request
2. timeout
3. cancel
response,
【在 s*****w 的大作中提到】 : 大概我没说清楚,不是说要等1000个request 全部从3rd party service收到response, : 而是node这里可以不间断地发出request. : 如果直接copy existing java code, 那个是block call, node只能发一个,等3rd : party service处理结束了再发下一个。
|
s*****w 发帖数: 1527 | 6 抱歉,是现有的java程序就是这样,
create 1000 threads
foreach thread {
block_function(req);
}
要改成node, 开始没想通node作为single thread 怎么做。
我最后发现的解决方案是用setTimeout,
比如
setTimeout(block_function, 0)
从node这端就可以不停地发了。
主要是自己没有完全理解node,请各位大牛指教。
【在 c******n 的大作中提到】 : 看了好几遍还是没看懂你的问题描述 : 第三方慢 为啥还要发这么多去轰炸人家服务器? : 还是说你这1000个是积累了很多request 因为对方慢? : 最直接的应该是promise.then()或者await,尤其是后者 直接可以抄blocking的逻辑了 : 另外可以看一下bluebird这个lib来做promise 有几个比较有用的附加功能 : 1. 限流 限制同时发起多少个request : 2. timeout : 3. cancel : : response,
|
c******n 发帖数: 16666 | 7 setTimeOut算是上古时代的async了 主要是后续不怎么好控制
而且你这1k个request对方服务器没有api访问限制吗
const Promise = require("bluebird")
// 假设你用了callback 或者其他办法 保证你这个block function是async
const block_functionAsync = Promise.promisifyAll(block_function)
const thousandFetch = [...Array(1000)].map(() => block_functionAsync (req))
const result = await Promise.map(thousandFetch, {concurrency: 10
})
没开ide硬写的 可能有语法错误 表达下思路
不过 这样稍微可以控制一下流量 直接扔一堆过去 我以前跑死过对面的IIS和Spring,
估计都是没优化好 没限流 也没load balancer那种
ref:
http://bluebirdjs.com/docs/api/promise.map.html
我其实还是没理解 你发了1k个request之后 准备怎么搞 以及为啥要发这么多
setTimeOut方便发 但是不方便后续拿到结果的处理 所谓callbackhell
或者说因为你知道对方服务器速度慢 但是你想尽快拿到一部分结果? 可以试试下面2
个 尤其是后面那个 拿到一个response就自动停止了
http://bluebirdjs.com/docs/api/promise.some.html
http://bluebirdjs.com/docs/api/promise.any.html
还是说其实就是想敲1k下门?
edit1: 果然写错了 改下
【在 s*****w 的大作中提到】 : 抱歉,是现有的java程序就是这样, : create 1000 threads : foreach thread { : block_function(req); : } : 要改成node, 开始没想通node作为single thread 怎么做。 : 我最后发现的解决方案是用setTimeout, : 比如 : setTimeout(block_function, 0) : 从node这端就可以不停地发了。
|
s*i 发帖数: 5025 | 8 我斗胆comment一下:
1. 楼主可能不知道Node里,request本身就是async的。
2. chunjuan,blocking的function在Node里是不可能变成async的。promisify只是把
一种写法换成另一种写法而已。把async的function变成blocking的倒是有可能。
【在 c******n 的大作中提到】 : setTimeOut算是上古时代的async了 主要是后续不怎么好控制 : 而且你这1k个request对方服务器没有api访问限制吗 : const Promise = require("bluebird") : // 假设你用了callback 或者其他办法 保证你这个block function是async : const block_functionAsync = Promise.promisifyAll(block_function) : const thousandFetch = [...Array(1000)].map(() => block_functionAsync (req)) : const result = await Promise.map(thousandFetch, {concurrency: 10 : }) : 没开ide硬写的 可能有语法错误 表达下思路 : 不过 这样稍微可以控制一下流量 直接扔一堆过去 我以前跑死过对面的IIS和Spring,
|
c******n 发帖数: 16666 | 9 嗯 我写了之后 就想他要是能把async改成blocking的 难道不直接await就好了
所以后来加了个注释 假设他那个request起码已经写成callback形式
【在 s*i 的大作中提到】 : 我斗胆comment一下: : 1. 楼主可能不知道Node里,request本身就是async的。 : 2. chunjuan,blocking的function在Node里是不可能变成async的。promisify只是把 : 一种写法换成另一种写法而已。把async的function变成blocking的倒是有可能。
|
s*****w 发帖数: 1527 | 10 "blocking的function在Node里是不可能变成async的。"
blocking function 外面加一个settimeout变成async,看这个
https://medium.com/from-the-scratch/javascript-writing-your-own-non-blocking
-asynchronous-functions-60091ceacc79
【在 s*i 的大作中提到】 : 我斗胆comment一下: : 1. 楼主可能不知道Node里,request本身就是async的。 : 2. chunjuan,blocking的function在Node里是不可能变成async的。promisify只是把 : 一种写法换成另一种写法而已。把async的function变成blocking的倒是有可能。
|
|
|
s*****w 发帖数: 1527 | 11 node service是中间人,
前端有用户不停地发request, 送给java service, 再送给第3方。第3方同时可以处理
1000个,每个处理完的发一个response给java。现在的问题是java用block call在等
response.
现在我想把java换成node。
【在 c******n 的大作中提到】 : setTimeOut算是上古时代的async了 主要是后续不怎么好控制 : 而且你这1k个request对方服务器没有api访问限制吗 : const Promise = require("bluebird") : // 假设你用了callback 或者其他办法 保证你这个block function是async : const block_functionAsync = Promise.promisifyAll(block_function) : const thousandFetch = [...Array(1000)].map(() => block_functionAsync (req)) : const result = await Promise.map(thousandFetch, {concurrency: 10 : }) : 没开ide硬写的 可能有语法错误 表达下思路 : 不过 这样稍微可以控制一下流量 直接扔一堆过去 我以前跑死过对面的IIS和Spring,
|
s*i 发帖数: 5025 | 12 postpone exexution != async 。那篇文章明显不懂
: "blocking的function在Node里是不可能变成async的。"
: blocking function 外面加一个settimeout变成async,看这个
: https://medium.com/from-the-scratch/javascript-writing-your-own-non-
blocking
: -asynchronous-functions-60091ceacc79
【在 s*****w 的大作中提到】 : node service是中间人, : 前端有用户不停地发request, 送给java service, 再送给第3方。第3方同时可以处理 : 1000个,每个处理完的发一个response给java。现在的问题是java用block call在等 : response. : 现在我想把java换成node。
|
s*****w 发帖数: 1527 | 13 不理解了,用那个settimout不就是为了让后面的request都有机会发出去吗?
第3方的回复会比较慢,java就用多线程最多同时处理1000个,
那你说我用node怎么办? 我不可能像java一样发一个等一个。
【在 s*i 的大作中提到】 : postpone exexution != async 。那篇文章明显不懂 : : : "blocking的function在Node里是不可能变成async的。" : : blocking function 外面加一个settimeout变成async,看这个 : : https://medium.com/from-the-scratch/javascript-writing-your-own-non- : blocking : : -asynchronous-functions-60091ceacc79 :
|
s*i 发帖数: 5025 | 14 用Java的思维方式来理解JS不会好。Node里,
...
request(url1, callback)
request(url2, csllback)
...
这两个是并行关系。就是同时并行发送2个请求出去。
如果同时并行发送1000个请求出去,并且想得到所有都结束后的结果,用Promise.all(
...)
: 不理解了,用那个settimout不就是为了让后面的request都有机会发出去吗?
: 第3方的回复会比较慢,java就用多线程最多同时处理1000个,
: 那你说我用node怎么办? 我不可能像java一样发一个等一个。
【在 s*****w 的大作中提到】 : 不理解了,用那个settimout不就是为了让后面的request都有机会发出去吗? : 第3方的回复会比较慢,java就用多线程最多同时处理1000个, : 那你说我用node怎么办? 我不可能像java一样发一个等一个。
|
c******n 发帖数: 16666 | 15 大致看懂了
你这个用最常见的js处理async的就可以了
js本身是non blocking的
无论是去post/get拿数据 本地读i/o 如果你直接写’我要去拿数据‘ 代码都是执行完
了一路向下走不管数据拿得怎么样的
比如
const abc = fetch('http://www.mitbbs.com')
console.log(abc)
控制台只会告诉你abc是个promise,数据啥都没 因为还没等拿到 代码已经执行到下面
那行了
而你那个setTimeOut只能群发 后面的没法控制
上面fetch()本身返回的是promise,算是加了糖的callback function
而callback function的作用就是等那边完成任务来叫告诉你 这边搞定了 顺便把数值
传给你 现在有数据 你该干嘛干嘛
所以你第一步先得把你和第三方通信的方式写成带callback的 如果只是普通的request
的话那现成轮子太多了 如果要读console那还得写readline
有了带callback的request,你再去瞄一眼async/await 你就可以按照你之前block的写
法写了
但是不用攒了1k个才发,有一个发一个 反正js手头的这个发掉就直接发下一个了 直到
对面callback了才接手一下
所以1k个真是很快就发出去了 你估计还得手动写个counter 控制下流量 别把第三方弄
崩了或者被封了ip/api key
【在 s*****w 的大作中提到】 : node service是中间人, : 前端有用户不停地发request, 送给java service, 再送给第3方。第3方同时可以处理 : 1000个,每个处理完的发一个response给java。现在的问题是java用block call在等 : response. : 现在我想把java换成node。
|
s*****w 发帖数: 1527 | 16 我看了下request, 你是对的,它可以用callback。
最主要是我忘了这是一个http request, 就只想着block call.
等等我去把java code换换看。
多谢!
all(
【在 s*i 的大作中提到】 : 用Java的思维方式来理解JS不会好。Node里, : ... : request(url1, callback) : request(url2, csllback) : ... : 这两个是并行关系。就是同时并行发送2个请求出去。 : 如果同时并行发送1000个请求出去,并且想得到所有都结束后的结果,用Promise.all( : ...) : : : 不理解了,用那个settimout不就是为了让后面的request都有机会发出去吗?
|