【发布时间】:2019-07-01 08:32:59
【问题描述】:
所以这是我在一个程序文件中的节点 js http 服务器,重要的是我没有在 2 个单独的进程中运行在 2 个服务器以下。 它们在同一个进程中运行。
var today = require('./today');
var http = require('http');
var server1 = http.createServer(function(request, response) {
var now = Date.now();
var body = "The day of the week is " + today() + " " + now;
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
response.end(body);
});
server1.listen(3000);
var server2 = http.createServer(function(request, response) {
var body = "The day of the week is " + today();
var count = 0;
while (true) {
count++;
if(count == 10000){
console.log('server2');
count = 0;
}
}
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
response.end(body);
});
server2.listen(3002);
运行此节点 js 程序后,我向 server1 发送了请求,它工作正常,即我得到了很好的响应。 (200)
然后我发送了对 server2 的请求,它进入了无限循环,第二个请求显然挂了。
当第二个请求挂起时,我在端口 3000 向 server1 发送第三个请求,server1 也挂起,所以这意味着 nodejs 不支持并发请求处理,即当回调处理程序正在处理特定请求时没有其他请求 即使我的机器是 intel i7 多核也可以处理...... server2 中的无限循环应该只阻塞其中一个核心, 剩下的核心应该已经处理了 server1 上的后续请求。
#所以下面是一个部署在 glassfish 中的 java web 服务,我将它开发为无状态 EJB,以便 ejb 容器可以创建多个实例 这个 EJB 并同时处理这个 Web 服务上的多个请求
@WebService(serviceName = "NewWebService")
@Stateless()
public class NewWebService {
@WebMethod(operationName = "hello")
public String hello(@WebParam(name = "name") String txt) {
if(txt.equals("infinite")){
int i = 0;
while(true){
i++;
if(i>10000){
try{
Thread.sleep(2000);
i=0;
}catch(Exception e){
}
}
}
}
return "Hello " + txt + " !" + (new Date());
}
}
当我在 glassfish 中部署上面的 Web 服务并以“infinite”作为输入发送请求时,该请求从另一个浏览器窗口挂起,但我向同一个 Web 服务发送了另一个请求,并以“Aziz”作为输入,它同时返回了良好的结果当带有“无限”输入的窗口挂起时......但是当我评论 Thread.sleep(2000);在上面,两个请求都挂起,所以这意味着 JAVA 不支持并发请求。
结论:至少对于我创建的 Web 服务器,java 和 node js 的行为方式相同,不管 nodejs 有一个回调的概念,它认为它是神奇的......所以我的问题是为什么我们特别将 nodejs 称为单线程,在这个特定问题中,java 的行为方式相同。
注意:我不是在谈论您可以使用诸如 crypto.pbkdf2sync crypto.pbkdf2.#################### 等异步函数进行的 nodejs 异步调用########
在@minus 的第一次更新后更新: 非常感谢@minus,你说: “如果你 99% 的响应时间是由于 IO,nodejs 就可以正常工作,甚至比 java 的多线程环境更好。”
所以我改变了我的节点代码,我改变了无限调用来读取一个主要是基于 IO 操作的文件,但 server2 仍然阻止了 server1。如果我们将节点的行为与 java 的行为进行比较,那么 java 正在同时处理节点在长时间运行的回调中被阻塞的情况......无论该回调是否主要执行 IO 都无关紧要。以下是我更改的节点代码:
var http = require('http');
var server1 = http.createServer(function(request, response) {
var now = Date.now();
var body = "Time " + now;
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
response.end(body);
});
server1.listen(3000);
var fs = require('fs');
var server2 = http.createServer(function(request, response) {
while (true) {
fs.readFile('stuff.txt', 'utf8', function(err, contents) {
if(err){
console.log(err);
}else{
console.log(contents);
}
});
var contents = fs.readFileSync('stuff.txt', 'utf8');
console.log(contents);
}
var now = Date.now();
var body = "Time " + now;
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain'
});
response.end(body);
});
server2.listen(3002);
【问题讨论】: