node

阅读 / 问答 / 标签

nodejs中的resolve是什么意思

promise接受两个参数,一个人reject,一个是resolve,表示成功时候执行的函数

node中path.resolve()用法

1、不带参数时 path.resolve() 返回的是当前的文件的绝对路径 /Users/xxxx/ 2、带不是 / 开头的参数 path.resolve("a") 返回的是当前绝对路径拼接现在的参数 /Users/xxxx/a path.resolve("a","b") 返回的是当前绝对路径拼接现在的参数 /Users/xxxx/a/b 3、带 ./ 开头的参数 path.resolve("./a") 返回的是当前绝对路径拼接现在的参数 /Users/xxxx/a path.resolve("./a","./b") 返回的是当前绝对路径拼接现在的参数 /Users/xxxx/a/b 4、带 / 开头的参数 返回的是 /+‘最后一个前面加/的文件文件名"+‘剩下文件夹 path.resolve("/a") 返回的是当前绝对路径拼接现在的参数 /a path.resolve("/a","/b") 返回的是当前绝对路径拼接现在的参数 /b path.resolve("/a","/b", "c") 返回的是当前绝对路径拼接现在的参数 /b/c 其他 Node.js 中, __dirname 总是指向被执行 js 文件的绝对路径

电驴kad节点的nodes.dat作用是什么?

nodes.dat保存有kad网络的节点信息,用来引导你连上kad网络。如果你对下载的nodes.dat不放心,可以到官方网站自行下载www.nodes-dat.com

如何搭建webdriver+selenium+nodejs自动化测试框架

  1  安装nodejs程序包  2  打开nodejs  从开始程序中选择Node.js--->Node.js command prompt  3  在命令窗口输入以下命令  一、npm install webdreverio -g  二、npm install selenium-standalone@latest -g  4  安装selenium服务,在命令窗口输入以及下命令  selenium-standalone install  此时会报错,告诉你IE和谷歌驱动安排不成功  解决方法:新此目录下的C:UserssaberAppDataRoaming pm ode_modulesselenium-standalone.selenium的chromedriver和iedriver文件夹替换掉  5  配置环境变量  编辑用户变量:  变量名:PATH  变量值:C:UserssaberAppDataRoaming pm  新建系统变量:  变量名:node_path  变量值:C:UserssaberAppDataRoaming pm ode_modules  6  开启selenium服务,在命令窗口输入以下命令  selenium-standalone start  7  打开cmd窗口,输入脚本的位置  8  运行自动化测试脚本  至此,webdriver+selenium+nodejs的自动化框架就搭建完成,大家尽情编写js脚本吧。

node.js里res.render是什么意思

node.js里res.render是express中专门渲染视图用的。根据查询相关资料信息显示:Node.js发布于2009年5月,由RyanDahl开发,是一个基于ChromeV8引擎的JavaScript运行环境,使用了一个事件驱动、非阻塞式模型,让JavaScript在服务端的开发平台运行。

int size=sizeof(struct stud node)什么意思

返回结构体的长度

webstrom怎么启动node

webstorm中新建项目后比如:node.js项目 项目路径中有bin目录,目录中有个www的文件。可以debug或者run这个文件,代表启动应用。 如下图:

webstrom调试node怎么失效了

在webStorm中调试node.js程序,不使用命令行形式、不使用node-inspector模块调试,纯粹使用webStorm调试可能是你的环境的问题。 webstorm那个版本的都可以集成调试。 注意启动程序的时候使用debug 模式次可以调试。

nodeb通过什么接口与rnc相连

Iur用于呼叫切换的RNC到RNC连接,通常通过OC-3链路实现。lu-csRNC与电路交换语音网络之间的核心网接口。通常作为OC-12速率链路实施。lu-psRNC与分组交换数据网络之间的核心网接口。通常作为OC-12速率链路实施。

大唐nea和nodeb断链什么意思

1、OML:Operation and Maintenance Link 操作维护链路;2、2G网络中,在基站和NodeB之间的接口成为Abis口。该接口是一个私有接口,在不同的厂家间是不公开的Abis接口中包含了3中链路:(1)、OML操作维护链路,是用来传递基站的控制命令的,通常后台所作的修改就是通过此链路发给基站;(2)、Sig信令链路,用于传递BSC与BTS之间的带外信令(3)、Trf业务链路,用于传递业务。通常开通基站时,首先要检查的就是OML,如果OML不同,那么是没有办法对基站进行任何操作的。3、一旦OML链路中断,那么基站会失去控制,也就是说后台的BAM上或者,网管上就无法对该基站进行任何额操作或者管理;4、一般出现OML中断的原因有:(1)传输链路断,导致OML链路断;(2)基站接口板出现问题;(3)基站或者NodeB上的数据配置错误。

nodejs怎么接入thrift

1、进入thrift.exe所在目录执行thrift-0.9.2.exe –gen js:node hello.thrift编译hello.thrift生成nodejs的实现文件。2、在cmd窗口进入生成的gen-nodejs目录,使用npm install thrift安装nodejs的thrift模块,安装完多了一个node_modules目录。3、新建一个js文件作为thrift的客户端。内容如下://引入thrift模块var thrift = require("thrift");//引入hello服务定义文件在同一路径下也要加 ./var Hello = require("./Hello.js"),ttypes = require("./hello_types");//创建连接和客户端var connection = thrift.createConnection("localhost", 19090),client = thrift.createClient(Hello, connection);//连接connection.on("error", function(err) {console.error(err);});//调用helloString函数console.log(client.helloString("tomdog").toString());4、启动上一篇文章中Java server程序,用node指令运行nodejsclient.js,看到控制台输出:[object Promise]。在这里js把Java返回的string当成object。

如何使用NodeManager管理WebLogic集群

1. 首先,要确认在安装Weblogic Server的过程中,勾选NodeManager选项,如下图,默认是不选中的,为了后期能简单的使用节点管理器,这里需要选择Yes,然后完成软件安装。2. 其次,创建Domain的过程参考:a) 选择创建Domain的类型b) 确认创建Domain的类型a) 确认集群名称b) 确认管理员用户名、口令c) 选择Domain的模式d) 选择修改Domain选项Yes,选择不配置DBMSe) 确认主管服务器的IP地址、端口、名称f) 确认受管服务器的IP地址、端口、名称g) 确认集群的地址、端口、名称h) 确认集群中有哪些受管服务i) 确认代理服务器的配置j) 确认物理服务器的信息(以Linux服务器为例)k) 确认哪些服务器运行在哪些物理机器上l) 确认集群Domain创建设置m) 完成集群创建3. 配置weblogic访问口令脚本要确认在启动Domain的Server时,不需要输入用户名、口令,方法(Linux平台,Windows平台参考修改setDomainEnv.cmd)如下:a) 第一步,按11g版本前的方法,在自己的${DOMAIN_HOME}文件夹下,创建boot.properties文件,内容为:username=weblogicpassword=welcome1b) 第二步,修改${DOMAIN_HOME}/bin文件夹下的setDomainEnv.sh,找到【# SET THE CLASSPATH】这行,修改其上面两行内容:从:JAVA_OPTIONS="${JAVA_OPTIONS}"export JAVA_OPTIONS修改为:JAVA_OPTIONS="${JAVA_OPTIONS} -Dweblogic.system.BootIdentityFile=${DOMAIN_HOME}/boot.properties"export JAVA_OPTIONS4. 配置主机名与IP映射关系要确认主机名与IP地址有对应关系,修改主机的hosts文件,加入192.168.182.12 oradb2这里,如果发现127.0.0.1对应到了oradb2这个主机名,应将其对应去掉,只需要127.0.0.1映射到localhost即可。5. 如何用NodeManager管理集群服务器为了能让nodemanager可以管理weblogic的domain,必须先启动nodemanager进程,方法为:cd /home/weblogic/bea/wlserver_10.3/server/bin./startNodeManager.sh接下来,可以启动AdminServer,方法为:cd /home/weblogic/bea/user_projects/domains/my_domain/bin./startWebLogic.sh接下来的服务都可以在weblogic的console中进行启动了,登录访问控制台页面:http://192.168.182.12:7001/console点击服务器,打开服务器管理页面:点击【控制】标签页,要管理哪个服务器,就勾选哪个,比如勾选MS_1,点击【启动】,就可以完成MS_1这个服务器:点击【是】按钮:这时【MS_1】,状态已经为STARTING等待一段时间后:最终MS_1就正常运行了,状态RUNNING我们还可以对节点进行其他管理,比如挂起、恢复等操作:我们从NodeManager的日志中,就可以看出MS_1已经正常启动了,要停止时,按上图,选中MS_1,点击停止即可。[weblogic@oradb2 domains]$ cd /home/weblogic/bea/wlserver_10.3/server/bin[weblogic@oradb2 bin]$ ./startNodeManager.sh+ CLASSPATH=/home/weblogic/bea/patch_wls1032/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/bea/jrockit_160_14_R27.6.5-32/lib/tools.jar:/home/weblogic/bea/utils/config/10.3/config-launch.jar:/home/weblogic/bea/wlserver_10.3/server/lib/weblogic_sp.jar:/home/weblogic/bea/wlserver_10.3/server/lib/weblogic.jar:/home/weblogic/bea/modules/features/weblogic.server.modules_10.3.2.0.jar:/home/weblogic/bea/wlserver_10.3/server/lib/webservices.jar:/home/weblogic/bea/modules/org.apache.ant_1.7.0/lib/ant-all.jar:/home/weblogic/bea/modules/net.sf.antcontrib_1.0.0.0_1-0b2/lib/ant-contrib.jar::/home/weblogic/bea+ export CLASSPATH+ export PATH+ cd /home/weblogic/bea/wlserver_10.3/common/nodemanager+ set -x+ "[" "" "!=" "" "]"+ "[" "" "!=" "" "]"+ /home/weblogic/bea/jrockit_160_14_R27.6.5-32/bin/java -jrockit -Xms128m -Xmx256m -Xverify:none -Djava.security.policy=/home/weblogic/bea/wlserver_10.3/server/lib/weblogic.policy -Dweblogic.nodemanager.javaHome=/home/weblogic/bea/jrockit_160_14_R27.6.5-32 weblogic.NodeManager -v<2013-2-6 12:51:13>2013-2-6 12:51:13 weblogic.nodemanager.server.NMServerConfig initDomainsMap信息: Loading domains file: /home/weblogic/bea/wlserver_10.3/common/nodemanager/nodemanager.domains<2013-2-6 12:51:14>2013-2-6 12:51:14 weblogic.nodemanager.server.SSLConfig loadKeyStoreConfig信息: Loading identity key store: FileName=/home/weblogic/bea/wlserver_10.3/server/lib/DemoIdentity.jks, Type=jks, PassPhraseUsed=true<2013-2-6 12:51:15>2013-2-6 12:51:15 weblogic.nodemanager.server.NMServer信息: Loaded node manager configuration properties from "/home/weblogic/bea/wlserver_10.3/common/nodemanager/nodemanager.properties"Node manager v10.3Configuration settings:NodeManagerHome=/home/weblogic/bea/wlserver_10.3/common/nodemanagerListenAddress=ListenPort=5556ListenBacklog=50SecureListener=trueAuthenticationEnabled=trueNativeVersionEnabled=trueCrashRecoveryEnabled=falseJavaHome=/home/weblogic/bea/jrockit_160_14_R27.6.5-32/jreStartScriptEnabled=falseStopScriptEnabled=falseStartScriptName=startWebLogic.shStopScriptName=LogFile=/home/weblogic/bea/wlserver_10.3/common/nodemanager/nodemanager.logLogLevel=INFOLogLimit=0LogCount=1LogAppend=trueLogToStderr=trueLogFormatter=weblogic.nodemanager.server.LogFormatterDomainsFile=/home/weblogic/bea/wlserver_10.3/common/nodemanager/nodemanager.domainsDomainsFileEnabled=trueStateCheckInterval=500Interface=NetMask=UseMACBroadcast=falseDomain name mappings:my_domain -> /home/weblogic/bea/user_projects/domains/my_domain

如何使用NodeManager管理WebLogic集群

  1. 首先,要确认在安装Weblogic Server的过程中,勾选NodeManager选项,如下图,默认是不选中的,为了后期能简单的使用节点管理器,这里需要选择Yes,然后完成软件安装。  2. 其次,创建Domain的过程参考:  a) 选择创建Domain的类型    b) 确认创建Domain的类型  a) 确认集群名称    b) 确认管理员用户名、口令    c) 选择Domain的模式    d) 选择修改Domain选项Yes,选择不配置DBMS    e) 确认主管服务器的IP地址、端口、名称    f) 确认受管服务器的IP地址、端口、名称    g) 确认集群的地址、端口、名称    h) 确认集群中有哪些受管服务    i) 确认代理服务器的配置    j) 确认物理服务器的信息(以Linux服务器为例)    k) 确认哪些服务器运行在哪些物理机器上    l) 确认集群Domain创建设置    m) 完成集群创建    3. 配置weblogic访问口令脚本  要确认在启动Domain的Server时,不需要输入用户名、口令,方法(Linux平台,Windows平台参考修改setDomainEnv.cmd)如下:  a) 第一步,按11g版本前的方法,在自己的${DOMAIN_HOME}文件夹下,创建boot.properties文件,内容为:  username=weblogic  password=welcome1  b) 第二步,修改${DOMAIN_HOME}/bin文件夹下的setDomainEnv.sh,找到【# SET THE CLASSPATH】这行,修改其上面两行内容:  从:  JAVA_OPTIONS="${JAVA_OPTIONS}"export JAVA_OPTIONS  修改为:  JAVA_OPTIONS="${JAVA_OPTIONS} -Dweblogic.system.BootIdentityFile=${DOMAIN_HOME}/boot.properties"export JAVA_OPTIONS  4. 配置主机名与IP映射关系  要确认主机名与IP地址有对应关系,修改主机的hosts文件,加入  192.168.182.12 oradb2  这里,如果发现127.0.0.1对应到了oradb2这个主机名,应将其对应去掉,只需要127.0.0.1映射到localhost即可。    5. 如何用NodeManager管理集群服务器  为了能让nodemanager可以管理weblogic的domain,必须先启动nodemanager进程,方法为:  cd /home/weblogic/bea/wlserver_10.3/server/bin  ./startNodeManager.sh  接下来,可以启动AdminServer,方法为:  cd /home/weblogic/bea/user_projects/domains/my_domain/bin  ./startWebLogic.sh  接下来的服务都可以在weblogic的console中进行启动了,登录访问控制台页面:http://192.168.182.12:7001/console    点击服务器,打开服务器管理页面:    点击【控制】标签页,要管理哪个服务器,就勾选哪个,比如勾选MS_1,点击【启动】,就可以完成MS_1这个服务器:    点击【是】按钮:    这时【MS_1】,状态已经为STARTING    等待一段时间后:    最终MS_1就正常运行了,状态RUNNING

Node.js命令行/批处理中如何更改Linux用户密码浅析

option主要为一些密码加密选项-c, --crypt-methodUse the specified method to encrypt the passwords.The available methods are DES, MD5, NONE, and SHA256 or SHA512 if your libc support these methods.-e, --encryptedSupplied passwords are in encrypted form.-h, --helpDisplay help message and exit.-m, --md5Use MD5 encryption instead of DES when the supplied passwords are not encrypted.-s, --sha-roundsUse the specified number of rounds to encrypt the passwords.The value 0 means that the system will choos输入命令后,按 username:password 格式输入用户名密码,一行一个,如:chpasswdnewghost:4567用这种方法可在node.js中使用:var cp = require("child_process")//更新密码var chpasswd = cp.spawn("chpasswd")var errmsg//查看是否有错误chpasswd.stderr.on("data", function (data) { errmsg += data.toString()})chpasswd.on("exit", function(code) { if (cb) { errmsg ? cb(new Error(errmsg)) : cb() }})//写入密码chpasswd.stdin.write(username + ":" + password)chpasswd.stdin.end()总结

利用node.js如何创建子进程详解

前言node本身为单进程,并使用驱动模式处理并发,为了解决单进程在多核cpu上的资源浪费,node提供了cluster和child_process模块来创建多个子进程。Node.js是单线程的,对于现在普遍是多处理器的机器是一种浪费,怎么能利用起来呢?于是child_process模块出现了。child_process模块可以在其他进程上产生、派生,并执行工作。child_process模块提供了一个ChildProcess的新类,它可以作为从父进程访问子进程的表示形式。Process模块也是ChildProcess对象。当你从父模块访问process时,它是父ChildProcess对象,当你从子进程访问Process是,它是ChildProcess对象了解一个对象无外乎事件、方法、属性。ChildProcess也是一样。每个子进程总带有三个流对象:child.stdin、child.stdout、child.stderr。他们可能会共享父进程的stdio流。这里我们先介绍利用child_process模块中exec、spawn、fork三个方法对子进程的操作。建立node-childProcess文件,在其中创建node-childPro.js文件。其中就一行代码如下:console.log("进程 " + process.argv[2] + " 执行。" );//换成下面的查看process.argv//console.log("进程 " + process.argv + " 执行。" );exec()方法在node-childProcess文件中新建node-childPro-exec.js文件,其中代码如下:const fs = require("fs");const child_process = require("child_process");for (var i = 0; i < 3; i++) { //这里有空格请注意。分别代表node路径 node-childPro.js路径 i第几个进程。 node-childPro.js中的process.argv可以获取这些信息值 var childProcess = child_process.exec("node node-childPro.js "+i, // 回调函数 子进程的输出以回调函数参数的形式返回 function (error, stdout, stderr) { if (error) { console.log(error.stack); console.log("Error code: " + error.code); console.log("Signal received: " + error.signal); } console.log("stdout: " + stdout); console.log("stderr: " + stderr); }); childProcess.on("exit", function (code) { console.log("子进程已退出,退出码 " + code); });}终端执行代码结果如下:G: ode ode-childProcess> node node-childPro-exec.js子进程已退出,退出码 0stdout: 进程 0 执行。stderr:子进程已退出,退出码 0stdout: 进程 1 执行。stderr:子进程已退出,退出码 0stdout: 进程 2 执行。stderr:spawn()方法在node-childProcess文件中新建node-childPro-spawn.js,其中代码如下:const fs = require("fs");const child_process = require("child_process"); for(var i=0; i<3; i++) { var childProcess = child_process.spawn("node", ["node-childPro-spawn.js", i]); childProcess.stdout.on("data", function (data) { console.log("stdout: " + data); });childProcess.stderr.on("data", function (data) { console.log("stderr: " + data); }); childProcess.on("close", function (code) { console.log("子进程已退出,退出码 "+code); });}终端执行代码结果如下:G: ode ode-childProcess> node node-childPro-spawn.jsstdout: 进程 0 执行。子进程已退出,退出码 0stdout: 进程 1 执行。stdout: 进程 2 执行。子进程已退出,退出码 0子进程已退出,退出码 0fork()方法在node-childProcess文件中新建node-childPro-fork.js,其中代码如下:const fs = require("fs");const child_process = require("child_process"); for(var i=0; i<3; i++) { var childProcess = child_process.fork("node-childPro.js", [i]); childProcess.on("close", function (code) { console.log("子进程已退出,退出码 " + code); });}终端执行代码结果如下:G: ode ode-childProcess> node node-childPro-fork.js进程 0 执行。进程 1 执行。子进程已退出,退出码 0进程 2 执行。子进程已退出,退出码 0子进程已退出,退出码 0关于exec、spawn、fork 1.exec函数是对spawn的一种友好封装,增加Shell命令解析,可以直接嵌入复杂的命令 2.exec函数缓存子进程的输出,并将子进程的输出以回调函数参数的形式返回 3.spawn在子线程开始执行后,就开始不断将数据从子进程返回给主进程(应用场景如“系统监控”) 4.spawn是不支持callback函数的,它通过流的方式发数据传给主进程,从而实现了多进程之间的数据交换 5.fork()是spawn()的特殊情景,用于派生Node进程。除了普通ChildProcess实例所具有的所有方法,所返回的对象还具有内建的通讯通道。下载地址:https://gitee.com/wangFengJ/node/tree/master/node-childProcess总结

使用travis-ci如何持续部署node.js应用详解

前言在开始之前,我们先来简单介绍下Travis-ci,Travis-ci是一款持续集成(Continuous Integration)服务,它能够很好地与Github结合,每当代码更新时自动地触发集成过程。Travis-ci配置简单,很多nodejs项目都用它做自动测试。然而,对于持续集成,仅做到自动测试是不够的,还要有后续的自动部署,才能完成“提交代码 => 自动测试 => 自动部署”的集成链条。本文以nodejs应用为例,来谈谈如何利用travis-ci完成自动部署。话不多说,来一起看看详细的介绍:基本原理从自动测试到自动部署的核心问题是测试机与生产服务器的信任问题,即如何安全地把程序包传输到生产服务器。市面上的部署工具如scp、ansible、chef,都绕不开这个核心问题。以scp为例,测试机登录生产服务器的方式有两种:密码和秘钥。密码登录方式需要交互式地输入密码,总不能每次测试的时候,人为地输入密码吧,所以密码方式行不通。秘钥的方式可以实现自动登录,但首次将测试机的公钥传输给生产服务器仍然需要密码。似乎走入了死胡同,但办法总是有的。我们知道开发机是可以登录到生产服务器的,那么我们就可以将开发机的公钥复制到生产服务器,将开发机的私钥复制到测试机,测试机通过私钥来伪装成开发机,自动地登录到生产服务器。解决了自动登录的问题,另一个问题是怎么将开发机的私钥复制到测试机上。由于测试机每次都是新开的一个虚拟机,这个新开的虚拟机IP不固定,所以没办法直接登录上去。解决办法是将私钥文件作为代码库的一部分提交,这样测试机每次从代码库上拉取代码的同时也获取到了秘钥文件,通过这种方式就实现了私钥从开发机复制到测试机。将私钥文件提交到代码库有一个很严重的安全性问题,即任何人只要得到了这个私钥文件,他就可以随心所欲的操纵生产服务器。幸好,travis-ci提供了加密方案,它能够将私钥文件加密,加密后的文件只在当前代码库有效。总的来说,通过复制私钥完成自动登录以及对私钥加密来保障安全性,我们就可以建立起测试机与生产服务器的信任通道,测试机就可以安全地操作生产服务器完成自动部署。配置现在我以scp方式部署nodejs应用为例,来说明travis-ci做自动部署的配置。首先,建立起开发机与生产服务器的信任关系:ssh-copy-id username@host然后,加密你的私钥,私钥文件通常在~/.ssh/id_rsa。加密私钥文件需要使用travis这个命令行工具,它是一个ruby包,使用gem安装:gem install travistravis login输入账号密码登录成功后,使用travis encrypt-file加密:travis encrypt-file ~/.ssh/id_rsa --add上面命令执行完后,会生成一段解密命令并添加到.travis.yml中:before_install: - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv -in ~/.ssh/id_rsa.enc -out ~/.ssh/id_rsa -d接下来,把加密后的私钥文件(id_rsa.enc)复制到代码库中,千万要注意不要错把未加密的私钥文件(id_rsa)复制到你的代码库中。然后把上面的解密命令的-in ~/.ssh/id_rsa.enc改为-in id_rsa.enc。通过上面的过程就基本建立测试机与生产服务器的信任关系,但还有一些小细节要处理。例如,降低id_rsa文件的权限,否则ssh处于安全方面的原因会拒绝读取秘钥;将生产服务器地址加入到测试机的信任列表中,否则连接时会询问是否信任服务器。更改后的配置如下:before_install: - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d - chmod 600 ~/.ssh/id_rsa - echo -e "Host 102.201.64.94 StrictHostKeyChecking no " >> ~/.ssh/config最后,测试机就可以愉快地操作生产服务器了,例如下面是一个nodejs应用的.travis.yml文件配置:language: node_jsnode_js: - "4.4.4"before_install: - openssl aes-256-cbc -K $encrypted_830d3b21a25d_key -iv $encrypted_830d3b21a25d_iv -in id_rsa.enc -out ~/.ssh/id_rsa -d - chmod 600 ~/.ssh/id_rsa - echo -e "Host 102.201.64.94 StrictHostKeyChecking no " >> ~/.ssh/configscript: - npm run testafter_success: - npm prune --production # 删除devDependencies - tar -jcf indoor-server.tar.bz2 * # 打包并压缩代码 - scp indoor-server.tar.bz2 jingsam@102.201.64.94:~/ # 复制到生产服务器上 - ssh jingsam@102.201.64.94 "mkdir -p indoor-server && tar -jxf indoor-server.tar.bz2 -C indoor-server" # 解压 - ssh jingsam@102.201.64.94 "cd indoor-server && pm2 startOrReload pm2.json" # 重启pm2总结本篇文章讲的自动部署其实与nodejs关系不大,完全适用于各种语言的自动部署,其原理都是相通的。好了,

如何在Node.js中使用原生ES模块

从版本 8.5.0 开始,Node.js 开始支持原生 ES 模块,可以通过命令行选项打开该功能。新功能很大程度上得归功于 Bradley Farias。本文主要和大家介绍在 Node.js 中使用原生 ES 模块方法解析,还有部分内容的链接,下面我们就来一起看看吧,需要的朋友可以参考下,希望能帮助到大家。1.演示这个示例的代码目录结构如下:lib.mjs:main.mjs:运行演示:2.清单:需要注意的事情ES 模块:·不能动态导入模块。但是 动态import() 的相关工作正在进行中,应该很快就能提供支持。·没有元变量,如 __dirname 和 __filename。但是,有一个的类似功能的提案:“import.meta”。看起来可能是这样:·现在所有模块标识符都是 URL(这部分在 Node.js 是新增的):·文件 - 带文件扩展名的相对路径: ../util/tools.mjs·库 - 没有文件扩展名,也没有路径 lodash·如何更好地使 npm 库在浏览器中也可用(不使用 bundler)仍有待观察。一种可能性是引入 RequireJS 风格的配置数据,将路径映射到实际路径。目前,在浏览器中使用 bare path 的模块标识符是非法的。与 CJS 模块的互操作性你可以导入 CJS 模块,但它们总是只有默认的导出 - 即 module.exports 的值。让 CJS 模块支持命名导出已经在做了,但可能需要一段时间。如果你能帮忙,可以来做。 · 不能在 ES 模块中使用 require()。主要原因是: · 路径解析工作稍有不同:ESM 不支持 NODE_PATH 和 require.extensions。而且,它的标识符始终是 URL 也会导致一些细微差异。 · ES 模块始终以异步方式加载,这确保了与 Web 的最大兼容性。这种加载风格并不能通过 require() 混合使用同步加载 CJS 模块。 · 禁止同步模块加载也可以为 Top-level await 导入 ES 模块保留后路(一个当前正在考虑的功能)。3.早期版本的 Node.js 上的 ES 模块如果要在 8.5.0 之前的 Node.js 版本上使用 ES 模块,请参阅 John-David Dalton 的 @std/esm。提示:如果不启用任何可解锁的额外功能,将在 Node.js 保持 100% 兼容原生 ES 模块.FAQ什么时候可以不带命令行选项使用ES 模块?目前的计划是在 Node.js 10 LTS 中默认可使用 ES 模块。进一步阅读有关 Node.js 和浏览器中 ES 模块的更多信息: · “Making transpiled ES modules more spec-compliant” [using ES modules natively vs. transpiling them via Babel] · “Module specifiers: what"s new with ES modules?” [Why .mjs? How are module specifiers resolved? Etc.] · “Modules” [in-depth chapter on ES modules in “Exploring ES6”]即将到来的 ECMAScript 提案: · 博客: “ES proposal: import() _ dynamically importing ES modules” · 提案: “import.meta”

NameNode HA实现原理

前言 :在Hadoop 1.x版本,HDFS集群的NameNode一直存在单点故障问题:集群只存在一个NameNode节点,它维护了HDFS所有的元数据信息,当该节点所在服务器宕机或者服务不可用,整个HDFS集群都将处于不可用状态,极大限制了HDFS在生产环境的应用场景。直到Hadoop 2.0版本才提出了高可用 (High Availability, HA) 解决方案,并且经过多个版本的迭代更新,已经广泛应用于生产环境。 解决方案 :在同一个HDFS集群,运行两个互为主备的NameNode节点。一台为主Namenode节点,处于Active状态,一台为备NameNode节点,处于Standby状态。其中只有Active NameNode对外提供读写服务,Standby NameNode会根据Active NameNode的状态变化,在必要时切换成Active状态。 【NameNode HA架构图】 HealthMonitor 定时调用NameNode的HAServiceProtocol RPC接口(monitorHealth和getServiceStatus),监控NameNode的健康状态并向ZKFC反馈; ActiveStandbyElector 接收ZKFC的选举请求,通过Zookeeper自动完成主备选举,选举完成后回调ZKFC的主备切换方法对NameNode进行Active和Standby状态的切换; JouranlNode集群 共享存储系统,负责存储HDFS的元数据,Active NameNode(写入)和Standby NameNode(读取)通过共享存储系统实现元数据同步,在主备切换过程中,新的Active NameNode必须确保元数据同步完成才能对外提供服务; ZKFailoverController在启动时同时会初始化HealthMonitor和ActiveStandbyElector服务,同时也会向HealthMonitor和ActiveStandbyElector注册相应的回调方法: HealthMonitor检测NameNode的两类状态,HealthMonitor.State和HealthMonitor.HAServiceStatus。在程序上启动一个线程循环调用NameNode的HAServiceProtocol RPC接口的方法来检测NameNode 的状态,并将状态的变化通过回调的方式来通知ZKFailoverController。 当HealthMonitor检测到NameNode的健康状态或角色状态发生变化时,ZKFC会根据状态的变化决定是否需要进行主备选举。 HealthMonitor.State状态变化导致的不同后续措施: HAServiceStatus在状态检测之中仅起辅助的作用,当HAServiceStatus发生变化时,ZKFC会判断NameNode返回的HAServiceStatus与ZKFC所期望的是否相同,如果不相同,ZKFC会调用ActiveStandbyElector的quitElection方法删除当前已经在ZK上建立的临时节点退出主备选举。 ZKFC通过ActiveStandbyElector的joinElection方法发起NameNode的主备选举,这个过程通过Zookeeper的写一致性和临时节点机制实现: a. 当发起一次主备选举时,Zookeeper会尝试创建临时节点 /hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock ,Zookeeper的写一致性保证最终只会有一个ActiveStandbyElector创建成功,创建成功的 ActiveStandbyElector对应的NameNode就会成为主NameNode,ActiveStandbyElector回调ZKFC的方法将对应的NameNode切换为Active状态。而创建失败的ActiveStandbyElector对应的NameNode成为备NameNode,ActiveStandbyElector回调ZKFC的方法将对应的NameNode切换为Standby状态; b. 不管是否选举成功,所有ActiveStandbyElector都会向Zookeeper注册一个Watcher来监听这个节点的状态变化事件; c. 如果Active NameNode对应的HealthMonitor检测到NameNode状态异常时,ZKFC会删除在Zookeeper上创建的临时节点ActiveStandbyElectorLock,这样处于Standby NameNode的ActiveStandbyElector注册的Watcher就会收到这个节点的 NodeDeleted事件。收到这个事件后,会马上再次创建ActiveStandbyElectorLock,如果创建成功,则Standby NameNode被选举为Active NameNode。 【防止脑裂】 在分布式系统中脑裂又称为双主现象,由于Zookeeper的“假死”,长时间的垃圾回收或其它原因都可能导致双Active NameNode现象,此时两个NameNode都可以对外提供服务,无法保证数据一致性。对于生产环境,这种情况的出现是毁灭性的,必须通过自带的隔离(Fencing)机制预防这种现象的出现。 ActiveStandbyElector为了实现fencing隔离机制,在成功创建 hadoop-ha/dfs.nameservices/ActiveStandbyElectorLock 临时节点 后,会创建另外一个 /hadoopu2212ha/{dfs.nameservices}/ActiveBreadCrumb 持久节点 ,这个持久节点保存了Active NameNode的地址信息。当Active NameNode在正常的状态下断开Zookeeper Session (注意由于 /hadoop-ha/dfs.nameservices/ActiveStandbyElectorLock 是临时节点,也会随之删除),会一起删除持久节点 /hadoopu2212ha/{dfs.nameservices}/ActiveBreadCrumb 。但是如果ActiveStandbyElector在异常的状态下关闭Zookeeper Session,那么由于 /hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 是持久节点,会一直保留下来。当另一个NameNode (standy => active) 选主成功之后,会注意到上一个Active NameNode遗留下来的ActiveBreadCrumb节点,从而会回调ZKFailoverController的方法对旧的Active NameNode进行fencing。 ① 首先ZKFC会尝试调用旧Active NameNode的HAServiceProtocol RPC接口的transitionToStandby方法,看能否将状态切换为Standby; ② 如果调用transitionToStandby方法切换状态失败,那么就需要执行Hadoop自带的隔离措施,Hadoop目前主要提供两种隔离措施: sshfence:SSH to the Active NameNode and kill the process; shellfence:run an arbitrary shell command to fence the Active NameNode; 只有在成功地执行完成fencing之后,选主成功的ActiveStandbyElector才会回调ZKFC的becomeActive方法将对应的NameNode切换为Active,开始对外提供服务。 博客主页: https://www.jianshu.com/u/e97bb429f278

ansys中nodes与keypoints的区别

一般用的都是keypoint,创建关键点;而point起划分作用。

idontbelieveinnodevil什么歌

I Don"t Believe in the Devil歌手:Erik Corona所属专辑:A Minimal Story作曲 : T. Magnussons

如何复用node.js包或代码

Meteor基于Node.js,但是却有自己的包管理系统(atmosphere)以及代码加载机制,且meteor是非异步的,这些都意味着,node.js包(npm package)和代码通常不能直接用于meteor程序。这里分享三种方法以在meteor中复用node.js包和代码。meteorhacks:npm + meteorhacks:asyncnpm+async是复用npm包最便捷的方式。meteor程序添加npm包之后,便可以在packages.json中声明包依赖,在程序中通过Meteor.npmRequire来加载包。值得一提的是,由于大部分npm包都是异步调用的,而meteor是同步运行的,所以需要某种方法将异步调用转为同步调用。async就是这样一个meteor包,添加之后,通过Async.runSync方法便可以同步地调用异步方法。具体安装、使用方法以及更多介绍,请参考文档。适配node.js代码如果需要复用的代码仅仅是个别文件、函数、片段等,可以手工修改代码以适配meteor程序。需要注意到,node.js的每一个文件都是一个模块,通过module.exports和require进行组织,但是在meteor中,每一个文件都是会被自动加载的(具体顺序参考meteor文档),通过全局变量进行跨文件调用;meteor中不能直接加载npm包;meteor框架是同步运行的(非异步)。综上,适配代码的工作包括:使用meteorhacks:npm来加载npm包修改跨文件调用方式,将原来的module.exports=xxx改为暴露全局变量,而调用方,将require(xxx)改为直接引用全局变量直接被meteor框架调用的方法,使用meteorhacks:async包,将其从异步调用改为同步调用形式创建meteor包这种方法更复杂,但是也更进阶,不仅可以封装npm包,也能封装任意node.js代码(当然需要修改、适配),更能创建新的meteor包。创建meteor包的具体方法不再赘述,参考如下:Writing Meteor Packagespackage.js docMeteor Packages Tutorial学会创建meteor包之后,只需要按照上述方法适配代码,并封装成meteor包,便可以方便地使用和分享了。参考项目meteor-submail该项目规模很小,便于分析。原始代码在submail-sdk文件夹中,其余代码为对原始代码的适配和封装。

如何复用node.js包或代码

打包成模块

enodeb包括以下哪些功能

  无线接入网络(RAN)包含一个或者多个无线网络子系统(RNS),每一个RNS又是由一个无线网络控制器(RNC)和一个或者多个NodeB组成的。 无线网络控制器(RNC)用于控制UTRAN的无线资源。RNC一般与一个MSC和一个SGSN或者广播域(BC Domain)通过Iu.  ENodeB 简称 ENB,可以理解为基站。负责UE(可理解为手机)的电话调度等。MME(移动性管理实体)负责UE移动性管理,比如漫游、切换。PGW(PND-GW(网关))负责UE网络用户面的管理,SGW(serving-GW)负责UE网络控制面管理。看看lte方面资料会了解多些。  首先你弄明白什么是网络,就是一堆设备连接在一块,可以相互通信的结构。我们把其中每个设备抽象出来当成一个节点,可称为逻辑节点。逻辑节点还有一层意思是,它只有单一的一种主要作用。比如接入网是由单一的ENB组成,一个ENB就是接入网的一个逻辑节点。而核心网有MME,SGW,pgw,hss。。。这都是逻辑节点,但正式做设备时会将其中几个逻辑节点的功能做成一个设备。

enodeb控制面实现了哪些功能

ENodeB简称ENB,可以理解为基站。负责UE(可理解为手机)的电话调度等。MME(移动性管理实体)负责UE移动性管理,比如漫游、切换。PGW(PND-GW(网关))负责UE网络用户面的管理,SGW(serving-GW)负责UE网络控制面管理。EvolvedNodeB,即演进型NodeB简称eNB,LTE中基站的名称,相比现有3G中的NodeB,集成了部分RNC的功能,减少了通信时协议的层次。NodeB:就是在和一个或者多个小区中和UE在无线传输中一个逻辑的接点。简单点理解就是小区。在4G中,ENodeB在功能实际上包含了NodeB的功能和部分RNC的功能。EPC=EvolvedPacketCore字面意思:进化型的分组核心。SGW提供用户面的控制功能,负责数据包的路由和转发,并支持终端移动性切换用户数据功能。PGW主要负责终端和外部分组数据网络的数据传输,在VoLTE网络中,PGW分配终端IP地址并提供EPC部分到IMS部分的接入。

Windows安装Node.js报错:2503、2502怎么办

本文主要给大家介绍了关于在Windows系统下安装Node.js报错:2503、2502的解决方法,文中将解决的方法一步步介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧,希望能帮助到大家。前言Windows真的是太恶心了!!!不仅会出现大量的垃圾文件,而且有时莫名的安装不上一些软件(正常软件)。前久因为想学学Koa2,打算升级下nodejs的版本以体验下ES6、ES7的aync,await等新特性,却死活安装不上nodejs同时也卸载不了老版的nodejs,不知所措,放了一段时间,今晚想看看D3准备学学,并借助Koa做个展示性的学习练手项目,决心查查资料解决下nodejs安装报错问题。功夫不负有心人,终于得以解决,故以此文记录下。目录权限问题?首先我想是不是权限问题,于是我把要安装的目录和Windos下的Temp目录权限都设为完全控制,还是不行,绝望!设置文件目录权限绝望之际,看到网上的一篇文章完美解决,握草还是权限问题!以管理员身份用msiexec安装1、以管理员身份运行cmd命令 (Win + X, A)以管理员身份运行cmd2、用msiexec安装用msiexec安装nodejsmsiexec /package node-v8.7.0-64.msi至此,安装完成!查看nodejs版本

Nanodet:手机端的 97FPS 的 Anchor-free 的目标检测模型

参考资料: YOLO之外的另一选择,手机端97FPS的Anchor-Free目标检测模型NanoDet现已开源~ 1、什么是 Nanodet Nanodet 是一个速度超快和轻量级的移动端 Anchor-free 目标检测模型,是基于 FCOS 模型进行轻量化改进而来的2、Nanodet 跟其他模型的性能对比华为 P30 上用 NCNN 移植跑 benchmark,一张图片仅需 10.23 毫秒,比 YoloV4-Tiny 快 3 倍,参数量小 6 倍,COCO mAP(05:0.95) 能够达到 20.6。而且模型权重文件仅有 1.8m 由此可见,Nanodet 能够在有较低参数量和较小的模型权重文件情况下,能够拥有跟 YoloV4-Tiny 一样的 mAP3、Nanodet 的网络结构图backbone 是 ShuffNetV2 1.0x,去掉最后一层的卷积层,并且抽取 8/16/32倍下采样率的特征输入到 PAN 中做多尺度的特征融合4、Nanodet 相对于 FCOS 的改进① 检测头 FCOS:共享检测头权重 Nanodet:不共享检测头,因为在移动端是使用 CPU 来进行计算的,共享检测头权重并不会对推理过程加速;共享检测头会使得其检测能力进一步下降 ② 归一化方式 FCOS:使用 Group Normalization Nanodet:使用 Batch Normalization 来取代 Group Normalization,因为后者虽然比前者有很多优点,但却有一个缺点:Batch Normalization 可以在推理时将其参数融入到卷积核中,节省这一步计算可以节省时间 ③ 检测头大小 FCOS:检测头大小为 4 个 256 通道数的卷积核组为一个分支,因此边框回归和分类两个分支,则总共需要 8 个 256 通道数的卷积 Nanodet:将 4 个卷积核组减少为 2 个卷积核组。在通道数上将 256 维降低为 96 维。将边框回归和分类共享检测头,然后再切割成两份,分别去预测边框回归和分类。 ④ FPN 层 FCOS:没有该模块 Nanodet:基于 FPN 改进为 PAN,原版的 FPN 在对高层特征图使用线性插值后,再使用 3*3 卷积。但是 Nanodet 去掉了 FPN 中线性插值后再使用的 3*3 卷积,只保留从骨干网络特征提取后的 1*1 卷积来进行特征通道维度的对齐。同时 FPN 只是在多层特征融合端使用了自上而下的特征融合,而 PAN 则不仅使用了自上而下的特征融合,而且还使用了自底向上的特征融合,使用的方法也是线性插值。5、Nanodet 的算法步骤6、Nanodet 的损失函数7、Nanodet 的优点 ① 速度快 ② 模型参数权重文件小8、Nanodet 的缺点 ① mAP 不高

【nodejs】网易云信短信接入&融云IM-token获取

短信接入文档 在网易云信管理中心->应用管理->自己的应用里查看appkey和appsecret 需要三样东西来生成签名 如法炮制,把请求头改成符合他条件的就好 文档 融云文档真是比网易的强太多

如何在Linux上安装Node.js_node.js

Node.js 是建立在谷歌的 V8 JavaScript 引擎服务器端的软件平台上。在构建高性能的服务器端应用程序上,Node.js 在 JavaScript 中已是首选方案。是什么让使用 Node.js 库和应用程序的庞大生态系统来开发服务器后台变得如此流行。Node.js 自带一个被称为 npm 的命令行工具可以让你轻松地安装它,进行版本控制并使用 npm 的在线仓库来管理 Node.js 库和应用程序的依赖关系。在本教程中,我将介绍 如何在主流 Linux 发行版上安装 Node.js,包括 Debian,Ubuntu,Fedora 和 CentOS 。Node.js 在一些发行版上有预构建的程序包(如,Fedora 或 Ubuntu),而在其他发行版上你需要通过源码安装。由于 Node.js 发展比较快,建议从源码安装最新版而不是安装一个过时的预构建的程序包。最新的 Node.js 自带 npm(Node.js 的包管理器),让你可以轻松的安装 Node.js 的外部模块。在 Debian 上安装 Node.js on从 Debian 8 (Jessie)开始,Node.js 已被纳入官方软件仓库。因此,你可以使用如下方式安装它:$ sudo apt-get install npm在 Debian 7 (Wheezy) 以前的版本中,你需要使用下面的方式来源码安装:$ sudo apt-get install python g++ make$ wget http://nodejs.org/dist/node-latest.tar.gz$ tar xvfvz node-latest.tar.gz$ cd node-v0.10.21 (replace a version with your own)$ ./configure$ make$ sudo make install在 Ubuntu 或 Linux Mint 中安装 Node.jsNode.js 被包含在 Ubuntu(13.04 及更高版本)。因此,安装非常简单。以下方式将安装 Node.js 和 npm。$ sudo apt-get install npm$ sudo ln -s /usr/bin/nodejs /usr/bin/node而 Ubuntu 中的 Node.js 可能版本比较老,你可以从 其 PPA 中安装最新的版本。$ sudo apt-get install python-software-properties python g++ make$ sudo add-apt-repository -y ppa:chris-lea/node.js$ sudo apt-get update$ sudo apt-get install npm在 Fedora 中安装 Node.jsNode.js 被包含在 Fedora 的 base 仓库中。因此,你可以在 Fedora 中用 yum 安装 Node.js。$ sudo yum install npm如果你想安装 Node.js 的最新版本,可以按照以下步骤使用源码来安装。$ sudo yum groupinstall "Development Tools"$ wget http://nodejs.org/dist/node-latest.tar.gz$ tar xvfvz node-latest.tar.gz$ cd node-v0.10.21 (replace a version with your own)$ ./configure$ make$ sudo make install在 CentOS 或 RHEL 中安装 Node.js在 CentOS 使用 yum 包管理器来安装 Node.js,首先启用 EPEL 软件库,然后运行:$ sudo yum install npm如果你想在 CentOS 中安装最新版的 Node.js,其安装步骤和在 Fedora 中的相同。在 Arch Linux 上安装 Node.jsNode.js 在 Arch Linux 的社区库中可以找到。所以安装很简单,只要运行:$ sudo pacman -S nodejs npm检查 Node.js 的版本一旦你已经安装了 Node.js,你可以使用如下所示的方法检查 Node.js 的版本。$ node --version

如何在NodeJS项目中使用ES6

本篇文章主要介绍了详解如何在NodeJS项目中优雅的使用ES6,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。NodeJs最近的版本都开始支持ES6(ES2015)的新特性了,设置已经支持了async/await这样的更高级的特性。只是在使用的时候需要在node后面加上参数:--harmony。但是,即使如此node也还是没有支持全部的ES6特性。所以这个时候就需要用到Babel了。项目地址:https://github.com/future-challenger/petshop现在开始Babel在开始使用Babel之前,假设1.你已经安装了nodejs,并且已经熟悉了Js。2.你也可以使用npm安装各种依赖包。3.而且你也对ES6(后来改为ES2015)有一定程度的熟悉。同时假设你已经安装了yarn,并且也熟悉了yarn。Yarn最大的优点就是它比npm要快很多,因为yarn只把需要的库下载一次,之后用到的时候直接使用本地缓存的版本。npm每次都会下载这些库。这简直就是浪费生命。如果你还没有安装yarn,也没有关系,下面也会有npm的使用方法。接下来开始安装配置Babel。安装babel-cliyarn add babel-cli --dev // npm install --save-dev babel-cli安装babel的presets。yarn add babel-preset-es2015 --dev // npm install --save-dev babel-preset-es2015这个时候你就可以使用ES2015的特性了。但是,这还不够,比如我不想用Promise我想用更加方便的async/await语法。只有es2015这个preset是不够的。Babel的plugin和presetBabel本身不处理语言特性的转码。这些功能都是由plugin和preset实现的(preset也是一个plugin的集合)。如上文所述,要使用es2015的内容就需要安装babel-preset-es2015这个preset。要使用async/await那么就需要安装对应的preset或者插件。为了简单我们安装preset:babel-preset-stage-0。preset stage-0包含了async/await相关的插件: babel-plugin-syntax-async-functions、babel-plugin-transform-regenerator。yarn add babel-preset-stage-0 --dev // npm install --save-dev babel-preset-stage-0这样还是不能在项目中使用es7的async/await了。还需要更多的配置,有两种方法可以达到目的:1.使用babel-polyfill。有一个不好地地方,babel-polyfill会污染global对象,所以不适合于library之类的使用。仅适合于web app使用。2.使用babel运行时转码工具,transform-runtime插件。使用这个方法正好弥补了上面的方法的不足之处。它是尤其适合于library一类的项目使用。分别介绍这两种方法。 安装babel-polyfill:yarn add babel-polyfill --dev // npm install --save-dev babel-polyfill之后,在你的项目的入口文件的最上方引入babel-polyfill。比如我现在有一个Express的Web App,那么的入口文件就是开启这个app的index.js文件。在这个文件的最上方引入polyfill,require("babel-polyfill")。或者你的入口文件已经是ES2015的写法了,那么就直接import,import "babel-polyfill"。使用transform-runtime也非常简单。安装:yarn add babel-plugin-transform-runtime --dev // npm install --save-dev babel-plugin-transform-runtime另外还需要安装babel-runtime:yarn add babel-runtime // npm install --save babel-runtime之后在.babelrc文件中添加如下的配置,两个二选其一即可:// without options{ "plugins": ["transform-runtime"]}// with options{ "plugins": [ ["transform-runtime", { "helpers": false, // defaults to true "polyfill": false, // defaults to true "regenerator": true, // defaults to true "moduleName": "babel-runtime" // defaults to "babel-runtime" }] ]}剩下的就是欢畅的使用async/await了。另外如果要使用Object.assing这样的方法的话,也可以使用插件:babel-plugin-transform-object-assign,如果要使用解构赋值可以使用插件:babel-plugin-transform-object-rest-spread。当然这些都包含在了stage-0这个preset中。现在就开始写ES2015的代码吧。在项目中安装ExpressJs,创建一个index.js文件。我们来试着创建一个小小的web app作为练习:import Express from "express"let app = Express()app.get("/", (req, res) => { res.send("hello world")})app.listen(8080, () => console.log("server is running at http://localhost:8080"))运行命令:./node_modules/.bin/babel-node index.js --preset es2015, stage-0使用命令*babel-node**就可以让代码运行起来,后面的参数指定了在转义js代码的时候使用的preset和plugin。Babel官方推荐的方法是时候用.babelrc文件,这一方式可以更加灵活。在项目的更目录上创建.babelrc文件,在里面添加你安装的preset和plugin的描述:{ "presets": ["es2015", "stage-0"]}这样可以直接使用babel-node来执行代码,或者使用命令babel来转义代码。如:babel -w code/ -d build/babel命令会从配置文件中读取配置,来变异code/目录下的文件,并把转义之后的JavaScript文件导出到build/目录下。还有命令行里的参数-w,这个命令参数指定的是watch,每次code目录的文件修改后都会触发babel命令的再次执行。在文件中使用Source Maps上面看起来很不错了。但是还有一个问题,在你调试代码的时候,你调试的实际是babel命令转码之后的js,不是原来你编写的源代码所在的文件。调试的不是源文件,多少会有些不便。比如下面的文件会抛出一个异常:async function errorAsyncFunc() { try{ throw new Error("Async function error") } catch(e) { throw e }}errorAsyncFunc()在转码命令中加一个--source-maps可以解决这个问题:babel code/ -d build/ --source-maps最后在package.json里添加scripts节点:"scripts": { "build": "babel src -d build --source-maps", "start": "node build/index.js"},接下来:npm run buildGulp出场上文讲述了如何使用Babel实现ES201x的开发。但是在正式的开发中,上面的这些配置还略显不足,尤其是你的项目包括web端、server端,尤其web端不仅处理ES201x的代码还需要处理。所以需要Gulp出场。这玩意儿看起来很复杂,你定义了编译的过程。其实掌握了以后很好用,尤其是可以自动处理很多东西,节约大把时间。要使用Gulp,必须先安装NodeJS。这个基本是标配。然后你会用到它的命令行工具。安装Gulp在最新发布的Gulp里有一点调整。gulp-cli从gulp分离出来作为单独的一部分使用。所以,如果你已经安装过gulp之前的版本需要先删除:npm rm --global gulp安装gulp-cliyarn global add gulp-cli // npm install --global gulp-cli在--dev模式下安装gulpyarn add gulp --dev // npm install --save-dev gulp创建gulp配置文件就像Babel要用.babelrc作为配置文件一样,gulp也需要一个配置文件。这个配置文件就是gulpfile.js, 但是和babel同用的情况下把gulpfile.js重命名为gulp.babel.js:mv "gulpfile.js" "gulpfile.babel.js"gulp的使用还是很简单的,主要就是在gulpfile.babel.js文件中添加各种task。在这些task中一定要添加一个叫做default的task,gulp命令的执行起点就是从这里开始。假设有这么一个场景:1.使用eslint检查代码,发现代码风格和潜在的错误。2.自动实现ES201x -> ES5的代码转码,并把转码后的代码放在指定目录下。3.在转码的时候添加sourcemaps。以上这些“任务”都是用gulp自动实现。该如何配置呢?gulp和eslint要在gulp中使用各种请他的类似于eslint这样的功能的时候需要使用在gulp上的对应的插件。没错,gulp的设计思路和gulp基本一样:插件机制。那么我们就需要首先下载eslint的插件:yarn add --dev gulp-eslint // npm install --save-dev gulp-eslint在开始编写我们的第一个task之前, 做最后的准备工作。首先需要配置.eslintrc文件。eslint会根据这个文件定义的规则检查代码的风格。我们不准备大批的配置规则,这样非常耗时间而且也照顾不到很多我们项目已经保留下来的编码风格。所以,airbnb的一套规则拿来使用时最好的办法。安装eslintyarn add --dev eslint // npm install --save-dev eslint然后你可以运行命令来初始化配置:./node_modules/.bin/eslint --init。你也可以忽略这个命令,直接创建一个.eslintrc的文件。安装eslint的airbnb扩展要使用airbnb的一套规则就需要安装他们的eslint扩展:yarn add eslint-config-airbnb --dev // npm install --save-dev eslint-config-airbnb命令执行之后会提示有些依赖项没有安装,分别是eslint-plugin-import@^2.2.0、eslint-plugin-import@^2.2.0、eslint-plugin-jsx-a11y@^3.0.2。依次安装这些依赖项就好。.eslintrc{ "env": { "es6": true }, "rules": { "semi": "off", "import/no-extraneous-dependencies": ["error", { "devDependencies": true, "optionalDependencies": false, "peerDependencies": false }] ,"quotes": ["error", "single", {"allowTemplateLiterals": true}] }, "extends": "airbnb"}env指定环境是支持es6的,rules指定的是一些补充内容,比如字符串使用单引号还是双引号等。这个是根据个人喜好配置的,你可以选择添加你需要的规则。最后是extends,这里配置airbnb就用上了airbnb的一套eslint编码检查规则。gulp-eslint插件用起来import gulp from "gulp"import eslint from "gulp-eslint// 配置需要处理的文件目录和转码之后文件的存放目录const paramConfig = { source: "src/**/*.js", dest: "build",}引入相关模块之后开始写任务:gulp.task("lint", () => { // eslint配置,使用配置的文件目录。排除node_modules下的全部文件。 return gulp.src([paramConfig.source, "!node_modules/**"]) .pipe(eslint()) .pipe(eslint.result(result => { console.log(`ESLint result: ${result.filePath}`); console.log(`# Messages: ${result.messages.length}`); console.log(`# Warnings: ${result.warningCount}`); console.log(`# Errors: ${result.errorCount}`); })) .pipe(eslint.format()) .pipe(eslint.failOnError())})如前文所述,default任务是必须:gulp.task("default", ["lint"], function () { // lint任务成功执行之后执行这个方法});跳转到项目的目录下,运行gulp命令。会得到如下的输出:$ gulp[21:43:01] Requiring external module babel-register[21:43:01] Using gulpfile ~/Documents/test-polyfill/gulpfile.babel.js[21:43:01] Starting "lint"...[21:43:02] Starting "babel-sourcemaps"...ESLint result: ~/Documents/test-polyfill/src/index.js# Messages: 0# Warnings: 0# Errors: 0ESLint result: ~/Documents/test-polyfill/src/test.js# Messages: 0# Warnings: 0# Errors: 0[21:43:02] Finished "lint" after 605 ms[21:43:02] Finished "babel-sourcemaps" after 653 ms[21:43:02] Starting "default"...gulp default task![21:43:02] Finished "default" after 98 μsgulp和babel这次同时处理babel和sourcemaps的问题。首先安装插件:yarn add --dev gulp-babel // npm install --save-dev gulp-babelimport gulp-babel插件:import babel from "gulp-babel"import sourcemaps from "gulp-sourcemaps"添加任务:gulp.task("babel-sourcemaps", () => { return gulp.src(paramConfig.source) .pipe(sourcemaps.init()) .pipe(babel()) .pipe(sourcemaps.write(".")) .pipe(gulp.dest(paramConfig.dest))})修改default任务:javascript gulp.task("default", ["lint", "babel-sourcemaps"], () => { console.log("gulp default task!") })如果你不想用sourcemaps的话,可以这么写:javascript gulp.task("babel", () => { return gulp.src(paramConfig.source) .pipe(babel()) .pipe(gulp.dest(paramConfig.dest)) })把gulp放在npm命令体系下babel老早就配置好了,现在和配置好了gulp。gulp每次输入命令基本上就是手动执行。现在应该让这个命令半自动执行了。修改package.json文件,在其中添加scripts节点: "scripts": { "build": "gulp", "start": "node build/index.js" },如此一来,很多的命令都可以像gulp一样放在npm的scripts里执行。比如,现在可以在命令行李输入如下命令来实现lint和babel转码:npm run build开始执行:npm start总结使用bebel可以提前使用最新的JavaScript语言特性,这样编写很多代码的时候会变得简洁高效。并且babel转码之后生成的代码也是非常规范的ES5写法,同时是在严格模式下的。所以,我们在写ES201x代码的时候不需要再添加"use strict";标识。使用gulp又可以使很多不大不小但是很费时间的事自动处理。把这两者结合在一起会让你的项目开发效率提升很多。所以,看到这里你不觉得你应该赶快在项目里使用这些技术,让开发进入快车道吗!!!???

请教关于Nodejs多进程共享缓存数据

以正常目前的业务场景来说(非nodejs),一个进程平均是用1.5-3G内存不等.缓存是根据某些特定条件组合生成的key(key的数量稍微有点儿多),需要从MongoDB/Redis读取数据.1MB的数据是业务数据传输量最大的那种,不是只有这种业务.场景可以假设为,获取用户的一些浏览记录,包含图片,描述,评测等(描述与评价都算是比较大的传输量的数据),每次获取30条左右.然后再乘以一定的用户在线数量,这个缓存数据是比较庞大的.先不考虑这个架构是否可以优化.发这个主题的原因只是想了解到nodejs有没有什么成熟方案可以共享进程间的数据比如用户X,访问站点时,被调度系统分配给A进程获取了luby的浏览历史,A进程从mongodb获取到luby的记录列表进行呈现.这时候用户Y也想看看luby的浏览历史,这调度系统分配给了B进程.这个时候B进程又要再去mongodb获取一次.我期望是B进程可以共享A进程的luby记录列表1)降低mongogdb的访问频率2)提高响应速度,因为减少了mongodb查询,减少了网络传输.

请教关于Nodejs多进程共享缓存数据

以正常目前的业务场景来说(非nodejs),一个进程平均是用1.5-3G内存不等.缓存是根据某些特定条件组合生成的key(key的数量稍微有点儿多),需要从MongoDB/Redis读取

如何使用Node.js读取JSON文件

本篇文章将介绍关于使用node.js读取JSON文件内容,使用的是JSonfile模块的readfile和readfilesync函数。要求:要在系统上安装node.js和npm。对于本篇文章,我们使用的是JSonfile NPM模块。因此,首先需要在系统上安装JSonfile模块$ npm install jsonfile --save现在,正在创建一个虚拟的json文件employee.json。也可以使用自己的JSON文件。文件名:employee.json[ { "emp_id" : "101", "emp_name" : "Mike", "emp_addr" : "123 California, USA", "designation" : "Editor" }, { "emp_id" : "102", "emp_name" : "Jacob", "emp_addr" : "456 Log Angelis, USA", "designation" : "Chief Editor" }]1、用nodejs读取json文件在上面的步骤中,创建了一个JSON文件示例。现在创建ReadJsonFile.js并添加以下内容。需要使用JSON文件名更改employee.json。文件名:ReadJsonFile.jsvar jsonFile = require("jsonfile")var fileName = "employee.json"jsonFile.readFile(fileName, function(err, jsonData) { if (err) throw err; for (var i = 0; i < jsonData.length; ++i) { console.log("Emp ID: "+jsonData[i].emp_id); console.log("Emp Name: "+jsonData[i].emp_name); console.log("Emp Address: "+jsonData[i].emp_addr); console.log("Designation: "+jsonData[i].designation); console.log("----------------------------------"); }});现在使用以下命令运行nodejs脚本。$ node ReadJsonFile.js Emp ID: 101Emp Name: MikeEmp Address: 123 California, USADesignation: Editor----------------------------------Emp ID: 102Emp Name: JacobEmp Address: 456 Log Angelis, USADesignation: Chief Editor----------------------------------2、用nodejs读取json文件或者,可以使用readfilesync函数读取JSON文件内容。创建一个包含以下内容的readjsonfilesync.js文件文件名:readjsonfilesync.jsvar jsonFile = require("jsonfile")var fileName = "employee.json"var jsonData = jsonFile.readFileSync(fileName);for (var i = 0; i < jsonData.length; ++i) { console.log("Emp ID : "+jsonData[i].emp_id); console.log("Emp Name : "+jsonData[i].emp_name); console.log("Emp Address : "+jsonData[i].emp_addr); console.log("Designation : "+jsonData[i].designation); console.log("----------------------------------");}现在使用以下命令运行nodejs脚本。$ node ReadJsonFileSync.js Emp ID: 101Emp Name: MikeEmp Address: 123 California, USADesignation: Editor----------------------------------Emp ID: 102Emp Name: JacobEmp Address: 456 Log Angelis, USADesignation: Chief Editor----------------------------------本篇文章到这里就已经全部结束了,更多其他精彩内容可以关注PHP中文网的node.js视频教程栏目!!!

快速了解Node中的Stream流是什么

StreamBuffer 的工作原理 Data 是一块大数据 他被分为很多个小数据 每块小数据都被存储在内存中的 Buffer 中 接着 Buffer 不断接收小数据 同时一旦 Buffer 接收的小数据填满了就会被消费 填满的 Buffer 也被称为一个 Chunk 所有 Chunk 组合而成的才是那块 Data 大数据Stream 的分类 Read Stream Write Stream Duplex TransformDuplex 实际上就是有两个 Buffer 一个处理 ReadStream 另一个是处理 WriteStream;典型的例子就是 Network SocketTransform 实际上有三个 Buffer 串联一起,中间的 Buffer 实际上就是类似中转的运输作用,也可以从中修改数据;典型的例子就是 encoding/decoding, Compressing/Decompressing, Filtering data, JS to JSONpipepipe 的概念就相当于一个“水管”,将 readable 连接至 writable总结

struct node啥意思

网络构架中的节点node(结点):网络连接的端点,或两条(或多条)线路的连接点.结点可以是处理器、控制器或工作站.结点随其功能不同而各不相同,他们可以通过链路互联在一起,在网络中用作控制点.节点是指一台电脑或其他设备与一个有独立地址和具有传送或接收数据功能的网络相连。(A computer or other device connected to a network, which has a unique address and is capable of sending or receiving data.)Node节点,结点,网点 节点可以是工作站、客户、网络用户或个人计算机,还可以是服务器、打印机和其他网络连接的设备。

为什么来自Node.js社区的stylus人气比不上sass和less

我曾听别人抱怨说,stylus语法太灵活,容易导致混乱。不过我倒是最喜欢stylus的说。还有一个原因是,stylus的相关工具不能和less以及scss相比。举个例子:bootstrap-stylus 281 starbootstrap-sass 7387 starbootstrap 72019 star你们感受下……因为没靠山嘛,Less 的发展有 Bootstrap,Sass 的发展有 Compass ,Stylus 有啥……所以即使我觉得 Stylus 完爆 Less 几条街,至少能和 Sass 分庭抗礼,Stylus 还是不温不火

如何在代码中引入 node

nodejs的几种模块加载方式一.直接在exports对象中添加方法1. 首先创建一个模块(module.js)module.jsexports.One = function(){console.log("first module");};2.load.jsvar module =require("./module");module.One();这样我们就可以在引入了该模块后,返回一个exports对象,这里是指module对象,其实都只是两个引用或者句柄,只是都指向了同一个资源,在load.js里,module的名字可以是任意取的,因为它仅仅是指向require("./module");返回后的一个实例对象的引用,在load.js文件里的module和在module.js里的exports对象是同一个东西.因此上述两个文件可以用一个文件来表示:exports.One = function(){console.log("first module");};exports.One();其运行结果是一致的,这里我们可以很清晰的看到,我们在使用require("./xxxx")后其实返回的总是在 xxxx.js文件中的exports对象的引用,这个引用的名字我们可以任意取,但是为了规范我们还是最好取符号某些非标准规定(后面说道),但是这样会有不妥的地方,因为它是始终指向exports的实例对象,也就是说,我们虽然有了这个模块,但是这个模块我们只能使用一次,这取决于rquire("./module")只会加在一次该模块.比如我们修改上述代码,module.jsvar name ;exports.setName = function(oName){name = oName;};exports.getName = function(){console.log(name);};load.jsvar module1 = require("./module");module1.setName("felayman1");module1.getName();var module2 = require("./module");module2.setName("felayman2");module2.getName();module1.getName();我们可以看到,虽然我们使用了两次require("./module");,但是当我们修改module2后,module1的内容也被修改,这恰恰说明了,module1和module2是指向的同一个对象.有时候这并不影响我们的程序,但是如果我们的module是Person呢?我们希望我们require("./person")后返回的是不同的对象.因此,这种方式是有缺陷的,尽管很方便,这种方式在大部分nodejs的模块中都是很常见,比如fs模块,http模块等.二.将模块中的函数挂载到exports对象的属性上person.js<span style="font-family:Courier New;font-size:18px;">function Person{<span style="white-space: pre; "> </span>var name;<span style="white-space: pre; "> </span>this.setName = function(theName){<span style="white-space: pre; "> </span>name = theName;<span style="white-space: pre; "> </span>};<span style="white-space: pre; "> </span>this.sayHello = function(){<span style="white-space: pre; "> </span>console.log("Hello",name);<span style="white-space: pre; "> </span>};}exports.Person = Person;</span><span style="font-size:24px;font-family: "Microsoft YaHei"; "></span>load.js var Person = require("./person").Person;var person1 = new Person();person1.setName("felayman1");person1.sayHello();var person2 = new Person();person2.setName("felayman2");person2.sayHello();person1.sayHello();这样我们可以看到,我们就可以引入一个函数了,我们把在person.js文件中的Person函数设置为eports对象的一个属性,我们只需要在load.js文件中引入该属性,就可以获取到多个该函数的实例,在nodejs中的EventEmitter就是基于这种方式,但是这样我们总是在使用 require("./person").Person;这样的写法有点太复杂,因此nodejs允许我们使用其他更简洁的方式,利用全局变量--module,这样我们在其他文件中引入其他模块的时候,就更方便了.三.利用全局变量module person.js<span style="font-family:Courier New;">function Person(){var name;this.setName = function(theName){name = theName;};this.sayHello = function(){console.log("Hello",name);};}// exports.Person = Person;module.exports = Person;</span>load.jsvar Person = require("./person");var person1 = new Person();person1.setName("felayman1");person1.sayHello();var person2 = new Person();person2.setName("felayman2");person2.sayHello();person1.sayHello();这样一修改,我们就在使用require函数的时候就方便了,如果觉得这里难以理解,我们可以把两个文件里语法放到一起:var Person = require("./person");module.exports = Person;这样,我们就可以看出,其实就是这样var Person = Person.因为上述我们都已经说过,require("./person")其实就是module.exports 对象的,这里的module我们不用太在意,就跟javascript中的window一样,是一个全局变量,即 module.exports =exports就类似于window.alert() =alert()差不多的效果,这样我们就能看出,我们再次使用require("./person")的时候其实就是导入了我们所需要的exports对象的属性函数模板了,这样我们也可以多次实例化我们所需要的对象了.这种方式是综合了前两种的方法,因此也是官方推荐的使用方法.

Node.js setTimeout在while循环中不起作用?

这段代码是一个错误的示例,因为在 Node.js 中的事件循环机制导致 setTimeout 函数无法按预期工作。在上面的代码中,while 循环会一直运行,不会等待 setTimeout 函数执行完成。因此,setTimeout 的回调函数永远不会被触发。如果要在循环中使用 setTimeout 函数,可以考虑使用递归或者使用 Promise 或 async/await 等异步操作来实现。例如,可以使用递归来执行多个 setTimeout 函数,每次循环内调用一个 setTimeout,并在其回调函数中递归调用下一次 setTimeout。这样可以模拟出延迟效果:var temp1 = 0;function myFunc() {if (temp1 < 5) {console.log("doing");temp1 += 1;setTimeout(myFunc, 1000);} else {console.log("done");}}myFunc();这段代码会每隔一秒输出一次 "doing",并在循环结束后输出一次 "done"。通过递归调用 setTimeout,可以确保每次 setTimeout 的回调函数执行时都在上一个 setTimeout 的回调函数执行完成之后。

如何正确使用Nodejs 的 c++ module 链接到 OpenSSL

事情的起因是这样的, 因为某些原因, 最近在写 Nodejs 的 c++ module, 然后在js这边调用。 网络通信自然离不开ssl, 于是需要链接到Openssl的库。我们本来的期望是,需要用户安装有Openssl的运行库, 然后我们的c++ module 动态链接到Openssl的so库上来运行。起初一切看起来还不错,直到我们发现这个openssl的函数不能工作:PKCS7_sign()PKCS7_sign ( )我们发现:如果我们的 c++ 模块与Openssl库动态链接的话, 编译都没问题. 但是运行会出现: PKCS7_sign 符号无法找到的错误.如果我们的 c++ 模块与Openssl库静态链接的话, 编译也没问题, 但是运行时,调用这个函数的地方没有效果, 这个函数返回值是 0. 按照文档表示出现错误, 但是用 Openssl的函数 ERR_get_error 获取错误码也是0. 表示没有错误码.在linux上是这样, 那在Mac上呢? 用Mac试了一下, 发现Mac没有问题. 于是,想到这可能是Nodejs的一个bug. 然后就去 Nodejs 给它报了一个bug: [https://github.com/joyent/node/issues/8026][1]同时, google上搜索了 nodejs linking to openssl 类似的关键字.找到这样几篇文章:https://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSLhttps://github.com/joyent/node/issues/3915http://serverfault.com/questions/338092/how-can-i-build-node-js-using-static-libssl-and-crypto-librarieshttps://github.com/robhawkes/node-extension/issues/1通过搜索, 我们发现, 原来Nodejs自己也使用了Openssl 库, 推测nodejs自己的crypto模块也是使用Openssl lib实现的. 这点从Nodejs的源码中就能发现, 它包含了最新的Openssl的全部源码.其中写上面第一篇文章: https://github.com/TooTallNate/node-gyp/wiki/Linking-to-OpenSSL 的那个帅哥是Nodejs的开发人员.基本结论:Nodejs 自己使用了Openssl在Nodejs 0.6之前, Nodejs是动态链接到 Openssl 库的. 而之后的版本都是静态链接的.这时发现 Node 那边已经回复我的bug了: https://github.com/joyent/node/issues/8026Node 解释的原因:Node 自己编译之后, 把自己没用到的符号清除, 所以我们在运行时就找不到符号了. 于是他们把这bug 修掉了. 保留了全部符号. 这导致 Node 的体积大了 400k.

Node.Js中怎样实现端口重用功能

了解http.js模块:我们都只有要创建一个http服务,必须引用http模块,http模块最终会调用net.js实现网络服务// lib/net.js"use strict"; ...Server.prototype.listen = function(...args) { ... if (options instanceof TCP) { this._handle = options; this[async_id_symbol] = this._handle.getAsyncId(); listenInCluster(this, null, -1, -1, backlogFromArgs); // 注意这个方法调用了cluster模式下的处理办法 return this; } ...};function listenInCluster(server, address, port, addressType,backlog, fd, exclusive) {// 如果是master 进程或者没有开启cluster模式直接启动listenif (cluster.isMaster || exclusive) { //_listen2,细心的人一定会发现为什么是listen2而不直接使用listen // _listen2 包裹了listen方法,如果是Worker进程,会调用被hack后的listen方法,从而避免出错端口被占用的错误 server._listen2(address, port, addressType, backlog, fd); return; } const serverQuery = { address: address, port: port, addressType: addressType, fd: fd, flags: 0 };// 是fork 出来的进程,获取master上的handel,并且监听,// 现在是不是很好奇_getServer方法做了什么 cluster._getServer(server, serverQuery, listenOnMasterHandle);} ...答案很快就可以通过cluster._getServer 这个函数找到代理了server._listen2 这个方法在work进程的执行操作向master发送queryServer消息,向master注册一个内部TCP服务器// lib/internal/cluster/child.jscluster._getServer = function(obj, options, cb) { // ... const message = util._extend({ act: "queryServer", // 关键点:构建一个queryServer的消息 index: indexes[indexesKey], data: null }, options); message.address = address;// 发送queryServer消息给master进程,master 在收到这个消息后,会创建一个开始一个server,并且listen send(message, (reply, handle) => { rr(reply, indexesKey, cb); // Round-robin. }); obj.once("listening", () => { cluster.worker.state = "listening"; const address = obj.address(); message.act = "listening"; message.port = address && address.port || options.port; send(message); });}; //... // Round-robin. Master distributes handles across workers.function rr(message, indexesKey, cb) { if (message.errno) return cb(message.errno, null); var key = message.key; // 这里hack 了listen方法 // 子进程调用的listen方法,就是这个,直接返回0,所以不会报端口被占用的错误 function listen(backlog) { return 0; } // ... const handle = { close, listen, ref: noop, unref: noop }; handles[key] = handle; // 这个cb 函数是net.js 中的listenOnMasterHandle 方法 cb(0, handle);}// lib/net.js/*function listenOnMasterHandle(err, handle) { err = checkBindError(err, port, handle); server._handle = handle; // _listen2 函数中,调用的handle.listen方法,也就是上面被hack的listen server._listen2(address, port, addressType, backlog, fd); }*/master进程收到queryServer消息后进行启动服务如果地址没被监听过,通过RoundRobinHandle监听开启服务如果地址已经被监听,直接绑定handel到已经监听到服务上,去消费请求// lib/internal/cluster/master.jsfunction queryServer(worker, message) { const args = [ message.address, message.port, message.addressType, message.fd, message.index ]; const key = args.join(":"); var handle = handles[key]; // 如果地址没被监听过,通过RoundRobinHandle监听开启服务 if (handle === undefined) { var constructor = RoundRobinHandle; if (schedulingPolicy !== SCHED_RR || message.addressType === "udp4" || message.addressType === "udp6") { constructor = SharedHandle; } handles[key] = handle = new constructor(key, address, message.port, message.addressType, message.fd, message.flags); } // 如果地址已经被监听,直接绑定handel到已经监听到服务上,去消费请求 // Set custom server data handle.add(worker, (errno, reply, handle) => { reply = util._extend({ errno: errno, key: key, ack: message.seq, data: handles[key].data }, reply); if (errno) delete handles[key]; // Gives other workers a chance to retry. send(worker, reply, handle); });}看到这一步,已经很明显,我们知道了多进行端口共享的实现原理其实端口仅由master进程中的内部TCP服务器监听了一次因为net.js 模块中会判断当前的进程是master还是Worker进程如果是Worker进程调用cluster._getServer 去hack原生的listen 方法所以在child调用的listen方法,是一个return 0 的空方法,所以不会报端口占用错误那现在问题来了,既然Worker进程是如何获取到master进程监听服务接收到的connect呢?监听master进程启动的TCP服务器的connection事件通过轮询挑选出一个worker向其发送newconn内部消息,消息体中包含了客户端句柄有了句柄,谁都知道要怎么处理了哈哈// lib/internal/cluster/round_robin_handle.jsfunction RoundRobinHandle(key, address, port, addressType, fd) { this.server = net.createServer(assert.fail); if (fd >= 0) this.server.listen({ fd }); else if (port >= 0) this.server.listen(port, address); else this.server.listen(address); // UNIX socket path. this.server.once("listening", () => { this.handle = this.server._handle; // 监听onconnection方法 this.handle.onconnection = (err, handle) => this.distribute(err, handle); this.server._handle = null; this.server = null; });}RoundRobinHandle.prototype.add = function (worker, send) { // ...};RoundRobinHandle.prototype.remove = function (worker) { // ...};RoundRobinHandle.prototype.distribute = function (err, handle) { // 负载均衡地挑选出一个worker this.handles.push(handle); const worker = this.free.shift(); if (worker) this.handoff(worker);};RoundRobinHandle.prototype.handoff = function (worker) { const handle = this.handles.shift(); const message = { act: "newconn", key: this.key }; // 向work进程其发送newconn内部消息和客户端的句柄handle sendHelper(worker.process, message, handle, (reply) => { // ... this.handoff(worker); });};下面让我们看看Worker进程接收到newconn消息后进行了哪些操作// lib/child.jsfunction onmessage(message, handle) { if (message.act === "newconn") onconnection(message, handle); else if (message.act === "disconnect") _disconnect.call(worker, true); }// Round-robin connection.// 接收连接,并且处理function onconnection(message, handle) { const key = message.key; const server = handles[key]; const accepted = server !== undefined; send({ ack: message.seq, accepted }); if (accepted) server.onconnection(0, handle);}总结net模块会对进程进行判断,是worker 还是master, 是worker的话进行hack net.Server实例的listen方法worker 调用的listen 方法是hack掉的,直接return 0,不过会向master注册一个connection接手的事件master 收到客户端connection事件后,会轮询向worker发送connection上来的客户端句柄worker收到master发送过来客户端的句柄,这时候就可以处理客户端请求了相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!推荐阅读:Vue.js双向绑定项目实战分析jquery如何判断元素内容为空

在nodejs中如何实现websocket通信功能

这篇文章主要介绍了nodejs结合socket.io实现websocket通信功能的方法,结合实例形式分析了nodejs结合socket.io实现websocket通信的具体步骤与相关操作技巧,需要的朋友可以参考下本文实例讲述了nodejs结合socket.io实现websocket通信功能的方法。分享给大家供大家参考,具体如下:因为项目中有需要实时获取后台数据的场景,之前一直是使用http心跳请求的方法。因为websocket与此模式相比有很大的性能提升,而且可以提高实时性,所以对websocket作了一些研究。这里是使用nodejs+socket.io来实现的。达成目标将原来心跳请求后台数据的方式,修改为通过socket连接后台统一推送的方式。后台的数据由别的进程写入文件或写入redis,这里实现的是读取文件的方式。前期准备安装nodejs(略)服务器端新建一个项目目录,这里是sockettest进入sockettest目录,安装express模块和socketio模块npm install --save express@4.10.2npm install --save socket.io新建package.json文件,在其中写入如下内容:{ "name": "socket-test", "version": "0.0.1", "description": "my first socket.io app", "dependencies": { "express": "^4.10.2", "socket.io": "^1.7.2" }}新建index.html,用于作为默认的访问显示页面,因为这里不会用到它,内容随意;新建trends.js文件,在其中写入内容:var app = require("express")();var http = require("http").Server(app);var io = require("socket.io")(http);var fs = require("fs");#默认打开文件app.get("/", function(req, res){ res.sendfile("index.html");});#用于存储所有socket以广播数据var iolist = [];#定义socket on connection(连入)事件行为io.on("connection", function(socket){ #将连入socket加入列表 iolist.push(socket); #记录index,在disconnect(断开连接)发生时将对应的socket删除 var sockex = iolist.indexOf(socket); #定义on disconnect事件行为 socket.on("disconnect", function(){ #将断开连接的socket从广播列表里删除 iolist.splice(sockex, 1); });});# 数据广播进程:每1秒钟广播一次setInterval(function() { # 如果没有正在连接的socket,直接返回; if (iolist.length <= 0) return; var trends = fs.readFileSync("./data/trends.json","utf-8");#trends数据 var coins = fs.readFileSync("./data/coins.json","utf-8");#coins数据 #向所有socket连接发送数据 for (i in iolist) { # 向客户端发送trends数据 iolist[i].emit("trends", trends); # 向客户端发送coins数据 iolist[i].emit("coins", coins); }}, 1000);# 服务器侦听在sockettest.com的3000端口上http.listen(3000, function(){ # 输出到标准输出 console.log("listening on sockettest.com:3000");});新建data目录,并在下面新建两个文件trends与coins,用于存放socket服务器将要读取的数据。新建public目录,在其中新建一个文件index.html,文件内容如下:<!--引入必要的js文件--><script type="text/javascript" src="http://sockettest:3000/socket.io/socket.io.js"></script><script type="text/javascript"> //新建socket var socket = io("http://sockettest.com:3000"); socketdata(socket); function socketdata() { #定义接收到coins类型数据时的行为 socket.on("coins", function(msg){ console.log(msg); } #定义接收到trends类型数据时的行为 socket.on("trends", function(msg){ console.log(msg); } }</script>代码部署刚才之所以要建两个index.html文件,是为了能够方便地在既有的web项目中使用nodejs提供的socket服务。这样我们把public/index.html可以部署在别的服务器中,比如nginx或tomcat之类,然后在根目下启动socket的服务器,为其提供socket服务。 首先在刚才的项目根目录下执行node ./trends.js并保持终端运行,然后再把项目部署在nginx里,通过chrome下访问nginx提供的web服务:http://hostname/public/index.html打开开发者模式,就能在console里看到每隔一秒便会收到来自node服务器的socket推送消息了。通过修改data目录下的两个文件,可以看到写入到文件的数据也会实时地推送到客户端这里来。上面是我整理给大家的,希望今后会对大家有帮助。相关文章:在vue中使用cli如何实现重构多页面脚手架在JS中实现点击下拉菜单内容同步输入框实现输入框与下拉框联动使用parcel.js打包出错的问题详细解读vue重构技术

请教,hadoop集群停止nodemanager失败

环境是一个master主节点(192.168.31.130)和两个slave节点(192.168.31.131/132)执行stop-all.sh命令时,终端提示如下Bash/shell code?12345678910111213141516hadoop@hadoopmaster pids]$ cd $HADOOP_HOME/sbin[hadoop@hadoopmaster pids]$ stop-all.shThis script is Deprecated. Instead use stop-dfs.sh and stop-yarn.shStopping namenodes on [hadoopmaster]hadoopmaster: stopping namenode192.168.31.132: stopping datanode192.168.31.131: stopping datanodeStopping secondary namenodes [hadoopmaster]hadoopmaster: stopping secondarynamenodestopping yarn daemonsstopping resourcemanager192.168.31.132: stopping nodemanager192.168.31.131: stopping nodemanager192.168.31.132: nodemanager did not stop gracefully after 5 seconds: killing with kill -9192.168.31.131: nodemanager did not stop gracefully after 5 seconds: killing with kill -9no proxyserver to stopslave节点记录yarn-hadoop-nodemanager-hadoopslaver01.log如下Bash/shell code?1234567891011121314151617181920212223242526272829303132333435362017-06-03 07:03:19,137 INFO org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking ResourceTrackerPBClientImpl.nodeHeartbeat over null. Retrying after sleeping for 30000ms.java.io.EOFException: End of File Exception between local host is: "hadoopslaver01/192.168.31.131"; destination host is: "hadoopmaster":8031; : java.io.EOFException; For more details see: htp/EOFException at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:423) at org.apache.hadoop.net.NetUtils.wrapWithMessage(NetUtils.java:801) at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:765) at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1485) at org.apache.hadoop.ipc.Client.call(Client.java:1427) at org.apache.hadoop.ipc.Client.call(Client.java:1337) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:227) at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:116) at com.sun.proxy.$Proxy73.nodeHeartbeat(Unknown Source) at org.apache.hadoop.yarn.server.api.impl.pb.client.ResourceTrackerPBClientImpl.nodeHeartbeat(ResourceTrackerPBClientImpl.java:85) at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:398) at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeMethod(RetryInvocationHandler.java:163) at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invoke(RetryInvocationHandler.java:155) at org.apache.hadoop.io.retry.RetryInvocationHandler$Call.invokeOnce(RetryInvocationHandler.java:95) at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:335) at com.sun.proxy.$Proxy74.nodeHeartbeat(Unknown Source) at org.apache.hadoop.yarn.server.nodemanager.NodeStatusUpdaterImpl$1.run(NodeStatusUpdaterImpl.java:766) at java.lang.Thread.run(Thread.java:748)Caused by: java.io.EOFException at java.io.DataInputStream.readInt(DataInputStream.java:392) at org.apache.hadoop.ipc.Client$IpcStreams.readResponse(Client.java:1786) at org.apache.hadoop.ipc.Client$Connection.receiveRpcResponse(Client.java:1155) at org.apache.hadoop.ipc.Client$Connection.run(Client.java:1052)2017-06-03 07:03:23,452 ERROR org.apache.hadoop.yarn.server.nodemanager.NodeManager: RECEIVED SIGNAL 15: SIGTERM2017-06-03 07:03:24,458 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoopmaster/192.168.31.130:8031. Already tried 0 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)2017-06-03 07:03:25,460 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoopmaster/192.168.31.130:8031. Already tried 1 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)2017-06-03 07:03:26,461 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoopmaster/192.168.31.130:8031. Already tried 2 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)2017-06-03 07:03:27,462 INFO org.apache.hadoop.ipc.Client: Retrying connect to server: hadoopmaster/192.168.31.130:8031. Already tried 3 time(s); retry policy is RetryUpToMaximumCountWithFixedSleep(maxRetries=10, sleepTime=1000 MILLISECONDS)更多0hadoop 是用的什么版本? 注意:只有 hadoop 3.0 才支持“一主多从”架构。而且 hadoop 3.0 现在还只是 alpha 4版本,还不建议用于生产环境。

如何使用NodeJS+Lighthouse+Gulp搭建自动化网站性能测试的工具

这篇文章主要介绍了关于如何使用NodeJS + Lighthouse + Gulp搭建自动化网站性能测试的工具,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下假设你还不知道Lighthouse是什么Lighthouse 是Google公司旗下一个开源的、可自动化检测网站质量的工具,界面友好、操作简单、使用方式多样、视角全面,可以用它来测试任意网页,普通用户、QA、开发都可以快速上手。启动姿势难度系数 +1使用Lighthouse的方式有很多种,最简单的,可以使用 Chrome 的开发者工具,步骤如下:打开 Chrome 浏览器按F12在弹出来的窗口中打开 audits 标签点击 Perform an audit...勾选全部Run audit难度系数+2也可以使用命令行。安装Node安装Lighthouse npm install -g lighthouse在命令行中run lighthouse <url>以上两种使用方式都不是本文的重点,如果想深入了解,可参照 Run Lighthouse in DevTools难度系数+3由于最近在学习 NodeJS, 因此笔者决定使用 Node 8 + Gulp 来跑 lighthouse,为了提高结果的准确性,每次task都跑10次 lighthouse, 并且只关心结果指标中的 first-meaningful-paint 毫秒数,最终取10次的平均值,为了可视化与可读性,最终的结果以网页的形式展示,用户可在网页上看到每次执行 Lighthouse 之后 first-meaningful-paint 的毫秒数,也可以看到平均值,如果用户对某次执行的细节感兴趣,可以点击链接察看。最终的结果长这个样子:环境搭建安装 Node 8安装依赖包npm i lighthouse --save-devnpm i chrome-launcher --save-devnpm i fs-extra --save-devnpm i gulp --save-dev配置在项目根目录下创建Lighthouse的配置文件 lighthouse-config.js, 这里我们全部使用默认配置,使用默认配置需在配置文件中声明 extends: "lighthouse:default"。module.exports = { extends: "lighthouse:default"}如果读者需要了解更详细的配置选项,可参考:Lighthouse 这篇大部分内容是关于命令行的,命令行参数同样可用于Nodethrottling这篇是关于网络模拟的Default Config 具体的默认配置参数Web Page Test 模拟不同的网速Emulation 模拟不同的设备Coding在项目根目录下创建 gulpfile.js,首先引入所有依赖的工具:const gulp = require("gulp");const lighthouse = require("lighthouse");const chromeLauncher = require("chrome-launcher");const printer = require("lighthouse/lighthouse-cli/printer");const Reporter = require("lighthouse/lighthouse-core/report/report-generator");const fs = require("fs-extra");const config = require(".lighthouse-config.js");在开始使用 lighthouse 之前,首先创建一个写入文件的方法, 用于最后生成自定义的 report 文件:async function write(file, report) { try { await fs.outputFile(file, report); } catch (Error e) { console.log("error while writing report ", e); }}调用 Lighthouse 之前,我们需要首先启动一个 Chrome 的 instance ,并将端口号提供给 Lighthouse 。--headless表示不打开 browser 窗口。async function launchChrome() { let chrome; try { chrome = await chromeLauncher.launch({ chromeFlags: [ "--disable-gpu", "--no-sandbox", "--headless" ], enableExtensions: true, logLevel: "error" }); console.log(chrome.port) return { port: chrome.port, chromeFlags: [ "--headless" ], logLevel: "error" } } catch (e) { console.log("Error while launching Chrome ", e); }}Chrome 实例启动之后,我们就可以调用 Lighthouse , 调用时,须提供需要进行性能测试的网站,参数,以及前文创建好的配置,参数包含了 Chrome 启动端口,启动方式(是否 headless 等信息)。async function lighthouseRunner(opt) { try { return await lighthouse("https://www.baidu.com", opt, config); } catch (e) { console.log("Error while running lighthouse"); }}Lighthouse 的返回结果是一个包含性能测试结果, 最终版的配置参数, 指标分组等信息的 json 对象,读者可以参考 Understanding Results 获得更深入的理解。由于这里我们需要使用 Lighthouse 官方的模板生成报告,因此调用官方提供的方法,注意第一个参数传入 result.lhr, 第二个参数声明生成 html 报告(还可以生成 csv 等格式的报告)。function genReport(result) { return Reporter.generateReport(result.lhr, "html");}下面我们写一个将上面几个方法串起来的函数,首先启动一个 Chrome 实例, 然后将 Chrome 实例的某些参数传递给 Lighthouse,使用 lighthouse 跑出来的结果生成报告,并写入 html 文件, html文件应带有时间戳和执行顺序作为唯一标识。start 方法返回结果中的first-meaningful-paint(这是我们最关心的指标,读者可根据自身需要替换,具体指标可参考 Lighthouse)。async function run(timestamp, num) { let chromeOpt = await launchChrome(); let result = await lighthouseRunner(chromeOpt); let report = genReport(result); await printer.write(report, "html", `./cases/lighthouse-report@${timestamp}-${num}.html`); return result.lhr.audits["first-meaningful-paint"].rawValue; await chrome.kill();}下面, 我们可以正式开始写一个 gulp task 啦,首先获得当前时间戳,用于最终生成的报告命名,然后声明一个数组,用于记录每次跑 Lighthouse 生成的 first-meaningful-paint 毫秒数,然后跑10次 Lighthouse, 使用提前创建的模板文件,根据这10的结果,生成一个汇总报告,这里,笔者使用了Lighthouse对外暴露的工具函数进行字符串的替换。gulp.task("start", async function() { let timestamp = Date.now(); let spent = []; for(let i=0; i<5; i++) { spent.push(await run(timestamp, i)); } let template = await fs.readFileSync("./summary/template/template.html", "utf-8"); let summary = Reporter.replaceStrings(template, [{ search: "%%TIME_SPENT%%", replacement: JSON.stringify(spent) }, { search: "%%TIMESTAMP%%", replacement: timestamp }]); write(`./summary/report/summary@${timestamp}.html`, summary)})最后的最后, 执行:gulp start万事大吉。附上汇总界面的模板源码:<!doctype html><html lang="en"><head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"> <title>Lighthouse Summary Report</title> <style> body { font-family: sans-serif; } table { margin: auto; } tr { border: 1px solid grey; } h1 { text-align: center; margin: 30px auto 50px auto } </style></head><body><table> <h1>Performance Summary Report</h1> <tr> <th> Case No. </th> <th> First Meaningful Paint </th> <th> Link To Details </th> </tr> <tbody id="tableBody"> </tbody></table><script>let timespent = %%TIME_SPENT%%;let timestamp = %%TIMESTAMP%%;let tableBody = document.getElementById("tableBody");let content = "";for(let i=0; i < timespent.length; i++) { content += `<tr style="border: 1px solid grey"> <td> ${i+1} </td> <td> ${timespent[i]} </td> <td> <a href="../../cases/lighthouse-report@${timestamp}-${i}.html">View Details</a> </td> </tr>`}let total = timespent.reduce((i, j) => { return i + j;})let count = timespent.filter(function(i) { return i}).lengthcontent += `<tr><td> AVG</td><td>${total / count}</td></tr>`tableBody.innerHTML = content;</script></body></html>

请教org.w3c.dom中node接口的方法在哪里实现的

Element一定是Node,但Node却不一定是Element。在org.w3c.dom.Node的最前面定义了一堆public static final short类型的整数,就是各种Node类型,其中只有ELEMENT_NODE才是Element类型的,其它类型有比如ATTRIBUTE_NODE,TEXT_NODE,CDATA_SECTIO.

org.w3c.dom node怎么用

import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; public class DomTest_02 { /** * @param args */ public...

你好 Yarn 2,再见 node_modules

三年多前,在 2017 年的时候, Yarn1.0 在 Facebook 的工程师的博客中被正式宣布。在首次发布仅 11 个月后,已有超过 175,000 个存储库开始使用新的包管理器。 Yarn 从那时起一直在稳步发展,成为 npm 包管理工具的替代品,但是还是会有包管理工具共有的毛病,比如速度缓慢、复杂性增加和数据占用。 相较于初始的版本,Yarn2 进行了一些根本性的更改,不仅解决了这些问题,还改进了整体工作流程。 当时流行的一个 搞笑 图在 Yarn2 中将不复存在!新的版本其实在去年一月份就(2020年)发布了,但是花了更多的时间去适配大型项目和库。 一些大公司仍在努力实现兼容性(适配Angular、React Native 和 Flow),但现在已经可以在你的代码中使用 Yarn2 了!(可惜笔者的技术栈是Vue,Yarn2 并没有适配) 即用支持并不是 Yarn 2 带来的唯一重大变化(这个概念本身不是全新的,可以追溯到 2018 年 9 月),该更新实际上提供了许多很棒的功能,让编程变得更加美好简单。 Yarn 的维护者在这些改进上投入了整整一年的时间,你绝对可以感觉到 Yarn 2 是一款经过深思熟虑的产品。 以前的 Yarn CLI 输出就像老太婆的裹脚布一样,又臭又长。而 Yarn2 从更加结构化的 CLI 输出开始,格式和颜色大大提高可读性,最重要的是,每一行都有自己的错误代码,因此变得更容易调试。 新版本显著减少了文件 I/O 数量,从而在安装过程中节省了大量的时间。 Yarn 现在包含一个单地图文件 pnp.js ,用来跟踪包引用并确保节点在运行代码后熟悉正确位置。 .yarn 文件夹会包含下载的软件包,保存在硬盘的某个位置上,那个位置是你的那些依赖项被缓存的地方。 总而言之,惹人烦的 node_modules 没有了! 更重要的是,Yarn2 提供了详细的旧项目迁移文档,在迁移后不会丢失node_modules文件夹 ,还等什么?赶紧上 yarn 官网查看迁移文档完善你的项目吧!

梳理 node、npm、yarn 相关路径

如果你对 npm、yarn 全局安装路径存疑,很混乱分不清,那么这篇文章应该能帮到你。本文以 macOS 为例,不同操作系统可能略有差异。 其实在安装完 Node 之后,便有类似提示: 可以得知 Node 和 NPM 的默认安装路径是 /usr/local/bin 。如果 /usr/local/bin 路径并不存在于环境变量 PATH 中,需在配置文件中写入。比如: 具体配置文件是 ~/.bash_profile 还是 ~/.zshrc ,取决于你当前使用哪一种 Shell 解析器。 使用 which 命令可查看「可执行文件」的路径,比如: 其中 /usr/local/bin 目录下的可执行文件多是软链接,并非文件真正所在路径。 说明一下,本文将以这种方式安装的 Node 称为系统版本的 Node,用于区别使用 nvm 安装的 Node。 从 npm Docs 官方文档中,对「全局安装」如何存放文件都有比较清晰的描述( 详看 ),翻译过来就是: 其中 prefix 是 npm 的一个配置项( 详见 ),它的默认值与 Node 的安装位置有关。在 Unix/Linux/Mac 操作系统中,通常是 /usr/local 。在 Windows 操作系统上通常是 %AppData% pm 。其中「可执行文件」是指 package.json 中 bin 字段的配置项。 使用 npm config 命令可对 prefix 配置进行操作: 也可在配置文件 ~/.npmrc 直接进行修改( 详见 )。 因此, 可通过以下命令查看: 可通过 npm ls 命令查看全局安装的依赖包,个人更喜欢使用其别名 npm list ,原因是它跟 yarn list 一致。 其打印结果为树状形式,可配合 --depth=n 参数使用以查看包的依赖信息,其中 n 表示树状深度。上面的 npm list -g 相当于 npm list -g --depth=0 。 插个话,在 v2 版本有着较大的差异,比如在 v2 版本将 yarn global 移除,其替代者是 yarn dlx ,更多 请看 ,这里不展开赘述了。 yarn 全局安装路径与 npm 不同,默认情况下: 可通过以下命令查看: 若要修改以上配置,可通过 yarn config 命令处理: 需要注意的是,修改全局安装路径的配置 key 是 global-folder ,可执行文件的 key 为 prefix 。别跟 npm 混淆了。 也可以在配置文件 ~/.yarnrc 直接修改: 需要注意的是,其中 npm 配置文件使用的是 ini-formatted 格式,也就是 key=value 形式,而 yarn 则是 key "value" 形式。 我们知道 npm(Node Package Manager)是 Node 包管理工具,而 nvm(Node Version Manager)则是 Node 版本管理工具。它可以通过命令行快速安装、使用不同版本的 Node。 假设有多个项目使用了不同版本的 Node,或者需要在不同版本的 Node 下测试我们开发的 npm 包,那么使用 nvm 将会很高效。其安装不展开细说,请看 官方文档 。 第一节已经介绍了,使用「传统」的方法安装其路径如下: 但如果使用 nvm 来管理 Node,这些都将会发生变化。当使用官方指引来安装 nvm,相关内容将会默认存放至 ~/.nvm 目录。 当使用 nvm install 来安装 Node,比如: 它将会存放于 ~/.nvm/versions/node/v16.14.0 目录下。 切换 system Node 与 nvm Node,只要通过以下方式即可: 我们观察一下 prefix 的变化就知道其安装路径了: 因此,在使用 nvm 管理的情况下: 前面提到过, prefix 的默认位置与 Node 的安装路径有关。比如,在 Unix/Linux/Mac 操作系统中, prefix 通常是 Node 安装路径的上一级,也就是 ~/.nvm/versions/node/vX.X.X 目录。因此,当我们在切换 Node 版本中,它总能正确地安装到 /usr/local/lib/node_modules 或 ~/.nvm/versions/node/vX.X.X/lib/node_modules/ 目录。 但是,如果在 ~/.npmrc 中配置了 prefix ,无论你如何切换 Node 版本,它总是被安装至所配置的路径下。 这样就违背了用 nvm 的初心,自定义 prefix 配置与 nvm 不兼容。nvm 在其官方文档中用指出( 详见 ): 如果你此刻用着 nvm,同时没有意识到这个问题,建议立刻去检查并将其移除。 目前,我同时使用着 nvm、npm、yarn(v1)三个工具,那么平常是这样管理它们的: 基于这种原则下,全局安装的依赖包将有这些路径: 使用以下命令,可查看全局依赖包所在路径: 使用以下命令,可查看已安装的全局依赖包: 到此,本文结束。以上希望可以帮你厘清个中混淆之处。 The end.

升级Yarn 2,摆脱node_modules

node 项目中最臭名昭著的莫过于 node_modules 文件夹,这个糟糕的结构动辄使你的文件数目增加几万甚至几十万,无论是安装还是删除,都要消耗大量时间,并且占据大量 inode 结点,我们随便进入一个 react 项目文件夹,看一下由于有 node_modules 会使你的项目中的文件个数变成多少: 仅仅一个项目下面就有多达22万个文件。 现在我们来看一下目前的 yarn 版本号是多少: 嗯,目前 yarn 的版本号是 1.22.11 ,那我们如何安装 yarn 2 呢?答案是不需要安装,只需要设置就可以了。 设置完了之后,我们再来看一下 yarn 的版本号: 不是说好的升级到 yarn 2 吗?怎么变成 3.0 了?不用恐慌,越高越好。 然后我们来看一下项目文件夹下多了这么几个文件,首先就是根目录下多了一个 .yarnrc.yml ,里面只有一句话: 相应的,还多了一个文件夹 .yarn ,里面有一个子文件夹 releases ,里面有一个文件 yarn-berry.cjs ,这几个文件就是全部 yarn 2 增加的内容了,这些内容不要在 .gitignore 里忽略,其它的内容是需要忽略的,现在我们来在 .gitignore 里增加一些需要忽略的内容: 接下来,我们准备利用新版的 yarn 安装我们的依赖文件,在此之前,我们需要先设置一下 yarn 库的镜像服务器以加快整个下载过程: 这时候,你再打开项目根目录下的 .yarnrc.yml 文件,会发现里面多了一行: 所以我们知道其实这个 yarn config 命令也没有什么特别的地方,只是通过它来修改 .yarnrc.yml 文件而已,你也可以通过直接修改 .yarnrc.yml 文件来达到同样的效果。 现在,我们开始删除旧的 node_modules 文件夹和 yarn.lock 文件,并重建整个项目: 整个下载过程应该还是比较顺利的,我们来看一下项目文件夹中多了哪些文件: 没有了 node_modules 文件夹,我们来看一下 .yarn/cache 文件夹下有什么内容,里面有我们之前依赖的 node_modules 文件夹下的所有依赖包,但不再是以目录的形式存在,而是变成了一个个 zip 文件, yarn 2 就是利用项目根目录下的 .pnp.cjs 文件定位到这些 zip 文件以达到取代 node_modules 的作用,这样极大程度地减少了项目中的文件个数。 下面我们开始启动项目: 十有八九你的项目这时候是启动不起来的,不要慌,这篇文章告诉你所有的解决方法。 首先,你遇到错误可能是这样: 具体内容可能不一样,但你要注意这个关键词 Your application ,这说明是你的代码当中的某个位置引用了后面的插件,但你没有在 package.json 文件中显式声明它,那为什么之前用 yarn 1 或者 npm 的时候没有这个问题呢?因为以前是有 node_modules 文件夹的,所有依赖包都被平摊在这个文件夹中,即使是被其它依赖的依赖引入的,它也会被释放在 node_modules 根目录下,所以 node 可以很轻松地找到它,而现在这个文件夹没有了,我们必须显式地在 package.json 文件中引用它,才能引导 yarn 找到这个依赖项。因此,解决这种 Your application 缺乏某个依赖项的方法很简单,我们只需要用 yarn 安装它就可以了: 哦,又出错误了: 这是因为我们在安装的时候没有指定版本,导致安装的插件版本过高,我们在 package.json 里把版本降低一些: 然后重新执行 yarn 进行安装,运行 yarn start 再次启动,终于启动起来了!不过,不要高兴得太早,又遇到了这样的问题: 不要慌,既然还是 Your application 缺乏某个依赖包,那就还是我们的问题,停下来再安装它,然后再启动,直到解决完所有 Your application 引起的问题。 这时候,产生了新的错误: 虽然同样是找不到依赖项,但这次的错误不是由于我们自己的应用导致的,而是由于依赖项自身导致的,这种问题该如何解决呢?不要急,我们打开 .yarnrc.yml 文件,按照错误提示增加以下设置: 缺什么咱们就增加什么,有时候还要注意版本号。同样,这个问题不是由于 yarn 2 导致,而是因为我们的依赖项该增加的依赖没有增加而已,我们这里只是给它补全依赖,使它得以正常运行。 别忘了,每次修改完 .yarnrc.yml 之后,都需要重新执行 yarn ,然后再执行 yarn start 。 至此为止,我们的项目终于能够成功运行了!我们来看一下目前项目文件夹中的文件个数: 现在只有 17000 个文件了,比我们最开始的 22 万个文件减少了 20 多万,运行速度也成倍提升。 怎么样,是不是很值得一试呢? 文章来源于@ 张京老师, https://segmentfault.com/a/1190000040520326

锂离子电池正极到底是anode,还是cathode

正负极是在原电池中的概念,这里的正负指的是电位的正负:电位正的为正极,发生还原反应,得电子;电位负的为负极,发生氧化反应,失电子。而阴阳极是在电解池中的概念,这里的阴阳指的是发生氧化或还原反应:发生氧化反应的为阳极,发生还原反应的为阴极。词典里anode翻译为负极,阳极,cathode翻译为正极,阴极。分别对应的是原电池和电解池。而锂离子电池体系,既是原电池(放电时)又是电解池(充电时)。通常正极(cathode)是钴酸锂,负极(anode)是石墨。这样讲在放电时一点问题都没有,可是充电时怎么描述呢?充电时石墨电极就变成阴极(cathode,发生还原反应),钴酸锂电极变成阳极(anode,发生氧化反应)。这样一来充电和放电两个过程就很难描述。所以无论是充电过程还是放电过程,为了描述的方便,我们都称为钴酸锂电极为正极(cathode),石墨电极为负极(anode)。至少我个人在描述的时候,就避免使用阴阳极。

在node.js中如何使用http模块

这篇文章主要介绍了深入理解node.js http模块,现在分享给大家,也给大家做个参考。http模块主要用于搭建HTTP服务端和客户端,使用HTTP服务器或客户端功能都必须调用http模块。创建服务器var http = require(“http”);var url = require(“url”);//创建服务器//http继承自tcpvar server = http.createServer(function (req,res) { var urlstr = req.url;//获取请求的路径 var urlMethod = req.method;//获取请求的方法 var urlObj = url.parse(urlstr,true); console.log(urlObj); console.log(urlMethod); res.end(“hello”);});server.listen(8080);对请求进行处理请求分为两种:get和post,get请求url地址带参数,req.url便能获取参数,而post请求便复杂一些。使用req.on()处理post请求。post请求方式:使用req.on("data"function(){})方式读取,使用str字符串拼接,在req.on("end",function(){})读取结束后输出str便是我们想得到的post请求发送的参数;get请求方式:在请求地址上使用url.parse(req.url,true).query得到参数。var http = require("http");var fs = require("fs");var url = require("url");var querystring = require("querystring");var server = http.createServer(function (req,res) { console.log(req.method); var pathname = url.parse(req.url,true).pathname; if(pathname=="/"){ // 加载注册页面 var rs = fs.createReadStream("post.html"); rs.pipe(res); }else if(pathname=="/post"){ // 处理post请求 var str = ""; req.on("data",function (chunk) { // console.log(chunk.toString()); str += chunk; }); req.on("end",function(){ var postObj = querystring.parse(str); console.log(postObj); }) }else if(pathname=="/get"){ // get请求 var getObj = url.parse(req.url,true).query; res.write(JSON.stringify(getObj)); res.end(); }else if(pathname!="/favicon.ico"){ var rs = fs.createReadStream("."+pathname); rs.pipe(res); };});server.listen(8787);上传文件处理前端html代码如下:就不细说了。<form action=“/upimg” method=“post” enctype=“multipart/form-data”>用户名: <input type=“text” name=“user”><br> 密码: <input type=“password” name=“pass”><br>上传图片: <input type=“file” name=“file1”><br> <input type=“submit” value=“提交”></form>想要实现文件上传,要引入formidable模块var formidable = require("formidable");若是没有此模块,在终端输入 npm install formidable安装。form.parse(req,function(err,fields,fies){})方法回调函数的三个参数err:返回错误信息fields:post请求返回的字段以及对应的值fies:上传的文件对象,对象中包含文件的很多详细信息得到文件信息后,使用数据流的读和写复制文件var http = require("http");var fs = require("fs");var url = require("url");// 文件上传var formidable = require("formidable");var server = http.createServer(function(req,res){ var pathname = url.parse(req.url,true).pathname; if(pathname=="/"){ var rs = fs.createReadStream("uploads.html"); rs.pipe(res); }else if(pathname=="/uploads"){ // 实例化一个formidable类 var form = new formidable.IncomingForm(); // 调用parse方法 form.parse(req,function(err,fields,files){ if(err){ return console.log(err); }else{ // console.log("字段",fields); // 存储字段 var fieldStr = JSON.stringify(fields); fs.writeFileSync("1.txt",fieldStr); // 转存文件 if(!fs.existsSync("uploads")){ fs.mkdir("uploads"); } // 随机路径 var filePath = files.img.path; var rs = fs.createReadStream(filePath); var ws = fs.createWriteStream("./uploads/"+files.img.name); rs.pipe(ws); rs.on("data",function (chunk) { }) rs.on("end",function(){ console.log("复制成功"); res.write("上传成功"); res.end(); }) res.setHeader("Content-type","text/html;charset=utf8"); console.log("文件",files); } }) }else if(pathname!="/favicon.ico"){ var rs = fs.createReadStream("."+pathname); rs.pipe(res); }});server.listen(8880);http模拟客户端主要是options的配置,最基本的参数如下面的代码块。method:说明请求方式;host: 服务器ip,这里以本地localhost为例;port:服务器端口号;path:请求路径;此时不在使用http.createServer()创建服务器了,而是使用http.request()请求服务器,其余的都和服务器差不多了。// 通过nodejs模拟客户端var http = require("http");var options = { method:"post", host:"localhost", port:2121, path:"/"};var request = http.request(options,function (res) { var str = ""; res.on("data",function(chunk){ str += chunk; }); res.on("end",function () { console.log(str); })});var obj = { name:"李四", age:20}request.write(JSON.stringify(obj));request.end();上面是我整理给大家的,希望今后会对大家有帮助。相关文章:在vue-router中配合ElementUI如何实现导航详解解读在vue项目中引入elementUI组件在vue中实现刷新和tab切换在Vue-cli中如何实现为单独页面设置背景色有关Material在Angular2中的使用(详细教程)在 Angular中 使用Lodash方法具体该怎么做?使用原生js实现省市区三级联动

nodejs后台,用formidable处理上传文件时,前台需要传什么参数给后端?

用一个表单<form method="post" enctype="multipart/form-data" action="/file-upload"> <input type="file" name="thumbnail"> <input type="submit"></form>这样就可以了

document.body.parentNode.style.overflow = "hidden";

document.body.style.overflow = "hidden";试试看

c#怎么向nodejs的socket.io发送请求

1. 简介首先是Socket.IO的官方网站:http://socket.io官网非常简洁,甚至没有API文档,只有一个简单的“How to use”可以参考。因为Socket.IO就跟官网一样简洁好用易上手。那么Socket.IO到底是什么呢?Socket.IO是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5,应该可以满足绝大部分需求了。2. 安装部署2.1 安装首先安装非常简单,在node.js环境下只要一句:复制代码 代码如下:npm install socket.io2.2 结合express来构建服务器express是一个小巧的Node.js的Web应用框架,在构建HTTP服务器时经常使用到,所以直接以Socket.IO和express为例子来讲解。复制代码 代码如下:var express = require("express") , app = express() , server = require("http").createServer(app) , io = require("socket.io").listen(server);server.listen(3001);若不使用express,请参考socket.io/#how-to-use3. 基本使用方法主要分为服务器端和客户端两段代码,都非常简单。Server(app.js):复制代码 代码如下://接上面的代码app.get("/", function (req, res) { res.sendfile(__dirname + "/index.html");});io.sockets.on("connection", function (socket) { socket.emit("news", { hello: "world" }); socket.on("other event", function (data) { console.log(data); });});首先io.sockets.on函数接受字符串"connection"作为客户端发起连接的事件,当连接成功后,调用带有socket参数的回调函数。我们在使用socket.IO的时候,基本上都在这个回调函数里面处理用户的请求。socket最关键的是emit和on两个函数,前者提交(发出)一个事件(事件名称用字符串表示),事件名称可以自定义,也有一些默认的事件名称,紧接着是一个对象,表示向该socket发送的内容;后者接收一个事件(事件名称用字符串表示),紧接着是收到事件调用的回调函数,其中data是收到的数据。在上面的例子中,我们发送了news事件和收到了other event事件,那么客户端应该会有对应的接收和发送事件。没错,客户端代码和服务器正好相反,而且非常相似。Client(client.js)复制代码 代码如下:<script src="/socket.io/socket.io.js"></script><script> var socket = io.connect("http://localhost"); socket.on("news", function (data) { console.log(data); socket.emit("other event", { my: "data" }); });</script>有两点要注意的:socket.io.js路径要写对,这个js文件实际放在了服务器端的node_modules文件夹中,在请求这个文件时会重定向,因此不要诧异服务器端不存在这个文件但为什么还能正常工作。当然,你可以把服务器端的socket.io.js这个文件拷贝到本地,使它成为客户端的js文件,这样就不用每次都向Node服务器请求这个js文件,增强稳定性。第二点是要用var socket = io.connect("网站地址或ip");来获取socket对象,接着就可以使用socket来收发事件。关于事件处理,上面的代码表示收到“news”事件后,打印收到的数据,并向服务器发送“other event”事件。注:内置默认的事件名例如“disconnect”表示客户端连接断开,“message”表示收到消息等等。自定义的事件名称,尽量不要跟Socket.IO中内置的默认事件名重名,以免造成不必要的麻烦。4. 其他常用API1).向所有客户端广播:socket.broadcast.emit("broadcast message");2).进入一个房间(非常好用!相当于一个命名空间,可以对一个特定的房间广播而不影响在其他房间或不在房间的客户端):socket.join("your room name");3).向一个房间广播消息(发送者收不到消息):socket.broadcast.to("your room name").emit("broadcast room message");4).向一个房间广播消息(包括发送者都能收到消息)(这个API属于io.sockets):io.sockets.in("another room name").emit("broadcast room message");5).强制使用WebSocket通信:(客户端)socket.send("hi"),(服务器)用socket.on("message", function(data){})来接收。5. 使用Socket.IO构建一个聊天室最后,我们通过一个简单的实例来结束本篇。用Socket.IO构建一个聊天室就是50行左右的代码的事情,实时聊天效果也非常好。以下贴出关键代码:Server(socketChat.js)复制代码 代码如下://一个客户端连接的字典,当一个客户端连接到服务器时,//会产生一个唯一的socketId,该字典保存socketId到用户信息(昵称等)的映射var connectionList = {};exports.startChat = function (io) { io.sockets.on("connection", function (socket) { //客户端连接时,保存socketId和用户名 var socketId = socket.id; connectionList[socketId] = { socket: socket }; //用户进入聊天室事件,向其他在线用户广播其用户名 socket.on("join", function (data) { socket.broadcast.emit("broadcast_join", data); connectionList[socketId].username = data.username; }); //用户离开聊天室事件,向其他在线用户广播其离开 socket.on("disconnect", function () { if (connectionList[socketId].username) { socket.broadcast.emit("broadcast_quit", { username: connectionList[socketId].username }); } delete connectionList[socketId]; }); //用户发言事件,向其他在线用户广播其发言内容 socket.on("say", function (data) { socket.broadcast.emit("broadcast_say",{ username: connectionList[socketId].username, text: data.text }); }); })};Client(socketChatClient.js)复制代码 代码如下:var socket = io.connect("http://localhost");//连接服务器完毕后,马上提交一个“加入”事件,把自己的用户名告诉别人socket.emit("join", { username: "Username hehe"});//收到加入聊天室广播后,显示消息socket.on("broadcast_join", function (data) { console.log(data.username + "加入了聊天室");});//收到离开聊天室广播后,显示消息socket.on("broadcast_quit", function(data) { console.log(data.username + "离开了聊天室");});//收到别人发送的消息后,显示消息socket.on("broadcast_say", function(data) { console.log(data.username + "说: " + data.text);});//这里我们假设有一个文本框textarea和一个发送按钮.btn-send//使用jQuery绑定事件$(".btn-send").click(function(e) { //获取文本框的文本 var text = $("textarea").val(); //提交一个say事件,服务器收到就会广播 socket.emit("say", { username: "Username hehe" text: text });});

有没有办法干掉node监听的所有事件

Import events modulevar events = require(;events.on(;例子创建一个名为具有以下代码main.js一个js文件; Create an eventEmitter objectvar eventEmitter = new events.emit(;eventName;eventName.js具有多个内置通过事件模块和用于将事件绑定和事件侦听; Fire the connection event eventEmitter; Fire an event eventEmitter:/.emit(:///:/.Program Ended;/, function(){console.log(;data received succesfully,如下EventEmitter类可用事件;).;);});/ Create an eventEmitter objectvar eventEmitter = new events;}。事件驱动编程Node.js大量使用事件.EventEmitter();/, connectHandler);/ Bind the connection event with the handlereventEmitter.on(;connection;, eventHandler).data received succesfully;data_received;/ Bind the data_received event with the anonymous functioneventEmitter.on(;data_received;.;);/.log(;connection succesful;connection;);console.log(Program Ended.);现在让我们试着运行上面的程序作为检查的输出:$ mnode main;);我们可以通过编程触发一个事件,如下所示;/Node JS是单线程应用程序,但它通过事件和回调概念,支持并发,这也是为何Node,声明的函数; Fire the data_received event eventEmitter;/ Create an event handler as followsvar connectHandler = function connected() {console.js是相当快相对于其他类似的技术。当Node启动其服务器,它可以简单地启动它的变量,然后简单地等待发生的事件。在事件驱动的应用中,通常主循环监听事件,然后触发回调函数时被检测到这些事件之一。尽管事件似乎类似于回调。不同之处在于如下事实; Import events modulevar events = require(;events.EventEmitter();以下为事件处理程序绑定使用事件的语法.emit(,当异步函数返回其结果的回调函数被调用的地方作为对观察者模式的事件处理。 监听事件的功能作为观察员。每当一个事件被触发,它的监听函数就开始执行。Node; Bind event and even handler as followseventEmitter://),每当任何任务得到完成,它触发这标志着该事件侦听器函数执行相应的事件。Node JS使用观察者模式。Node线程保持一个事件循环。 由于Node JS每一个API是异步的,作为一个单独的线程,它使用异步函数调用,以保持并发性;).js这将产生以下结果:connection succesful

k8s:将pod部署到指定的node运行(pod&node选择部署策略)

查看所有节点labels: 添加labels: 修改yaml配置文件: 添加nodeSelector配置,样式为[label.key]: [label.value] 修改后重启服务 参考文章: https://blog.csdn.net/lzy_zhi_yuan/article/details/106913428 nodeSelector配置相对简单,k8s提供了另外一个pod调度配置: nodeAffinity(节点亲和) ,相对于nodeSelector的简单匹配他拥有更多更加个性化的配置。 这段配置表示:该pod可以被调度到标签key为 "deploy.type" ,值为 "yztssjdxt-test" 或 "yztssjdxt" 的节点。 通过使用的语句不同,调度分成软策略(soft)和硬策略(hard) ,在软策略下,如果没有满足调度条件的节点,pod会忽略这条规则,继续完成调度。而硬策略下,pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。 DuringScheduling和IgnoredDuringExecution组合生成目前主要的nodeaffinity策略 软硬策略可以组合使用 ,如下面这段配置中pod必须被调度到标签为 "deploy.type=yztssjdxt-test" 的节点。另外,在满足该条件的节点中,优先使用具有 "server=oms" 标签的节点。 nodeAffinity中nodeSelector字段下,节点满足任何一个条件即可;但更下一级matchExpressions,节点必须同时满足所有条件才能运行pod 。 如下面这段配置需要deploy.type=yztssjdxt-test、server=oms同时满足 而这段配置只需要deploy.type=yztssjdxt-test、deploy.type1=yztssjdxt满足一个即可 operator字段 :pod与node的匹配逻辑,可选的操作符有:(我只测过in、notin) 如下方这段配置,pod将不会调度到deploy.type=yztssjdxt-test的node上

《CyranodeBergerac》epub下载在线阅读,求百度网盘云资源

《Cyrano De Bergerac》(Rostand, Edmond)电子书网盘下载免费在线阅读资源链接:链接:https://pan.baidu.com/s/127hZ-1EwPEQqNIY5y_Nnkg 提取码:i625书名:Cyrano De Bergerac作者:Rostand, Edmond出版年份:2009-2页数:244内容简介:Tonight When I make my sweeping bow at heaven"s gate, One thing I shall still possess, at any rate, Unscathed, something outlasting mortal flesh, And that is ... My panache." The first English translation of Cyrano de Bergerac, in 1898, introduced the word panache into the English language. This single word summed up Rostand"s rejection of the social realism which dominated late nineteenth-century theatre. He wrote his heroic comedy", unfashionably, in verse, and set it in the reign of Louis XIII and the Three Musketeers. Based on the life of a little known writer, Rostand"s hero has become a figure of theatrical legend: Cyrano, with the nose of a clown and the soul of a poet, is by turns comic and sad, as reckless in love as in war, and never at a loss for words. Audiences immediately took him to their hearts, and since the triumphant opening night in December 1897 - at the height of the Dreyfus Affair - the play has never lost its appeal. The text is accompanied by notes and a full introduction which sets the play in its literary and historical context. Christopher Fry"s acclaimed translation into chiming couplets" represents the homage of one verse dramatist to another.

结构施工图中“节点”翻译成英文是用JOINT还是NODE?

来个甲级院的设计师来解答,学习。

结构施工图中“节点”翻译成英文是用JOINT还是NODE?

来个甲级院的设计师来解答,学习。

e.parentNode.nextSibling.innerHTML=e.innerHTML;是什么意思呀....

节点e里面的HTML内容赋值给该节点的父节点的下一个节点里面;

安装sql server时报cluster node failed怎么办

1.Authentication to the ricci agent at node1 failed修改ricci的密码就可以了passwd ricci 然后重启ricci服务2.Unable to establish an SSL connection to node1:11111 after 5 tries.确保ricci正常启动,如果启动正常,查看是不是iptables的设置问题,可以直接把iptables关掉3.、提示node1不是集群节点一般都是因为cman 和 rgmanager没有起来导致的,启动cman和rgmanager刷新下。4.启动cman的时候报错一般是因为NetworkManager在启动的原因,把NetworkManager关掉即可,并设置成开机关闭。5.重启报错:Kernel panic not syncing :Attempted to kill init!发现是自己吧selinux文件中的selinuxType修改错误导致的。改过来就行了!6.创建Cluster的时候提示node1 not a cluster member可尝试手动先启动rgmanager 然后启动cman7.node无法发现iscsi目标:No portals found修改openfile vi /etc/initiators.deny 把要发现的目标注释掉

LTE中的基本术语请教:E-UTRAN,ENodeB,EPC,各指什么,区别在哪里

UTRAN——U指的是UMTS(universal mobile telecommunication system)上面很详尽并且通俗易懂~

013 Hadoop 高可用 - Namenode 自动故障切换

013 Hadoop High Availability – Namenode Automatic Failover Before Hadoop 2.0 that is Hadoop 1.0 faced a single point of failure (SPOF) in NameNode. This means if the NameNode failed the entire system would not function and manual intervention was necessary to bring the Hadoop cluster up with the help of secondary NameNode which resulted in overall downtime. With Hadoop 2.0 we had single standby node to facilitate automatic failover and with Hadoop 3.0 which supports multiple standby nodes, the system has become even more highly available. In this tutorial, we will talk about Hadoop high availability. We will look at various types of failover and discuss in detail how the components of Zookeeper provide for automatic failover. 在 Hadoop 2.0 之前,Hadoop 1.0 在 NameNode 中面临单点故障 (SPOF).这意味着,如果 NameNode 出现故障,整个系统将无法运行,需要手动干预 Hadoop 集群 在二级 NameNode 的帮助下,导致了整体停机.借助 Hadoop 2.0,我们有了单个备用节点,以方便自动故障切换; 借助支持多个备用节点的 Hadoop 3.0,系统变得更加可用.在本教程中,我们将讨论 Hadoop 高可用性.我们将研究各种类型的故障切换,并详细讨论 动物园管理员组件 提供自动故障切换. Hadoop High Availability – Automatic Failover With Hadoop 2.0, we have support for multiple NameNodes and with Hadoop 3.0 we have standby nodes. This overcomes the SPOF (Single Point Of Failure) issue using an extra NameNode (Passive Standby NameNode) for automatic failover. This is the high availability in Hadoop. 借助 Hadoop 2.0,我们支持多个名称节点,借助 Hadoop 3.0,我们拥有备用节点.这克服了使用额外的 NameNode (被动备用 NameNode) 进行自动故障切换的 SPOF (单点故障) 问题.这是 Hadoop 中的高可用性. Failover is a process in which the system transfers control to a secondary system in an event of failure. 故障切换是指在发生故障时,系统将控制转移到辅助系统的过程. There are two types of failover: 故障切换有两种类型: Automatic failover in Hadoop adds up below components to a Hadoop HDFS deployment: Hadoop 中的自动故障切换将以下组件添加到 Hadoop HDFS 部署中: Zookeeper quorum is a centralized service for maintaining small amounts of data for coordination, configuration, and naming. It provides group services and synchronization. It keeps the client informed about changes in data and track client failures. Implementation of automatic HDFS failover relies on Zookeeper for: Zookeeper 是用于维护少量数据以进行协调、配置和命名的集中服务.它提供组服务和同步.它让客户了解数据的变化,并跟踪客户故障.执行自动 HDFS 失败转移功能依赖于管理员的: ZKFC is a client of Zookeeper that monitors and manages the namenode status. So, each of the machines which run namenode service also runs a ZKFC. ZKFC 是一个客户管理员监督和管理、复制指令的情况.因此,运行 namenode 服务的每台机器也都运行 ZKFC. ZKFC handles: ZKFC 手柄: **Health Monitoring – **ZKFC periodically pings the active NameNode with Health check command and if the NameNode doesn"t respond it in time it will mark it as unhealthy. This may happen because the NameNode might be crashed or frozen. 健康监测- ZKFC 定期用健康检查命令 ping 活跃的 NameNode,如果 NameNode 没有及时响应,它会将其标记为不健康.这可能是因为 NameNode 可能会崩溃或冻结. Zookeeper Session Management – If the local NameNode is healthy it keeps a session open in the Zookeeper. If this local NameNode is active, it holds a special lock znode . If the session expires then this lock will delete automatically. 会话管理- 如果本地名称节点是健康的,它会在 Zookeeper 中保持会话打开.如果这个本地名称节点是活动的,它会持有一个特殊的锁 Znode .如果会话过期,则此锁将自动删除. Zookeeper-based Election – If there is a situation where local NameNode is healthy and ZKFC gets to know that none of the other nodes currently holds the znode lock, the ZKFC itself will try to acquire that lock. If it succeeds in this task then it has won the election and becomes responsible for running a failover. The failover is similar to manual failover; first, the previously active node is fenced if required to do so and then the local node becomes the active node. 动物园管理员的选举 如果本地 NameNode 健康,ZKFC 知道目前没有其他节点持有 znode 锁,ZKFC 本身将尝试获得该锁.如果它在这个任务中成功,那么它就赢得了选举,并负责运行故障切换.故障切换类似于手动故障切换; 首先,如果需要,以前的活动节点会被隔离,然后本地节点会成为活动节点. Hence, in this Hadoop High Availability article, we saw Zookeeper daemons configure to run on three or five nodes. Since Zookeeper does not have high resource requirement it could be run on the same node as the HDFS Namenode or standby Namenode. Many operators choose to deploy third Zookeeper process on the same node as the YARN Resource Manager. So, it is advised to keep Zookeeper data separate from HDFS metadata i.e. on different disks as it will give the best performance and isolation. 因此,在这个 Hadoop 高可用性 文章中,我们看到 Zookeeper 守护进程被配置为在三到五个节点上运行.因为管理员没有所需的它可以运行在相同的节点为 HDFS 、复制指令或待机、复制指令.许多操作员选择在与 YARN 资源管理器相同的节点上部署第三个 Zookeeper 进程.因此,建议将 Zookeeper 数据与 HDFS 元数据分开,即在不同的磁盘上,因为它将提供最佳的性能和隔离. You must check the latest Hadoop Interview Questions for your upcoming interview. 你必须检查一下 最新 Hadoop 面试题: 为你即将到来的面试. Still, if any doubt regarding Hadoop High Availability, ask in the comments. We will definitely get back to you. 尽管如此,如果对 Hadoop 的高可用性有任何疑问,请在评论中提问.我们一定会给你回复的 https://data-flair.training/blogs/hadoop-high-availability

javascript的parentNode,parentElement

parentElement 是IE专用属性,parentNode 是W3C标准属性,parentElement 指的是该元素的父元素,parentNode指的是该DOM元素节点的上级节点

JS中的parentElement,parentNode,childNodes,children,[object text]问题

parentElement 获取对象层次中的父对象。 parentNode 获取文档层次中的父对象。 childNodes 获取作为指定对象直接后代的 HTML 元素和 TextNode 对象的集合。 children 获取作为对象直接后代的 DHTML 对象的集合。 parentNode和parentElement功能一样,childNodes和children功能一样。但是parentNode和childNodes是符合W3C标准的,可以说比较通用。而另外两个不是标准,Firefox就不支持。当父节点的nodeType不是1,即不是element节点的话,它的parentElement就会是null一般情况parentNode可以取代parentElement的所有功能。parentElement匹配的是parent为element的情况,而parentNode匹配的则是parent为node的情况。element是包含在node里的,它的nodeType是1。

华为wcdma 怎么知道nodeb的id

你是应届毕业生,运营商不会看你有没有什么认证,那些都是针对工程师而言的。想去运营商就要多了解一下他们什么时候有招聘,在什么方面需要人。 你需要展现给运营商的是有上进心、有责任心、能够融入到他们的工作环境。 还有,运营商中好的职位...

parentNode(parentNode属性什么意思)

您好,我就为大家解答关于parentNode,parentNode属性什么意思相信很多小伙伴还不知道,现在让我们一起来看看吧!1、parentNode 属性以 N... 您好,我就为大家解答关于parentNode,parentNode属性什么意思相信很多小伙伴还不知道,现在让我们一起来看看吧! 1、parentNode 属性以 Node 对象的形式返回指定节点的父节点。 2、parentNode跟parentElement除了前者是w3c标准,后者只ie支持。 3、当父节点的nodeType不是1,即不是element节点的话,它的parentElement就会是null。 4、一般情况parentNode可以取代parentElement的所有功能。 5、parentElement匹配的是parent为element的情况,而parentNode匹配的则是parent为node的情况。 6、element是包含在node里的,它的nodeType是1。

node.js怎么去除字符串空格

忘了U0001f61cU0001f61c

怎么自己检查NodeJS的代码是否存在内存泄漏

首先,我们来看一个简单的内存泄漏var http = require("http");var server = http.createServer(function (req, res) {for (var i=0; i<1000; i++) {server.on("request", function leakyfunc() {});}res.end("Hello World ");}).listen(1337, "127.0.0.1");server.setMaxListeners(0);console.log("Server running at http://127.0.0.1:1337/. Process PID: ", process.pid);每一个请求我们增加了1000个导致泄漏的监听器。如果我们在一个shell控制台中执行以下命令:while true; do curl "http://127.0.0.1:1337/"; done然后在另外一个shell控制台中查看我们的进程top -pid我们会看到node进程产生异常高的内存占用,我们的node进程看起来失控了。那么,当我们的node进程出现这种情况的时候,通常我们该怎样诊断出问题的根源?内存泄露的检测npm模块 memwatch 是一个非常好的内存泄漏检查工具,让我们先将这个模块安装到我们的app中去,执行以下命令:npm install --save memwatch然后,在我们的代码中,添加:var memwatch = require("memwatch");//memwatch.setup(); 原文有这行代码,最新版本的memwatch已去掉这个方法(译者注)然后监听 leak 事件memwatch.on("leak", function(info) {console.error("Memory leak detected: ", info);});这样当我们执行我们的测试代码,我们会看到下面的信息:{start: Fri Jan 02 2015 10:38:49 GMT+0000 (GMT),end: Fri Jan 02 2015 10:38:50 GMT+0000 (GMT),growth: 7620560,reason: "heap growth over 5 consecutive GCs (1s) - -2147483648 bytes/hr"}参考文献https://w3ctech.com/topic/842#rd?sukey=1a2e6cf0ed628693963c7d024fae83cd29147e987cc93e20f3292fef404a2fc91774fa0e1af5eeb690c5521ad1e164fb

node-sass 安装失败 win32-x64-57_binding.node

window系统下,安装npm install环境的时候缺少node-sass文件 解决办法: 如果还是安装不成功,把modules包删除,检查一下.npmrc里面是否有路径设置,先删除(保留副本,待安装好node-sass再恢复),再重复上面的两步安装步骤。 如果package.json中引用了gulp-sass,有时候安装或这运行也会出问题,先删除package.json中的gulp-sass,按照上面的两个不走步骤手动安装node-sass,再npm install -D gulp-sass。

node-sass插件缺失vendor目录的问题

Mac重装系统后,原有使用node-sass插件的项目在npm install命令安装完成后,商量好似的统一都报如下错误: 意思是vendor文件不存在,在进入node_modules node-sass目录查看后,确认该文件夹不存在。 尝试了删除package-locl.json和node_modules文件夹重新安装、升级和降级node-sass以及nodejs的版本,问题仍然存在。看来得想其它办法了。 去github上查阅官方的Issues之后发现有不少人遇到过这样的问题,但并没有一个准确的解释是什么原因造成的。个人判断应该是node-sass安装编译过程中自身的问题造成的。 解决方式是安装所有依赖后重新对node-sass插件进行编译就好了:

安装node-sass的正确方法

安装node-sass的时候会报该错误: Error: Can"t find Python executable "python", you can set the PYTHON env variable. 有如下方法: 这里有一篇文章介绍了如何在Windows上找不到Python可执行文件"python": https://catalin.me/how-to-fix-node-js-gyp-err-cant-find-python-executable-python-on-windows/ node-sass正常安装不成功几率占60%左右,但是通过以上两种方法解决问题,就不需要去改变环境变量等。 npm切换源具体请看: npm切换源之nrm 源管理工具

安装node-sass正确姿势

windows下面安装node-sass,确实令人头痛,正确姿势如下: 1、npm或yarm指定淘宝镜像 查看镜像 修改为淘宝镜像 此时,正常情况再安装node-sass都可以成功,如果安装还报错,则进入下面第二步。安装编译windows平台编译环境 2、安装windows平台编译环境(需要在管理员权限下安装) 3、当然也可在项目目录下临时安装指定node-sass为镜像淘宝 以上三步,基本保证node-sass安装成功!

Node node-sass sass-loader 版本对应关系

当前已知 node-sass 与 node 版本对应如下: node-sass 和 sass-loader 的对应关系未找到官方说明,附上常见版本对应关系:

node-sass模块报错安装不上?试试这个方法,亲测有效

node-sass 模块报错、老是安装不上? node-sass这个模块很坑爹,一直报错安装不上,试了各种办法。 用了npm install 、cnpm install 、yarn install 都不行。 后来发现是node-sass模块对node版本有兼容性,版本不适配,就容易报错。 下图是node-sass和 node的对应的版本 如果切换node版本后,仍然报错,尝试重新构建下 node-sass模块 在项目目录下打开cmd: 或者删除原先的node-pass,然后cnpm install node-pass 都可以 看下效果,运行顺利 <figcaption class="cke_widget_editable" contenteditable="true" data-cke-display-name="标题" data-cke-enter-mode="2" data-cke-filter="74" data-cke-widget-editable="caption">标题</figcaption>

webpack中node-sass、sass-loader在Linux中安装问题

我是在深度deepin4.15.0的Linux系统上搭建的环境,node和npm版本如下: 在安装node-sass的过程中确实很容易遇到的坑 1、一开始安装的时候一直报错,看报错也没仔细,在网上找了各种安装node-sass的方法,均失败; 2、后来仔细看了一下是g++命令执行失败导致的,这种情况是Linux操作系统g++版本的问题,属于g++低版本的原因。 报错当时忘记截图了,后来也没找到,所以就不附报错内容了。 3、先更新系统g++版本 a.先更新安装更新gcc(需要在root权限下去更新): sudo apt-get install gcc b.再安装更新g++(需要在root权限下去更新): sudo apt-get install g++ 4、这样g++就安装好了,可以开始安装node-sass了,本以为会一路绿灯,无奈事与愿违; 刚开始安装node-sass是4.5.3的版本安装报错如下: 出现这种报错情况一般是版本的问题导致。 5、安装node-sass的4.12.0版本没有报错就算成功了: npm install node-sass@4.12.0 (可以加 -g 或 -save-dev 进行全局或局部安装) 6、安装sass-loader的7.1.0版本没有报错就算成功的; npm install sass-loader@7.1.0 (可以加 -g 或 -save-dev 进行全局或局部安装) 7、可以到package.json文件中查看包是否存在 总结: 安装各种webpack的依赖经常会出现这种或那样的问题,需要我们仔细分析一下报错才行。虽然网上有各种问题的安装方法,但按照他们的也许可行,也许不可行,但总会耗费自己的大量时间。所以仔细分析自己的报错是什么原因导致的,才能对症下药快速解决问题。

有sass-loader还需要node-sass吗

1. github添加ssh key报错Key is invalid. Ensure you"ve copied the file correctly(2)webpack常用的插件安装命令webpack常用的插件安装命令:1:npm install html-webpack-plugin --save-dev //自动快速的帮我们生成HTML。2:npm install css-loader style-loader --save-dev//样式文件,我们需要两种loader,css-loader 和 style-loader,css-loader会遍历css文件,找到所有的url(...)并且处理。style-loader会把所有的样式插入到你页面的一个style tag中。3:npm install babel-loader css-loader style-loader --save-dev// 安装加载器(babel-loader 进行转码css-loader 对 css 文件进行打包style-loader 将样式添加进 DOM 中)4:npm install sass-loader node-sass --save-dev//css预编译程序,还需要添加node-sass来解析sass文件5:npm install url-loader --save-dev//图片自动转成base64编码的6:npm install jquery moment --save-dev//添加第三方库(jquery和moment)7:npm install babel-preset-es2015 --save-dev//添加ES6的支持8:npm install babel-preset-es2015 babel-preset-react --save-dev//安装转码规则9:npm install webpack-dev-middleware --save-dev//服务器端使用的是express框架,你还可以直接安装express的middleware,webpack配合express10: npm install react --save-dev//安装并引用 React 模块

node-sass和dart-sass区别(以及解决M1芯片/arm芯片无法使用node-sass的问题)

我们先用vue-cli举例 在这时我们可以看到有两个sass解释器一个为node-sass,另一个为dart-sass。 这里建议选择大家使用dart-sass。而不要使用node-sass,下面我会解释一下为什么推荐大家使用dartsass。 单独安装和dart-sass或node-sass的命令先贴在下面 我们选择dart-sass很重要的一点就是 sass官方推荐使用dart-sass 往后的node-sass虽然会继续维护,但是不会再更新新功能。 不过就目前来说,node-sass在编译时依然比dart-sass拥有更好的性能(个人觉得编译时性能对开发不构成影响)。 国内网络对node-sass不太友好。 启动报错症状: 安装报错症状: 解决方案: 从package.json文件中找到node-sass删掉 然后使用命令安装dart-sass 问题原因: 这个问题的原因其实我们从node-sass的github上的版本中可以找到答案 可以看到都macOSX系统仅仅支持x64而M1芯片是arm64并不是x86。 也就是说如果我们的nodejs环境若为使用rosetta转译运行的x86 64位nodejs版本,那么就可以使用这个node-sass并且不会报错。 所以网上有些人说让回退nodejs版本,因为老版本nodejs不兼容arm64,那时候还没有M1芯片啊!QWQ。 老版本nodejs只能用resetta转译运行啊。

node-sass使用python2

可以使用nodesass是一个库,它将Node.js绑定到LibSass【流行样式表预处理器Sass的C版本】,它允许用户以令人难以置信的速度将【.scss】文件本地编译为css,并通过连接中间件自动编译。Sass是一种预处理器脚本语言,可以解释或编译成层叠样式表(CSS)。

关于node,node-sass,sass-loader版本

1、node.js: node 10 2、node-sass: npm install node-sass@4.9.0 --save 3、sass-loader: npm i sass-loader@10.1.0 --save-dev 附一张node和node-sass版本对照图

用sass替代node-sass

不要安装node-sass,直接安装sass即可,前者的安装会出很多问题

.net treeview 控件 的ontreenodeexpanded 是什么东西?什么事件?怎么发生的?

http://apps.hi.baidu.com/share/detail/2101385此处为相关的应用,请仔细了解就行了 你明白的 祝你好运
 1 2 3  下一页  尾页