Heim > Artikel > Web-Frontend > Über das Prinzip von NodeJS als Server
In diesem Artikel geht es hauptsächlich um das Prinzip von NodeJS als Server. Freunde, die es brauchen, können sich darauf beziehen. Schauen wir uns das unten mit dem Herausgeber an.
Node.js-Funktionen
1. Einzelner Thread
In serverseitigen Sprachen wie Java, PHP oder .net wird für jede Clientverbindung ein neuer Thread erstellt. Jeder Thread benötigt ca. 2 MB Speicher. Mit anderen Worten: Theoretisch beträgt die maximale Anzahl von Benutzern, die gleichzeitig mit einem Server mit 8 GB Speicher verbunden sein können, etwa 4.000. Damit eine Webanwendung mehr Benutzer unterstützen kann, muss die Anzahl der Server erhöht werden, und natürlich steigen auch die Hardwarekosten der Webanwendung.
Node.js erstellt nicht für jede Client-Verbindung einen neuen Thread, sondern verwendet nur einen Thread. Wenn ein Benutzer eine Verbindung herstellt, wird ein internes Ereignis ausgelöst. Durch nicht blockierende E/A- und ereignisgesteuerte Mechanismen ist das Node.js-Programm makroskopisch parallel. Mithilfe von Node.js kann ein Server mit 8 GB Speicher die Verbindungen von mehr als 40.000 Benutzern gleichzeitig verarbeiten.
Darüber hinaus besteht der Vorteil eines einzelnen Threads darin, dass das Betriebssystem nicht mehr den Zeitaufwand für die Erstellung und Zerstörung von Threads hat.
Der Nachteil besteht darin, dass, wenn ein Benutzer den Thread zum Absturz bringt, der gesamte Dienst abstürzt und andere ebenfalls abstürzen.
2
Wenn Sie beispielsweise auf die Datenbank zugreifen, um Daten abzurufen, dauert es eine Weile. Beim herkömmlichen Single-Thread-Verarbeitungsmechanismus wird nach der Ausführung des Codes für den Zugriff auf die Datenbank der gesamte Thread angehalten und darauf gewartet, dass die Datenbank das Ergebnis zurückgibt, bevor der nachfolgende Code ausgeführt wird. Mit anderen Worten: E/A blockiert die Ausführung des Codes, wodurch die Ausführungseffizienz des Programms erheblich verringert wird.
Aufgrund des in Node.js verwendeten nicht blockierenden E/A-Mechanismus wird nach der Ausführung des Codes, der auf die Datenbank zugreift, der Code dahinter sofort ausgeführt. Fügen Sie den Verarbeitungscode für die von der Datenbank zurückgegebenen Ergebnisse in die Rückruffunktion ein und verbessern Sie so die Ausführungseffizienz des Programms.
Wenn eine E/A abgeschlossen ist, wird der Thread, der die E/A-Operation ausführt, in Form eines Ereignisses benachrichtigt und der Thread führt die Rückruffunktion von aus dieses Ereignis. Um asynchrone E/A verarbeiten zu können, muss der Thread über eine Ereignisschleife verfügen, die ständig prüft, ob nicht behandelte Ereignisse vorliegen, und diese nacheinander verarbeitet.
Im Blockierungsmodus kann ein Thread nur eine Aufgabe bearbeiten. Um den Durchsatz zu verbessern, muss Multithreading verwendet werden. Im nicht blockierenden Modus führt ein Thread immer Berechnungsvorgänge aus und die CPU-Kernauslastung dieses Threads beträgt immer 100 %. Das ist also eine besonders philosophische Lösung: Anstatt viele Menschen untätig zu haben, ist es besser, dass einer sein Leben und seine Arbeit bis zum Tod riskiert.
3. Ereignisgesteuert 🎜>Wenn der Client den Aufbau einer Verbindung, die Übermittlung von Daten usw. anfordert, werden entsprechende Ereignisse angezeigt ausgelöst. In Node kann immer nur eine Ereignisrückruffunktion gleichzeitig ausgeführt werden. Während der Ausführung einer Ereignisrückruffunktion können Sie jedoch zur Verarbeitung anderer Ereignisse wechseln (z. B. wenn ein neuer Benutzer eine Verbindung herstellt) und dann zurückkehren, um mit der Ausführung fortzufahren Originalereignis. Die Rückruffunktion, dieser Verarbeitungsmechanismus, wird als „Ereignisschleife“
Mechanismus bezeichnet.
Die unterste Ebene von Node.js ist C++ (V8 ist auch in C++ geschrieben).
Fast die Hälfte des zugrunde liegenden Codes wird zum Erstellen von Ereigniswarteschlangen und Rückruffunktionswarteschlangen verwendet. Die ereignisgesteuerte Planung von Serveraufgaben kann sich nur ein Genie vorstellen. Der Tanz auf der Nadelspitze mit einem Faden übernimmt die Aufgabe, viele Aufgaben zu bewältigen.
单线程,单线程的好处,减少了内存开销,操作系统的内存换页。 如果某一个事情,进入了,但是被I/O阻塞了,所以这个线程就阻塞了。 非阻塞I/O, 不会傻等I/O语句结束,而会执行后面的语句。 非阻塞就能解决问题了么?比如执行着小红的业务,执行过程中,小刚的I/O回调完成了,此时怎么办?? 事件机制,事件环,不管是新用户的请求,还是老用户的I/O完成,都将以事件方式加入事件环,等待调度。 |
Wenn ein bestimmtes Ding eintritt, aber durch I/O blockiert wird, so Dieser Thread ist blockiert.
Nicht blockierende E/A, Kann Nichtblockierung das Problem lösen? Während der Ausführung von Xiaohongs Geschäft ist beispielsweise der E/A-Rückruf von Xiaogang abgeschlossen. Was soll ich zu diesem Zeitpunkt tun? ? Ereignismechanismus, Ereignisschleife, Unabhängig davon, ob es sich um die Anforderung eines neuen Benutzers oder um die E/A-Vervollständigung eines alten Benutzers handelt, wird sie als abgeschlossen Die Ereignismethode tritt der Ereignisschleife bei und wartet auf die Planung. Es soll drei Eigenschaften haben, aber tatsächlich ist es eine Eigenschaft. Es kann nicht ohne irgendjemanden verwendet werden und es kann nicht mehr gespielt werden. Node.js ist wie ein geiziger Restaurantbesitzer, der nur einen Kellner anstellt, um viele Leute zu bedienen. Dadurch ist er effizienter als viele Kellner. Alle E/A in Node.js sind asynchron, Rückruffunktion, Rückruffunktion. Was eignet sich Node.js für die Entwicklung? Für welche Art von Anwendungen eignet sich Node.js zur Entwicklung? Gut in I/O, nicht gut in der Berechnung. Da Node.js bei der Aufgabenplanung am besten geeignet ist und Ihr Unternehmen viele CPU-Berechnungen umfasst, bedeutet dies tatsächlich, dass diese Berechnung den einzelnen Thread blockiert und nicht für die Knotenentwicklung geeignet ist. Wenn die Anwendung eine große Menge gleichzeitiger E/A verarbeiten muss und keine sehr komplexe Verarbeitung durchführen muss, bevor sie eine Antwort an den Client sendet, Node .js passt hervorragend. Node.js eignet sich auch sehr gut für die Arbeit mit Web-Sockets, um interaktive Echtzeitanwendungen mit langen Verbindungen zu entwickeln. Zum Beispiel: ● Benutzerformularsammlung ● Prüfungssystem ● Chatroom ● Grafik- und Text-Liveübertragung ● Bereitstellung von JSON API (für Frontend-Angular-Verwendung) Der Unterschied zwischen Node.js und PHP und JSP ● Node.js ist keine unabhängige Sprache . Im Gegensatz zu PHP, JSP, Python, Perl und Ruby, die sowohl Sprachen als auch Plattformen sind, verwendet Node.js JavaScript für die Programmierung und läuft auf einer JavaScript-Engine ( V8). ● Im Vergleich zu PHP, JSP usw. (PHP, JSP, .net müssen alle auf dem Serverprogramm ausgeführt werden, Apache, Naginx, Tomcat, IIS ), Node.js überspringt HTTP-Server wie Apache, Naginx und IIS und muss nicht auf einer Serversoftware erstellt werden. Viele Designkonzepte von Node.js unterscheiden sich stark von der klassischen Architektur (LAMP = Linux + Apache + MySQL + PHP), die eine leistungsstarke Skalierbarkeit bieten kann. Node.js hat keinen Webcontainer . Beispiel 1: Auf der Seite wird „Hello World!“ angezeigt JS-Code: Öffnen Sie den Browser und geben Sie 127.0.0.1:8083 ein
Beispiel 2: Node.js hat keinen Webcontainer Bei Verwendung des Apache-Servers , wir Sie können oft sehen, dass es im htdocs-Verzeichnis verschiedene Unterordner gibt. Wenn wir auf die angegebene Seite zugreifen möchten, müssen wir nur 127.0.0.1:80/app/index.html in die Adressleiste des Browsers eingeben dazu Node.js verfügt jedoch nicht über einen Webcontainer. Wenn Sie also /xx.xx nach der URL-Adresse eingeben, wird diese nicht normal angezeigt 有这么一个文件目录结构:
fang.html 里面是一个 红色的、正方形的p,yuan.html 里面是一个 绿色的、圆形的p 现在新建一个 noWebContainer.js,看能否在url中输入 fang.html 打开页面 运行 127.0.0.1:4000,并在url后面加上 /fang.html,发现完全没用
现在初步对“Node.js没有web容器”这句话有了一点印象了,那想要打开fang.html,怎么办呢? 也就是说,如果 请求的url 里面包含了 /fang,就读取当前目录下(./ ---> 表示当前目录)的 fang.html,否则,就只显示 Hello World 同理,我也可以 输入 /yuan,显示 yuan.html
进一步,在 fang.html 中添加一个图片,从上面的目录结构中可以看到,图片的路径是完全正确的 运行 127.0.0.1:4000/fang,却发现图片破了,说明路径不对。但事实上,我们可以看到,这个路径是一点问题都没有的呀,那怎么办呢?
又回到了那句话,“Node.js没有web容器”,所以,还是要用前面的方法处理一下图片 再次运行,图片可正常显示 现在新建一个 yellow.css 样式表,让 yuan.html 引入这个css 文件 yellow.css 但是,页面的背景颜色没有发生任何改变
看来 “Node.js没有web容器”这句话是无处不在呀,同样需要对 css 文件做处理 再次运行代码,发现页面背景颜色变成了黄色<span style="font-size: 14px;">//require表示引包,引包就是引用自己的一个特殊功能<br/>var http = require(‘http‘);<br/><br/>//创建服务器,参数就是一个回调函数,表示如果有请求进来,要做什么<br/>var server = http.createServer(function(req, res){<br/> //req表示请求, request;res表示响应,response<br/><br/> //设置HTTP头部,状态码是200, 文件类型是html。字符编码格式是 UTF-8<br/> res.writeHead(200, {‘Content-Type‘:‘text/html; charset= UTF-8; ‘});<br/> res.end(‘Hello World!‘);<br/>});<br/><br/>//运行服务器,监听8083端口<br/>server.listen(8083, ‘127.0.0.1‘);<br/></span>
<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>
<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>
<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>
<span style="font-size: 14px;"><img src="yule.png" alt="图片"><br/></span>
<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>
<span style="font-size: 14px;">body{background:yellow;}<br/></span>
<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>
Das obige ist der detaillierte Inhalt vonÜber das Prinzip von NodeJS als Server. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!