>  기사  >  웹 프론트엔드  >  서버로서의 nodejs의 원리에 대하여

서버로서의 nodejs의 원리에 대하여

零到壹度
零到壹度원래의
2018-03-21 13:54:101996검색

이 글은 주로 서버로서의 nodejs의 원리에 대해 이야기하고 있습니다. 필요한 친구들이 참고하면 도움이 될 것입니다. 아래 에디터와 함께 살펴보겠습니다.

Node.js 기능

1. 단일 스레드

Java, PHP 또는 .net과 같은 서버 측 언어에서 각 클라이언트 연결됩니다. 새 스레드를 만듭니다. 각 스레드에는 약 2MB의 메모리가 필요합니다. 즉, 이론적으로 8GB 메모리를 탑재한 서버에 동시에 접속할 수 있는 최대 사용자 수는 약 4,000명 정도이다. 웹 애플리케이션이 더 많은 사용자를 지원하려면 서버 수가 늘어나야 하며, 웹 애플리케이션의 하드웨어 비용도 당연히 증가하게 됩니다.

Node.js는 각 클라이언트 연결에 대해 새 스레드를 생성하지 않고 하나의 스레드만 사용합니다. 사용자가 연결하면 비차단 I/O 및 이벤트 기반 메커니즘을 통해 내부 이벤트가 트리거되며 Node.js 프로그램은 거시적으로 병렬입니다. Node.js를 사용하면 8GB 메모리를 갖춘 서버에서 동시에 40,000명 이상의 사용자 연결을 처리할 수 있습니다.

또한 단일 스레드가 가져오는 이점은 운영 체제에 더 이상 스레드 생성 및 삭제에 대한 시간 오버헤드가 없다는 것입니다.

단점은 한 사용자가 스레드 충돌을 일으키면 전체 서비스가 충돌하고 다른 사용자도 충돌한다는 것입니다.


서버로서의 nodejs의 원리에 대하여

서버로서의 nodejs의 원리에 대하여

2. 비차단 I/O

예를 들어 데이터를 얻기 위해 데이터베이스에 접근할 때 시간이 좀 걸립니다. 전통적인 단일 스레드 처리 메커니즘에서는 데이터베이스에 액세스하는 코드를 실행한 후 전체 스레드가 일시 중지되고 후속 코드를 실행하기 전에 데이터베이스가 결과를 반환할 때까지 기다립니다. 즉, I/O가 코드 실행을 차단하여 프로그램 실행 효율성을 크게 떨어뜨립니다.

Node.js에서 사용하는 비차단 I/O 메커니즘으로 인해 데이터베이스에 액세스하는 코드가 실행된 후 그 뒤의 코드가 즉시 실행되며 데이터베이스 반환 결과에 대한 처리 코드는 다음과 같습니다. 콜백 함수에 배치하여 프로그램의 실행 효율성을 향상시킵니다.

I/O 작업이 완료되면 I/O 작업을 수행하는 스레드에 이벤트 형태로 알림이 전달되고 스레드는 이 이벤트에 대한 콜백 함수를 실행합니다. 비동기 I/O를 처리하기 위해서는 스레드에 이벤트 루프가 있어야 하며, 처리되지 않은 이벤트가 있는지 지속적으로 확인하고 이를 차례로 처리해야 합니다.

블로킹 모드에서는 하나의 스레드가 하나의 작업만 처리할 수 있으므로 처리량을 향상하려면 멀티스레딩을 사용해야 합니다. 비 차단 모드에서는 스레드가 항상 계산 작업을 수행하고 이 스레드의 CPU 코어 사용률은 항상 100%입니다. 그래서 이것은 특히 철학적인 해결책입니다. 많은 사람을 놀리게 하는 것보다 한 사람이 목숨을 걸고 목숨을 걸고 일하는 것이 더 좋습니다.

3. Event-driven event-driven

Node에서는 클라이언트가 연결 설정, 데이터 제출 및 기타 동작을 요청하면 해당 이벤트가 트리거됩니다. Node에서는 한 번에 하나의 이벤트 콜백 함수만 실행할 수 있지만, 이벤트 콜백 함수를 실행하는 도중에 다른 이벤트(예: 신규 사용자 접속 등) 처리로 전환했다가 다시 돌아와 해당 이벤트를 계속 실행할 수 있습니다. 원래 이벤트 콜백 함수에서 이 처리 메커니즘을 "이벤트 루프" 메커니즘이라고 합니다.

Node.js의 맨 아래 레이어는 C++입니다(V8도 C++로 작성되었습니다). 기본 코드의 거의 절반이 이벤트 대기열과 콜백 함수 대기열을 구성하는 데 사용됩니다. 이벤트 기반을 사용하여 서버 작업 일정을 완료하는 것은 천재만이 생각할 수 있는 일입니다. 실을 이용해 바늘끝에서 춤을 추는 것은 많은 일을 처리하는 임무를 맡는다.

서버로서의 nodejs의 원리에 대하여


단일 스레드, 단일 스레드의 장점은 운영 체제의 메모리 오버헤드와 메모리 페이징이 줄어드는 것입니다.

어떤 것이 들어왔는데 I/O로 막히면 스레드가 막히게 됩니다.

비 차단 I/O, I/O 문이 끝날 때까지 기다리지 않고 다음 문을 실행합니다.

논블로킹으로 문제를 해결할 수 있나요? 예를 들어 Xiaohong의 비즈니스를 실행하는 동안 Xiaogang의 I/O 콜백이 완료되었습니다. 이때 어떻게 해야 합니까? ?

이벤트 메커니즘, 이벤트 루프, 신규 사용자의 요청이든 기존 사용자의 I/O 완료이든 이벤트 형태로 이벤트 루프에 추가되어 일정을 기다립니다.

세 가지 특성이라고 하는데 사실은 누구도 없으면 작동할 수 없고 더 이상 재생할 수 없는 특성입니다.

Node.js는 많은 사람들에게 서비스를 제공하기 위해 웨이터 한 명만 고용하는 인색한 식당 주인과 같습니다. 결과적으로 많은 웨이터보다 더 효율적입니다.

Node.js의 모든 I/O는 비동기식 콜백 함수, 콜백 함수 집합입니다.

개발에 적합한 Node.js는 무엇인가요?

Node.js는 어떤 종류의 애플리케이션 개발에 적합합니까?

I/O는 잘하는데 계산은 잘 못해요. Node.js는 작업 스케줄링에 가장 적합하기 때문에 비즈니스에 CPU 계산이 많이 포함된다면 실제로 이 계산이 단일 스레드를 차단한다는 의미이며 Node 개발에 적합하지 않습니다.

Node.js는 애플리케이션이 대량의 동시 I/O를 처리해야 하고 클라이언트에 응답을 보내기 전에 애플리케이션 내에서 매우 복잡한 처리를 수행할 필요가 없을 때 매우 적합합니다. Node.js는 긴 연결을 통해 실시간 대화형 애플리케이션을 개발하기 위해 웹 소켓을 사용하는 데에도 매우 적합합니다. ㅋㅋㅋ
● JSON API 제공( 프론트엔드 Angular 사용을 위해)

Node.js는 PHP 및 JSP와 다릅니다

Node.js는 독립적인 언어가 아닙니다. PHP, JSP, Python, Perl 및 Ruby와는 달리 " 언어, 다양한 플랫폼, Node.js는 프로그래밍에 JavaScript를 사용하고 JavaScript 엔진(V8)에서 실행됩니다.

● PHP, JSP 등에 비해(PHP, JSP, .net은 모두 서버 프로그램, Apache, Naginx, Tomcat, IIS에서 실행해야 함) Node.js는 Apache, Naginx, IIS를 건너뜁니다. HTTP 서버 자체는 서버 소프트웨어에 구축될 필요가 없습니다. Node.js의 많은 디자인 개념은 강력한 확장성을 제공할 수 있는 클래식 아키텍처(LAMP = Linux + Apache + MySQL + PHP)와 매우 다릅니다. Node.js에는 웹 컨테이너가 없습니다.

페이지에 "Hello World!"가 표시됩니다.

Node.js에 웹 컨테이너가 없습니다


htdocs 디렉터리에 다양한 하위 폴더가 있는 경우가 많습니다. 지정된 페이지에 액세스하려면 브라우저 주소 표시줄에 127.0.0.1:80/app/index.html만 입력하면 됩니다. 그러나 Node 이후로는 이와 유사한 구조입니다. .js에는 웹 컨테이너가 없으므로 URL 주소 뒤에 /xx.xx를 입력하면 제대로 작동하지 않습니다.

有这么一个文件目录结构:

서버로서의 nodejs의 원리에 대하여

fang.html 里面是一个 红色的、正方形的p,yuan.html 里面是一个 绿色的、圆形的p

现在新建一个 noWebContainer.js,看能否在url中输入 fang.html 打开页面

<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/>   <br/>    res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/>    res.end("Hello World!");<br/>    <br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>

运行 127.0.0.1:4000,并在url后面加上 /fang.html,发现完全没用

서버로서의 nodejs의 원리에 대하여

现在初步对“Node.js没有web容器”这句话有了一点印象了,那想要打开fang.html,怎么办呢?

<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/>    if(req.url==‘/fang‘){<br/>        fs.readFile(‘./fang.html‘, function(err,data){<br/>            //req表示请求,request;  res表示响应,response<br/>            //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else{<br/>        res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/>        res.end("Hello World!");<br/>    }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>

也就是说,如果 请求的url 里面包含了 /fang,就读取当前目录下(./ ---> 表示当前目录)的 fang.html,否则,就只显示 Hello World

서버로서의 nodejs의 원리에 대하여

同理,我也可以 输入 /yuan,显示 yuan.html

<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/>    if(req.url==‘/fang‘){<br/>        fs.readFile(‘./fang.html‘, function(err,data){<br/>            //req表示请求,request;  res表示响应,response<br/>            //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yuan‘){<br/>        fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else{<br/>        res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/>        res.end("Hello World!");<br/>    }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>


서버로서의 nodejs의 원리에 대하여

进一步,在 fang.html 中添加一个图片,从上面的目录结构中可以看到,图片的路径是完全正确的

<span style="font-size: 14px;"><img src="yule.png" alt="图片"><br/></span>

运行 127.0.0.1:4000/fang,却发现图片破了,说明路径不对。但事实上,我们可以看到,这个路径是一点问题都没有的呀,那怎么办呢?

서버로서의 nodejs의 원리에 대하여

又回到了那句话,Node.js没有web容器”,所以,还是要用前面的方法处理一下图片

<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/>    if(req.url==‘/fang‘){<br/>        fs.readFile(‘./fang.html‘, function(err,data){<br/>            //req表示请求,request;  res表示响应,response<br/>            //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yuan‘){<br/>        fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yule.png‘){<br/>        fs.readFile(‘./yule.png‘, function(err,data){<br/><br/>            res.writeHead(200, {"Content-type":"image/jpg"});<br/>            res.end(data);<br/>        })<br/>    }else{<br/>        res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/>        res.end("Hello World!");<br/>    }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>

再次运行,图片可正常显示

서버로서의 nodejs의 원리에 대하여   서버로서의 nodejs의 원리에 대하여

现在新建一个 yellow.css 样式表,让 yuan.html 引入这个css 文件

yellow.css

<span style="font-size: 14px;">body{background:yellow;}<br/></span>

但是,页面的背景颜色没有发生任何改变

서버로서의 nodejs의 원리에 대하여


看来 “Node.js没有web容器”这句话是无处不在呀,同样需要对 css 文件做处理

<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/>var fs = require(‘fs‘);<br/><br/>//创建服务器,参数是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/>    if(req.url==‘/fang‘){<br/>        fs.readFile(‘./fang.html‘, function(err,data){<br/>            //req表示请求,request;  res表示响应,response<br/>            //设置HTTP头部,状态码是200,文件类型是html,字符集是utf8<br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yuan‘){<br/>        fs.readFile(‘./yuan.html‘, function(err,data){<br/><br/>            res.writeHead(200, {‘Content-type‘:‘text/html;charset=UTF-8‘});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yule.png‘){<br/>        fs.readFile(‘./yule.png‘, function(err,data){<br/><br/>            res.writeHead(200, {"Content-type":"image/jpg"});<br/>            res.end(data);<br/>        })<br/>    }else if(req.url==‘/yellow‘){<br/>        fs.readFile(‘./yellow.css‘, function(err,data){<br/><br/>            res.writeHead(200, {"Content-type":"text/css"});<br/>            res.end(data);<br/>        })<br/>    }else{<br/>        res.writeHead(200,{"Content-type":"text/html;charset=UTF-8"});<br/>        res.end("Hello World!");<br/>    }<br/>});<br/><br/><br/>//运行服务器,监听4000端口(端口号可以任改)<br/>server.listen(4000,"127.0.0.1");<br/></span>

再次运行代码,发现页面背景颜色变成了黄色

서버로서의 nodejs의 원리에 대하여

위 내용은 서버로서의 nodejs의 원리에 대하여의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.