• 关于 js 多线程循环 的搜索结果

回答

至少从开发者的角度来看,Node.js 是单线程运行的。底层使用 libuv 使用多线程。 每一个 I/O 操作都需要一个回调,一旦操作完成会被事件循环执行

茶什i 2019-12-02 03:21:38 0 浏览量 回答数 0

回答

" Java开发者的安全性有待提高呀,居然用root超级用户跑Tomcat服务进程.可以用start-stop-daemon指定用户运行守护进程. 话说Java服务器都这么吃内存的么?居然占用了18个GB. 还有,我查了,E5-4603 v2是一个4核心的CPU,你的服务器有2个CPU,那总的核心数就是8个.这时,top命令在Tasks进程模式下(你的截图就是这个模式),一个任务(进程)利用全部CPU资源时,%CPU应该显示为800%.很多人用惯了Windows,想当然的认为任务的CPU使用率最大值是100%.在Linux上,一个包含多线程的任务进程,CPU使用率超过100%就表示使用超过1个核心,比如我在Ubuntu桌面上使用的Firefox浏览器,其就是一个典型的多线程应用. <img alt="""" height=""69"" src=""https://static.oschina.net/uploads/space/2017/0314/190655_U05T_561214.png"" width=""567"" /> 我的笔记本处理器是双核4线程的i5-3230M,CPU满载时最大显示400%. 如果你把top命令从Tasks任务进程模式切换到Threads线程模式,则任一线程的%CPU都不能超过100%,比如: top -H -p pidof firefox (参数-H表示使用Threads线程模式观测) 可见: <img alt="""" height=""603"" src=""https://static.oschina.net/uploads/space/2017/0314/191357_XH4d_561214.png"" width=""352"" /> 所以你可以在这个Threads线程模式下看看到底是那个Java线程占用了1个CPU核心,对于C程序(如Nginx/PHP-FPM)一般都是用sudo strace -p PID来跟踪系统调用来发掘问题,对Java程序,也可以用strace看看,不过Java不是还有像jstat这种专门的东西么?######还有top里的TIME+列也很有意义,表示该任务(进程或线程)启动后使用的总的 CPU 时间.比如1:23.45代表1分钟23.45秒.######你这是地图炮了######我的截图里,top里面还有一个P列,这个可以在top里按f进去设置把它调出来,表示的是程序最后使用的CPU核心编号(Last Used Cpu),我的处理器核心只有4个,所以P的取值只能是:0, 1, 2, 3###### 找个晚上,自己压压看~~可以用 JMeter gattling,慢慢增加人数,同时观察 CPU######回复 <a href=""https://my.oschina.net/u/3356111"" class=""referer"" target=""_blank"">@XhuiFly : 你是说 JS 卡吗? 那你都知道原因了,直接 review JS 代码啊######回复 <a href=""https://my.oschina.net/u/3356111"" class=""referer"" target=""_blank"">@XhuiFly : 外包的业务每人关心性能的,之前遇到过,主要是调数据库的问题######登录的人再多的不会卡,就是部分操作比如选择商品后有大量的js代码做检验,这个工具能跟踪出来么?###### 查一下应用代码吧###### 外包都是草草了事,负责的外包企业少之又少###### 呵呵了,死循环可以99%  空跑看看######应该不是死循环,同样的操作重启后就没问题。###### top -Hp pid jstack pid###### 如果不想花太多时间查问题,在不影响使用的前提下,跑一个crontab定时任务,每天晚上自动重启一次吧。######我倒是做了一个重启的脚本,就是怕这玩意哪天突然启不了怎么办…担心稳定性###### hashmap死循环?###### 你看下数据库那台机器怎么样,如果数据库那台机器正常的话,那就是你的应用代码写的有问题,看下是不是什么线程在搞事情,jstack pid号。###### 这种现象,问题基本都是在应用层代码上。"

kun坤 2020-06-09 23:38:18 0 浏览量 回答数 0

问题

一台tomcat服务器,应对峰值200人的压力,为何会卡。403.10 禁止访问:配置无效 

kun坤 2020-05-28 13:24:42 3 浏览量 回答数 1

新用户福利专场,云服务器ECS低至102元/年

新用户专场,1核2G 102元/年起,2核4G 699.8元/年起

回答

//请写出输出内容 async function async1() { console.log('async1 start'); await async2(); console.log('async1 end'); } async function async2() { console.log('async2'); } console.log('script start'); setTimeout(function() { console.log('setTimeout'); }, 0) async1(); new Promise(function(resolve) { console.log('promise1'); resolve(); }).then(function() { console.log('promise2'); }); console.log('script end'); /* script start async1 start async2 promise1 script end async1 end promise2 setTimeout */ 这道题主要考察的是事件循环中函数执行顺序的问题,其中包括async ,await,setTimeout,Promise函数。下面来说一下本题中涉及到的知识点。 任务队列 首先我们需要明白以下几件事情: - JS分为同步任务和异步任务 - 同步任务都在主线程上执行,形成一个执行栈 - 主线程之外,事件触发线程管理着一个任务队列,只要异步任务有了运行结果,就在任务队列之中放置一个事件。 - 一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到可执行栈中,开始执行。 根据规范,事件循环是通过任务队列的机制来进行协调的。一个 Event Loop 中,可以有一个或者多个任务队列(task queue),一个任务队列便是一系列有序任务(task)的集合;每个任务都有一个任务源(task source),源自同一个任务源的 task 必须放到同一个任务队列,从不同源来的则被添加到不同队列。 setTimeout/Promise 等API便是任务源,而进入任务队列的是他们指定的具体执行任务。 宏任务 (macro)task(又称之为宏任务),可以理解是每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。 浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个(macro)task执行结束后,在下一个(macro)task 执行开始前,对页面进行重新渲染,流程如下: (macro)task->渲染->(macro)task->... (macro)task主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、postMessage、MessageChannel、setImmediate(Node.js 环境) 微任务 microtask(又称为微任务),可以理解是在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。 所以它的响应速度相比setTimeout(setTimeout是task)会更快,因为无需等渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。 microtask主要包含:Promise.then、MutaionObserver、process.nextTick(Node.js 环境) 运行机制 在事件循环中,每进行一次循环操作称为 tick,每一次 tick 的任务处理模型是比较复杂的,但关键步骤如下: 执行一个宏任务(栈中没有就从事件队列中获取)执行过程中如果遇到微任务,就将它添加到微任务的任务队列中宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染- 渲染完毕后,JS线程继续接管,开始下一个宏任务(从事件队列中获取) 回到本题 首先,事件循环从宏任务(macrotask)队列开始,这个时候,宏任务队列中,只有一个script(整体代码)任务;当遇到任务源(task source)时,则会先分发任务到对应的任务队列中去。然后我们看到首先定义了两个async函数,接着往下看,然后遇到了 console 语句,直接输出 script start。输出之后,script 任务继续往下执行,遇到 setTimeout,其作为一个宏任务源,则会先将其任务分发到对应的队列中script 任务继续往下执行,执行了async1()函数,前面讲过async函数中在await之前的代码是立即执行的,所以会立即输出async1 start。遇到了await时,会将await后面的表达式执行一遍,所以就紧接着输出async2,然后将await后面的代码也就是console.log('async1 end')加入到microtask中的Promise队列中,接着跳出async1函数来执行后面的代码。script任务继续往下执行,遇到Promise实例。由于Promise中的函数是立即执行的,而后续的 .then 则会被分发到 microtask 的 Promise 队列中去。所以会先输出 promise1,然后执行 resolve,将 promise2 分配到对应队列。 script任务继续往下执行,最后只有一句输出了 script end,至此,全局任务就执行完毕了。 根据上述,每次执行完一个宏任务之后,会去检查是否存在 Microtasks;如果有,则执行 Microtasks 直至清空 Microtask Queue。 因而在script任务执行完毕之后,开始查找清空微任务队列。此时,微任务中, Promise 队列有的两个任务async1 end和promise2,因此按先后顺序输出 async1 end,promise2。当所有的 Microtasks 执行完毕之后,表示第一轮的循环就结束了。 第二轮循环依旧从宏任务队列开始。此时宏任务中只有一个 setTimeout,取出直接输出即可,至此整个流程结束。

九旬 2020-05-24 22:19:57 0 浏览量 回答数 0

问题

Node.js应用性能优化的五个技巧

忆远0711 2019-12-01 21:50:58 8422 浏览量 回答数 1

回答

http协议本身就是请求-响应, 不可能反向。所谓的服务器push其实核心依然是依靠浏览器主动发起请求,有两种方式,一种是js轮询请求,一种是长连接。 长连接指发送请求后,服务器不是立即响应而是等到有推送数据时在响应,如果中间超时,浏览器还要再发送请求过去。 ######回复 @Anger_Coder : 长连接是必须有线程的,否则无法同时处理多个长连接请求。发起方一定是用户端!不太明白你问的是什么意思?######没错,那可以理解为http虽然是tcp socket,但是短连接,无状态信息是吧,而且js轮询请求 是做在client端的;那么有没有可能,服务器端做无差别的消息发送,client端 做校验,那么无论动态模板还是静态页,都是没有常驻内存的,也就是类似于php那种脚本语言,没有线程、进程;那么长连接的建立 是当客户端发起连接请求开始的;那么对用户状态 如何 监控呢?######js定时执行 ######你好,用过js定时 用的是setInterval,但这个的前提是 客户端打开了浏览器,并且浏览器能执行js代码,发起者 还是客户端######可行的,反向ajax就是这么做的,只不过会使服务器的压力增大######回复 @Anger_Coder : 我也只是知道有这个东西,具体也没用过,哈哈######谢谢,我先了解下反向Ajax,不懂的话 在请教你######反向Ajax?即服务器Push。###### 这个就像osc的动弹嘛。osc用的是setTimeout来做的吧 dwr也可以,都可以看看 ######这叫服务器推送,可以百度一下: HTML5 Server-Sent Events和HTML5 WebSockets,不过这要求使用支持HTML5的浏览器,IE8及以下只能用客户端拉取了,就是长连接Long-polling。######好的,谢谢,我会了解相关的东东滴:)######XMPP?######可参考Html5的WebSocket技术######这个可以做,在服务器端和客户端之间保持一个连接,然后服务器端有跟新内容就像客户端写入,没有跟新的内容也不关闭连接。但是这样非常消耗性能,如此的话就只能采用折中的方法,每个连接保持一段时间,过了这段时间关闭,有新的请求过来的时候重新创建一个连接,如此循环######恩,了解,我先实现一个demo..感谢######用blazds向前段的swf文件推送数据,前端的swf文件你设置成不可见就可以了,然后将获取到的数据再传送给js调用,这样就不用考虑长链接或者websocket之类不同浏览器的特性了######swf在这个项目中 不适用了T_T

kun坤 2020-05-29 12:11:27 0 浏览量 回答数 0

问题

【精品问答】前端开发必懂之JS技术二百问

茶什i 2019-12-01 22:05:04 146 浏览量 回答数 0

回答

就拿查询MySQL获取结果集并在页面上显示数据为例来分析. HTTP请求由C级别的程序比如Apache/Nginx处理(Java的HTTP服务用的是Java开发的Tomcat等), PHP则调用内置在PHP引擎的C开发的数据库驱动mysqlnd(Java用的是Java开发的JDBC驱动)来操作MySQL, 查询的逻辑这个重点都落在了C/C++开发的MySQL身上, 然后就是把返回结果集放到PHP数组, 经过字符串处理后在页面输出, 这些逻辑并不复杂, PHP负荷并不大. 值得注意的是, PHP内置的大量库函数全部使用C实现, 而Java的核心运行时类库rt.jar则是使用Java实现.在一些CLI下的压力测试中,因为存在大量的循环,很容易就触发Java的JIT热点编译,这时Java的计算性能上升到C的级别,这样的测试结果只能说Java在计算上的性能碾压动态解释型弱类型的PHP,而不是在Web上.对比具有JIT的机制的HHVM和PHP7的性能也能说明这个问题,在bench.php这个计算脚本的压力测试中,HHVM还是要比PHP7快1到2倍,但在WordPress等真实Web应用的测试中,HHVM和PHP7两者的性能相近.PHP的运行模式要比Java健壮稳定得多,比如PHP-FPM是经典的多进程prefork模式,主进程会维持指定数量的工作进程数,可以设置工作进程在处理多少个请求后自动重启.反观Java多线程的Tomcat,除了内存膨胀,代码稍有不慎,就有可能让Tomcat崩溃退出,抛出一大堆的错误信息.PHP开启ZendOpcache后,可以把脚本生成的opcode缓存到内存形成opcache供下次请求直接在ZendVM上执行,能带来一定的性能提升.PHP进程(PHP-FPM,Apache)可以和MySQL/Memcached/Redis建立持久连接,一个PHP进程保持一个MySQL持久连接,省去每次请求都建立连接的开销.但需要注意PHP进程数不要超过MySQL最大连接数这一点,超时或重启MySQL后PHP-FPM在代码mysqli_connect时会自动重连,但会返回"MySQL server has gone away"的Warning信息,可以用@抑制错误输出.PHP的热部署特性大大方便了开发和运维,这点是Java等其他语言(包括RoR/Python/Node.JS)所不能媲美的.

蛮大人123 2019-12-02 01:53:14 0 浏览量 回答数 0

回答

云端接入域名和端口号是什么? 域名:js ${YourProductKey}.iot-as-mqtt.${YourRegionId}.aliyuncs.com 。 其中,${YourProductKey}请替换为您的产品ProductKey;${YourRegionId}请参见地域和可用区,替换为您在物联网平台创建产品时选择的地域代码。 端口: 1883。 使用MQTT协议连接,不同的设备可以使用相同的clientID连接服务器吗? clientID需为全局唯一。如果不同的设备使用相同的clientID同时连接物联网平台,那么先连接的那个设备会被强制断开。 如何开启域名直连? MQTT连接有两种方式。 认证后再连接:首先使用HTTPS连接到```js js iot-auth.cn-shanghai.aliyuncs.com:443 获取认证cert后,再使用MQTT连接到 ```js js/public.iot-as-mqtt.cn-shanghai.aliyuncs.com/1883。 认证连接必须使用TLS加密进行认证。 域名直连:连接域名:js ${productKey}.iot-as-mqtt.cn-shanghai.aliyuncs.com:1883 。 域名直连减少了HTTPS获取证书cert的过程。 资源受限的设备推荐使用域名直连。一些特殊增值服务,例如设备级别的引流,则推荐先HTTPS发送授权后再连接MQTT。在make.setting中设置js FEATURE_MQTT_DIRECT=y , 然后执行js make reconfig 即 可设置为先认证后再MQTT连接。 MQTT协议版本是多少? 在MQTT connect packet中设置MQTT的版本。目前SDK(V2.02)使用MQTT 3.1.1 。 可以修改SDK代码中js src\mqtt\mqtt_client.h IOTX_MC_MQTT_VERSION 的 值,来修改支持的版本。3:3.1版;4:3.1.1版。 MQTT进行设备认证时,server返回“400”错误 认证返回400错误,表示鉴权认证失败。请检查设备证书信息ProductKey、DeviceName和DeviceSecret是否正确。 C语言SDK中MQTT是否支持iOS接入? C语言SDK可以移植到任何能够支持C语言的系统上。如果是iOS系统建议寻找开源的Object-C实现。 目前mqtt-example设备上线后会立刻下线,请问如何修改mqtt-example让设备一直处于上线状态? mqtt-example程序发送一次消息后会自动退出,可以尝试以下任意一种方式实现长期在线。 执行mqtt-example时,使用命令行js ./mqtt-example loop , 设备会保持长期在线。修改demo代码。example 的代码在最后会调用IOT_MQTT_Destroy,设备最后会变成离线状态,所以可以修改代码,去掉IOT_MQTT_Unregister 和IOT_MQTT_Destroy。 while(1) { IOT_MQTT_Yield(pclient, 200); HAL_SleepMs(100); } 心跳的时间间隔如何设置? 在IOT_MQTT_Construct里面可以设置keepalive_interval_ms的取值。物联网平台使用这个值来作为心跳间隔时间。keepalive_interval_ms的取值范围是60000~300000。 设备端的重连机制是什么? 设备端会在keepalive_interval_ms时间间隔发送ping request,然后等待ping response。 如果设备端在keepalive_interval_ms时间内无法收到ping response,或是在进行send以及recv时发生错误,平台就认为此时网络断开,而需要进行重连。 重连机制是平台内部触发,无需使用者接入。重连时,会重新进行认证。如果认证成功就会开始再次进行MQTT connect。重连会一直持续直到再次连接成功。 云端如何侦测到设备离线? 云端会根据MQTT CONNECT packet里面keepalive的设置,等待ping request。如果在指定时间内没有收到ping request,则认为设备离线。 云端可以接受的最大时延是5秒。 设备端SDK是否支持MQTT和CCP协议的断线重连? 支持。测试场景描述:开发板通过WiFi连接上路由器后,把网线拔掉,MQTT和CCP协议都会自动尝试和server重新建立连接。尝试时间间隔是1s、2s、4s、8s、…,最大间隔时间默认是60s,也就是说断网后超过60s时间仍未连接成功,之后会每隔60s尝试和server重连。您可以设置最大间隔时间。 发布(Publish QoS1)数据时,偶尔会出现MQTT_PUSH_TO_LIST_ERROR(-42),如何解决? 需要等待ACK的packet都会存放起来,等待ACK。存放量有上限,当需要等待的packet太多到达上限时,就会触发js MQTT_PUSH_TO_LIST_ERROR(-42) error 。 出现错误可能是因为当前网络状态不好,或者是发送的频率过高。如果排除上述两个问题,当前的发送的频率是预期的,那么可以适当的调整IOTX_MC_REPUB_NUM_MAX、 IOTX_MC_SUB_REQUEST_NUM_MAX和IOTX_MC_SUB_NUM_MAX的大小。 如果业务允许,也可以把publish的QoS调整成0。 IOT_MQTT_Yield的作用是什么? IOT_MQTT_Yield的作用是尝试接收数据。因此在需要接收数据时,例如subscribe 和 unsubscribe之后,publish QoS1 消息之后,或是希望收到publish 数据时,都需要主动调用该函数。 IOT_MQTT_Yield参数timeout的意义是什么? IOT_MQTT_Yield会尝试接收数据,直到timeout时间到后才会退出。 IOT_MQTT_Yield与HAL_SleepMs的区别 IOT_MQTT_Yield与HAL_SleepMs都是阻塞一段时间,但是IOT_MQTT_Yield实质是去读取数据,而HAL_SleepMs则是系统什么也不做,等待timeout。 如何循环接收消息? 需要循环调用IOT_MQTT_Yield ,函数内自动维持心跳和接收数据。 订阅了多个Topic,调用一次IOT_MQTT_Yield,能接收到多个Topic的消息吗? 首先需要确定Topic的权限,是不是同时满足发布和订阅。如果是,调用一次IOT_MQTT_Yield,可以接收到多个packet。 MQTT连接方式,只能通过不停地调用IOT_MQTT_Yield来轮询获取数据吗? 如果使用的TCPIP协议栈,可以实现TCP主动通知上层有数据到达,可以改动实现事件触发的方式来触发IOT_MQTT_Yield。但是改动比较大,所以还请自行评估是否需要修改。 修改流程是: 调整utils_net.c里面socket的API,变成可以由TCP数据到达时回调的API。 当TCP主动通知上层有数据到达时,通知到MQTT服务器。让MQTT服务器内部执行IOT_MQTT_Yield,这样就可以不需要外部调用IOT_MQTT_Yield来读取数据。 如果TCP无法做到主动上报数据,但OS支持多线程,也可以在MQTT-example里面再起一个thread,在这个thread里面以下代码用于接收数据。收到数据时,触发主线程进行数据处理,而主线程大部分时间可以用于处理其他逻辑。 while(1) { IOT_MQTT_Yiled(pclient, 200); HAL_SleepMs(200); } 如果使用的系统也不支持多线程,就只能把IOT_MQTT_Yield的timeout时间间隔减小,然后提高调用的频率,在每次调用的时间间隔内执行其他操作,从而做到尽量减少对其他操作的阻塞。 是否支持QoS 2? 不支持。 什么情况下会发生订阅超时(subscribe timeout)? 在2倍request_timeout_ms时间内,系统未接收到SUBACK packet时,会触发订阅超时,并通过event_handle函数发送超时通知。 请在subscribe之后,立刻执行IOT_MQTT_Yield尝试读取SUBACK,请勿使用HAL_SleepMs。 subcribe时,返回IOTX_MQTT_EVENT_SUBCRIBE_NACK 请检查Topic的操作权限是否为订阅。 如果发布报错“no authorization”,请确认是否为发布权限。 MQTT 发布的消息体大小限制 MQTT的协议包受限于IOT_MQTT_Construct里参数的write_buf和read_buf的大小。 MQTT协议包大小不能超过256 KB。超过大小限制的消息会被丢弃。 MQTT协议pub消息payload格式是怎么样的? 物联网平台没有制定pub消息payload的具体字段有那些。您根据应用场景制定自己的协议,然后以JSON格式放到pub消息载体里面传给服务端。 ota_mqtt升级的时候报错“mqtt read buffer is too short” MQTT设置的buffer过小,即mqtt_param的pread_buf和pwrite_buf申请过小造成的。可以根据实际需要修改OTA_MQTT_MSGLEN的大小。 是否可以使用MQTT直连的方式进行OTA升级? OTA升级时,必须使用HTTPS进行固件下载。MQTT只接收版本更新指令,与MQTT的连接方式无关。阿里云不支持HTTP下载固件,因此如果设备没有SSL通信的能力,则不能使用OTA服务。 打开MQTT over TLS,运行时提示MQTT创建失败,返回错误码0x2700 如果关闭MQTT over TLS则可以成功地订阅和发布信息;打开MQTT over TLS时,建连失败。首先确认mbedtls是否做了修改,这是用于传输层和应用层之间加密的功能,不能随意更改。mbedtls没有修改,则考虑系统时间是否正确,系统时间不对也会导致证书校验失败。 进行mqtt连接的时候,是否需要root.crt证书验证? 若使用TLS进行MQTT接入,需要下载根证书。 若使用物联网平台提供的demo进行开发,无需再下载根证书,demo中已自带证书。 物联网平台支持哪些QoS Level? 在MQTT协议和CCP协议下,阿里云物联网平台支持的QoS Level都包括0和1。

剑曼红尘 2020-03-05 12:51:20 0 浏览量 回答数 0

问题

五步教你如何学习前端开发

云效平台 2019-12-01 21:44:57 7061 浏览量 回答数 4

回答

简介 如果您听说过 Node,或者阅读过一些文章,宣称 Node 是多么多么的棒,那么您可能会想:“Node 究竟是什么东西?”尽管不是针对所有人的,但 Node 可能是某些人的正确选择。 为试图解释什么是 Node.js,本文探究了它能解决的问题,它如何工作,如何运行一个简单应用程序,最后,Node 何时是和何时不是一个好的解决方案。本文不涉及如何编写一个复杂的 Node 应用程序,也不是一份全面的 Node 教程。阅读本文应该有助于您决定是否应该学习 Node,以便将其用于您的业务。 Node 旨在解决什么问题? Node 公开宣称的目标是 “旨在提供一种简单的构建可伸缩网络程序的方法”。当前的服务器程序有什么问题?我们来做个数学题。在 Java™ 和 PHP 这类语言中,每个连接都会生成一个新线程,每个新线程可能需要 2 MB 配套内存。在一个拥有 8 GB RAM 的系统上,理论上最大的并发连接数量是 4,000 个用户。随着您的客户端基础的增长,您希望您的 web 应用程序支持更多用户,这样,您必须添加更多服务器。当然,这会增加业务成本,尤其是服务器成本、运输成本和人工成本。除这些成本上升外,还有一个技术问题:用户可能针对每个请求使用不同的服务器,因此,任何共享资源都必须在所有服务器之间共享。例如,在 Java 中,静态变量和缓存需要在每个服务器上的 JVMs 之间共享。这就是整个 web 应用程序架构中的瓶颈:一个服务器能够处理的并发连接的最大数量。 Node 解决这个问题的方法是:更改连接连接到服务器的方式。每个连接都创建一个进程,该进程不需要配套内存块,而不是为每个连接生成一个新的 OS 线程(并向其分配一些配套内存)。Node 声称它绝不会死锁,因为它根本不允许使用锁,它不会直接阻塞 I/O 调用。Node 还宣称,运行它的服务器能支持数万个并发连接。事实上,Node 通过将整个系统中的瓶颈从最大连接数量更改到单个系统的流量来改变服务器面貌。 现在您有了一个能处理数万条并发连接的程序,那么您能通过 Node 实际构建什么呢?如果您有一个 web 应用程序需要处理这么多连接,那将是一件很 “恐怖” 的事!那是一种 “如果您有这个问题,那么它根本不是问题” 的问题。在回答上面的问题之前,我们先看看 Node 如何工作以及它被设计的如何运行。 Node 肯定不是什么 没错,Node 是一个服务器程序。但是,它肯定不 像 Apache 或 Tomcat。那些服务器是独立服务器产品,可以立即安装并部署应用程序。通过这些产品,您可以在一分钟内启动并运行一个服务器。Node 肯定不是这种产品。Apache 能添加一个 PHP 模块来允许开发人员创建动态 web 页,使用 Tomcat 的程序员能部署 JSPs 来创建动态 web 页。Node 肯定不是这种类型。 在 Node 的早期阶段(当前是 version 0.4.6),它还不是一个 “运行就绪” 的服务器程序,您还不能安装它,向其中放置文件,拥有一个功能齐全的 web 服务器。即使是要实现 web 服务器在安装完成后启动并运行这个基本功能,也还需要做大量工作。 Node 如何工作 Node 本身运行 V8 JavaScript。等等,服务器上的 JavaScript?没错,您没有看错。服务器端 JavaScript 是一个相对较新的概念,这个概念是大约两年前在 developerWorks 上讨论 Aptana Jaxer 产品时提到的(参见 参考资料)。尽管 Jaxer 一直没有真正流行,但这个理念本身并不是遥不可及的 — 为何不能在服务器上使用客户机上使用的编程语言? 什么使 V8?V8 JavaScript 引擎是 Google 用于他们的 Chrome 浏览器的底层 JavaScript 引擎。很少有人考虑 JavaScript 在客户机上实际做了些什么?实际上,JavaScript 引擎负责解释并执行代码。使用 V8,Google 创建了一个以 C++ 编写的超快解释器,该解释器拥有另一个独特特征;您可以下载该引擎并将其嵌入任何 应用程序。它不仅限于在一个浏览器中运行。因此,Node 实际上使用 Google 编写的 V8 JavaScript 引擎并将其重建为在服务器上使用。太完美了!既然已经有一个不错的解决方案可用,为何还要创建一种新语言呢? 事件驱动编程 许多程序员接受的教育使他们认为,面向对象编程是完美的编程设计,而对其他编程方法不屑一顾。Node 使用一个所谓的事件驱动编程模型。 清单 1. 客户端上使用 jQuery 的事件驱动编程 复制代码 代码如下: // jQuery code on the client-side showing how Event-Driven programming works // When a button is pressed, an Event occurs - deal with it // directly right here in an anonymous function, where all the // necessary variables are present and can be referenced directly $("#myButton").click(function(){ if ($("#myTextField").val() != $(this).val()) alert("Field must match button text"); }); 实际上,服务器端和客户端没有任何区别。没错,这没有按钮点击操作,也没有向文本字段键入的操作,但在一个更高的层面上,事件正在 发生。一个连接被建立 — 事件!数据通过连接接收 — 事件!数据通过连接停止 — 事件! 为什么这种设置类型对 Node 很理想?JavaScript 是一种很棒的事件驱动编程语言,因为它允许匿名函数和闭包,更重要的是,任何写过代码的人都熟悉它的语法。事件发生时调用的回调函数可以在捕获事件处编写。这样,代码容易编写和维护,没有复杂的面向对象框架,没有接口,没有在上面架构任何内容的潜能。只需监听事件,编写一个回调函数,然后,事件驱动编程将照管好一切! 示例 Node 应用程序 最后,我们来看一些代码!让我们将讨论过的所有内容综合起来,创建我们的第一个 Node 应用程序。由于我们已经知道,Node 对于处理高流量应用程序很理想,我们就来创建一个非常简单的 web 应用程序 — 一个为实现最大速度而构建的应用程序。下面是 “老板” 交代的关于我们的样例应用程序的具体要求:创建一个随机数字生成器 RESTful API。这个应用程序应该接受一个输入:一个名为 “number” 的参数。然后,应用程序返回一个介于 0 和该参数之间的随机数字,并将生成的数字返回调用者。由于 “老板” 希望它成为一个广泛流行的应用程序,因此它应该能处理 50,000 个并发用户。我们来看看代码: 清单 2. Node 随机数字生成器 复制代码 代码如下: // these modules need to be imported in order to use them. // Node has several modules. They are like any #include // or import statement in other languages var http = require("http"); var url = require("url"); // The most important line in any Node file. This function // does the actual process of creating the server. Technically, // Node tells the underlying operating system that whenever a // connection is made, this particular callback function should be // executed. Since we're creating a web service with REST API, // we want an HTTP server, which requires the http variable // we created in the lines above. // Finally, you can see that the callback method receives a 'request' // and 'response' object automatically. This should be familiar // to any PHP or Java programmer. http.createServer(function(request, response) { // The response needs to handle all the headers, and the return codes // These types of things are handled automatically in server programs // like Apache and Tomcat, but Node requires everything to be done yourself response.writeHead(200, {"Content-Type": "text/plain"}); // Here is some unique-looking code. This is how Node retrives // parameters passed in from client requests. The url module // handles all these functions. The parse function // deconstructs the URL, and places the query key-values in the // query object. We can find the value for the "number" key // by referencing it directly - the beauty of JavaScript. var params = url.parse(request.url, true).query; var input = params.number; // These are the generic JavaScript methods that will create // our random number that gets passed back to the caller var numInput = new Number(input); var numOutput = new Number(Math.random() * numInput).toFixed(0); // Write the random number to response response.write(numOutput); // Node requires us to explicitly end this connection. This is because // Node allows you to keep a connection open and pass data back and forth, // though that advanced topic isn't discussed in this article. response.end(); // When we create the server, we have to explicitly connect the HTTP server to // a port. Standard HTTP port is 80, so we'll connect it to that one. }).listen(80); // Output a String to the console once the server starts up, letting us know everything // starts up correctly console.log("Random Number Generator Running..."); 将上面的代码放到一个名为 “random.js” 的文件中。现在,要启动这个应用程序并运行它(进而创建 HTTP 服务器并监听端口 80 上的连接),只需在您的命令提示中输入以下命令:% node random.js。下面是服务器已经启动并运行时它看起来的样子: 复制代码 代码如下: root@ubuntu:/home/moila/ws/mike# node random.js Random Number Generator Running... 访问应用程序 应用程序已经启动并运行。Node 正在监听任何连接,我们来测试一下。由于我们创建了一个简单的 RESTful API,我们可以使用我们的 web 浏览器来访问这个应用程序。键入以下地址(确保您完成了上面的步骤):localhost/?number=27。 您的浏览器窗口将更改到一个介于 0 到 27 之间的随机数字。单击浏览器上的 “重新载入” 按钮,将得到另一个随机数字。就是这样,这就是您的第一个 Node 应用程序! Node 对什么有好处? 到此为止,应该能够回答 “Node 是什么” 这个问题了,但您可能还不清楚什么时候应该使用它。这是一个需要提出的重要问题,因为 Node 对有一些东西有好处,但相反,对另一些东西而言,目前 Node 可能不是一个好的解决方案。您需要小心决定何时使用 Node,因为在错误的情况下使用它可能会导致一个多余编码的 LOT。 它对什么有好处? 正如您此前所看到的,Node 非常适合以下情况:您预计可能有很高的流量,而在响应客户端之前服务器端逻辑和处理所需不一定是巨大的。Node 表现出众的典型示例包括: 1.RESTful API 提供 RESTful API 的 web 服务接收几个参数,解析它们,组合一个响应,并返回一个响应(通常是较少的文本)给用户。这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它还不需要大量逻辑;它只是从一个数据库查找一些值并组合一个响应。由于响应是少量文本,入站请求时少量文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。 2.Twitter 队列 想像一下像 Twitter 这样的公司,它必须接收 tweets 并将其写入一个数据库。实际上,每秒几乎有数千条 tweets 达到,数据库不可能及时处理高峰时段需要的写入数量。Node 成为这个问题的解决方案的重要一环。如您所见,Node 能处理数万条入站 tweets。它能迅速轻松地将它们写入一个内存排队机制(例如 memcached),另一个单独进程可以从那里将它们写入数据库。Node 在这里的角色是迅速收集 tweet 并将这个信息传递给另一个负责写入的进程。想象一下另一种设计 — 一个常规 PHP 服务器自己试图处理对数据库的写入 — 每个 tweet 将在写入数据库时导致一个短暂的延迟,这是因为数据库调用正在阻塞通道。由于数据库延迟,一台这样设计的机器每秒可能只能处理 2000 条入站 tweets。每秒 100 万条 tweets 需要 500 个服务器。相反,Node 能处理每个连接而不会阻塞通道,从而能捕获尽可能多的 tweets。一个能处理 50,000 条 tweets 的 Node 机器只需要 20 个服务器。 3.映像文件服务器 一个拥有大型分布式网站的公司(比如 Facebook 或 Flickr)可能会决定将所有机器只用于服务映像。Node 将是这个问题的一个不错的解决方案,因为该公司能使用它编写一个简单的文件检索器,然后处理数万条连接。Node 将查找映像文件,返回文件或一个 404 错误,然后什么也不用做。这种设置将允许这类分布式网站减少它们服务映像、.js 和 .css 文件等静态文件所需的服务器数量。 它对什么有坏处? 当然,在某些情况下,Node 并非理想选择。下面是 Node 不擅长的领域: 1.动态创建的页 目前,Node 没有提供一种默认方法来创建动态页。例如,使用 JavaServer Pages (JSP) 技术时,可以创建一个在这样的 JSP 代码段中包含循环的 index.jsp 页。Node 不支持这类动态的、HTML 驱动的页面。同样,Node 不太适合作为 Apache 和 Tomcat 这样的网页服务器。因此,如果您想在 Node 中提供这样一个服务器端解决方案,必须自己编写整个解决方案。PHP 程序员不想在每次部署 web 应用程序时都编写一个针对 Apache 的 PHP 转换器,当目前为止,这正是 Node 要求您做的。 2. 关系数据库重型应用程序 Node 的目的是快速、异步和非阻塞。数据库并不一定分享这些目标。它们是同步和阻塞的,因为读写时对数据库的调用在结果生成之前将一直阻塞通道。因此,一个每个请求都需要大量数据库调用、大量读取、大量写入的 web 应用程序非常不适合 Node,这是因为关系数据库本身就能抵销 Node 的众多优势。(新的 NoSQL 数据库更适合 Node,不过那完全是另一个主题了。) 结束语 问题是 “什么是 Node.js?” 应该已经得到解答。阅读本文之后,您应该能通过几个清晰简洁的句子回答这个问题。如果这样,那么您已经走到了许多编码员和程序员的前面。我和许多人都谈论过 Node,但它们对 Node 究竟是什么一直很迷惑。可以理解,他们具有的是 Apache 的思维方式 — 服务器是一个应用程序,将 HTML 文件放入其中,一切就会正常运转。而 Node 是目的驱动的。它是一个软件程序,使用 JavaScript 来允许程序员轻松快速地创建快速、可伸缩的 web 服务器。Apache 是运行就绪的,而 Node 是编码就绪的。 Node 完成了它提供高度可伸缩服务器的目标。它并不分配一个 “每个连接一个线程” 模型,而是使用一个 “每个连接一个流程” 模型,只创建每个连接需要的内存。它使用 Google 的一个非常快速的 JavaScript 引擎:V8 引擎。它使用一个事件驱动设计来保持代码最小且易于阅读。所有这些因素促成了 Node 的理想目标 — 编写一个高度可伸缩的解决方案变得比较容易。 与理解 Node 是 什么同样重要的是,理解它不是 什么。Node 并不是 Apache 的一个替代品,后者旨在使 PHP web 应用程序更容易伸缩。事实确实如此。在 Node 的这个初始阶段,大量程序员使用它的可能性不大,但在它能发挥作用的场景中,它的表现非常好。 将来应该期望从 Node 得到什么呢?这也许是本文引出的最重要的问题。既然您知道了它现在的作用,您应该会想知道它下一步将做什么。在接下来的一年中,我期待着 Node 提供与现有的第三方支持库更好地集成。现在,许多第三方程序员已经研发了用于 Node 的插件,包括添加文件服务器支持和 MySQL 支持。希望 Node 开始将它们集成到其核心功能中。最后,我还希望 Node 支持某种动态页面模块,这样,您就可以在 HTML 文件中执行在 PHP 和 JSP(也许是一个 NSP,一个 Node 服务器页)中所做的操作。最后,希望有一天会出现一个 “部署就绪” 的 Node 服务器,可以下载和安装,只需将您的 HTML 文件放到其中,就像使用 Apache 或 Tomcat 那样。Node 现在还处于初始阶段,但它发展得很快,可能不久就会出现在您的视野中。 答案来源于网络

养狐狸的猫 2019-12-02 02:17:03 0 浏览量 回答数 0

问题

【精品问答】Java必备核心知识1000+(附源码)

问问小秘 2019-12-01 22:00:28 870 浏览量 回答数 1

问题

【Java学习全家桶】1460道Java热门问题,阿里百位技术专家答疑解惑

管理贝贝 2019-12-01 20:07:15 27612 浏览量 回答数 19

问题

程序员报错QA大分享(1)

问问小秘 2020-06-18 15:46:14 8 浏览量 回答数 1
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 SQL审核 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站 人工智能 阿里云云栖号 云栖号案例 云栖号直播