这是我参与「第四届青训营 」笔记创作活动的第5天
服务端基础
how the web works
- 客户端发送网址向DNS服务器,DNS就像号码簿一样,把网址解析成端口号,然后返回给client
- 通过拿到的ip,和server建立TCP/IP连接(一种协议,规定网络通过什么方式进行连接)
- 发送请求,包括Start line ,HTTP request headers,BODY(用户传的东西)
- 服务器收到请求,把请求的东西分成一小块一小块再发送给client
- 一开始页面拿到的都是index.html,然后client对着index.html的东西重复上述的操作
Static websites , Dynamic websites,Api-Powered websites
api构建方式的数据,不止可以用在browsers还可以在app,exe等上面用
Node
Node,V8,Libuv and C++
V8 engine is what converts JS code into machine code that a computer can actually understand
Libuv is a opensource lib with a strong focus on asynchronous IO(异步IO),同时实现了两个node.js的重要功能,线程池和事件循环
(c-ares用于一些DNS请求的东西,OpenSSL用于保存记录
Processes,Threads and the Threads Pool
What is thread:Just imagine a thread as being a box where our code is executed in a computer's processor(计算机处理器)
Node runs in just one thread
event loop is where most of the work is done in your app ,it is really the heart of the entire Node architecture(整个Node架构的核心),but some tasks are too heavy that they will block the single thread,and so,that is where the thread
pool comes in(这就是线程池的用武之地)
the thread pool gives us four additional threads that are completely separate from the main single thread,these threads together formed a thread pool
决定哪些东西进去线程池不是开发者决定的,由node自主决定(常见的是上图的右下角那四个)
Cryptography 密码 Compression压缩 DNS lookups DNS查找
Nodejs是单线程的,那么nodejs启动后线程数是1?
不是,启动的时候是多线程的
Node.js启动的线程数不为1,是因为线程池?
答案:线程数不为1,不是因为线程池,而是因为V8。Node.js启动后会创建V8实例,V8实例是多线程的,V8中的线程有:
- 主线程:获取代码、编译执行
- 编译线程:主线程执行的时候,可以优化代码
- Profiler线程:记录哪些方法耗时,为优化提供支持
- 其他线程:用于垃圾回收清除工作,因为是多个线程,所以可以并行清除
Node.js线程池是预先创建好的?
答案:并不是,线程池中的线程是按需创建的。,线程池中的默认线程的4
线程池的线程个数最小为1,最多128
更改线程的个数
process.nextTick(()=>console.log("Process.nextTick"))
The Node.js Event Loop(事件循环)
介绍
这是Node设计中最重要的功能,使它可以异步编程
为什么这么重要? 因为它阐明了 Node.js 如何做到异步且具有非阻塞的 I/O,所以它基本上阐明了 Node.js 的“杀手级应用”,正是这一点使它成功了。
Node.js JavaScript 代码运行在单个线程上。 每次只处理一件事。
这个限制实际上非常有用,因为它大大简化了编程方式,而不必担心并发问题。
事件循环机制做的是什么事情
用于管理异步API的回调函数什么时候回到主线程中执行
Node.js采用的是异步I/O模型。同步API在主线程中执行,异步API在底层的C++维护的线程中执行,异步API的回调在主线程中执行,在js应用运行时,众多异步API的回调什么时候能回到主线程中调用呢,这就是事件循环做的事情
为什么叫做事件循环
因为Node.js是事件驱动的,事件驱动就是当什么时候做什么事情(当文件读取完做什么事情,当用户发送消息完做什么事情),做的事情就定义在回调函数中,可以将异步API的回调函数理解为事件处理函数,所以管理异步API回调什么时候回到主线程中调用的机制就叫事件循环机制
阻塞
任何花费太长时间才能将控制权返回给事件循环的 JavaScript 代码,都会阻塞页面中任何 JavaScript 代码的执行,甚至阻塞 UI 线程,并且用户无法单击浏览、滚动页面等。
JavaScript 中几乎所有的 I/O 基元都是非阻塞的。 网络请求、文件系统操作等。 被阻塞是个异常,这就是 JavaScript 如此之多基于回调(最近越来越多基于 promise 和 async/await)的原因。
调用堆栈
调用堆栈是一个 LIFO 队列(后进先出)。
事件循环不断地检查调用堆栈,以查看是否需要运行任何函数。
当执行时,它会将找到的所有函数调用添加到调用堆栈中,并按顺序执行每个函数。