什么是Node.js?在CentOS8下和Windows10下安装Node.js详细步骤

1. 什么是Node.js

1.1 百度解释

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型。
Node 是一个让 JavaScript 运行在服务端的开发平台,它让 JavaScript 成为与 等服务端语言平起平坐的脚本语言。

1.2 简单理解

之前我们提到服务器端脚本语言,都会说PHP、Python、Perl、Ruby等。然后有一天,有个程序员安耐不住寂寞,想要把Javascript也运行在服务器端,然后Node.js就诞生了。

2. 为什么要用Node.js

Node.js当初火爆的最直接原因是其非阻塞式I/O的工作机制。

阻塞式

比如我们来看一段PHP代码:

<?php
echo "开始执行函数superFunction";
superFuncion("这个程序要运行很久");
echo "函数执行完毕,开始执行第二个函数helloWorld";
helloWorld("我只是想问个好!");
?>

在上面的代码中,superFunction()这个函数如果要运行很久的话,无论后面的helloWorld()函数的任务多么简单,都必须等待superFunction()函数执行完毕后才可以运行。换句话说,superFunction()函数把后面的的任务都阻塞了。

非阻塞式

我们再来看一段Node.js代码:

var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
    if (err) return console.error(err);
    console.log(data.toString());
});
console.log("程序执行结束!");

上面程序中,我们不需要等待文件读取完,这样就可以在读取文件时同时执行接下来的代码,大大提高了程序的性能。

高流量、高并发

由于阻塞是按顺序执行的,而非阻塞是不需要按顺序的。所以Node.js的这种非阻塞机制已经被应用于目前很多高并发、高流量的大型网站的后端上。

3. “Node.js”好还是“PHP们”好

这其实是个伪命题!
在Node.js出现前,不是有“PHP、Python、Perl、Ruby哪个好?”这样的讨论吗?最终有结果吗?—没有。人家四门语言任然都活的好好的!
所以不要纠结于Node.js是否好用,是否有前途的问题。记住以下几点就好了:

  1. 如果你是PHP、Python、Perl、Ruby程序员,可以仍然坚持自己的主线技术,把其用到极致。Node.js可以作为扩充知识面的技术,学习了解下。这样真用到的时候,不至于过于陌生。
  2. Node.js与其它服务器端技术没有谁更好的问题,只有谁更合适的问题。

4. Node.js和npm

4.1 npm

npm是Node Package Manager的简称,是Node.js的包依赖管理工具。类似JAVA的MAVEN和PHP的Composer。
Node项目中如果要引入某个包或者库,都是先通过NPM安装到本地,然后再引用即可。

4.2 全局安装和本地安装

npm 的包安装分为本地安装(local)、全局安装(global)两种,从敲的命令行来看,差别只是有没有-g而已,比如:

npm install express          # 本地安装
npm install express -g       # 全局安装

A. 本地安装

  1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modules 目录。
  2. 可以通过 require() 来引入本地安装的包。

B. 全局安装

  1. 将安装包放在node的安装目录或node指定的目录中。
  2. 可以直接在命令行里使用。

5. Node.js在Windows10下的安装

5.1 下载安装文件

Node.js官网:https://nodejs.org
我下载的版本是:node-v12.15.0-x64.msi
下载链接:https://nodejs.org/dist/v12.15.0/node-v12.15.0-x64.msi

5.2 安装

Windows下的安装和普通软件安装过程一样,非常简单:
file
安装完毕后,进入cmd,用以下命令分别查看下Node.js和NPM的版本号:

node -v
npm -v

5.3 配置

其实截止到上一步,Node.js已经安装完成了,但是为了后期使用的方便,我们最好配置一下npm在安装全局模块时(4.2.B)的路径和缓存cache的路径。因为如果配置,那么在执行例如npm install webpack -g等命令全局安装的时候,默认会将模块安装在C:\Users\用户名\AppData\Roaming路径下的npm和npm_cache中,不方便管理且占用C盘空间,所以这里配置自定义的全局模块安装目录。

  1. 在node.js安装目录下新建两个文件夹node_globalnode_cache
  2. 在cmd命令下执行如下两个命令:
    npm config set prefix "D:\Program Files\nodejs\node_global"
    npm config set cache "D:\Program Files\nodejs\node_cache"
  3. 配置环境变量:
    • “环境变量” -> “系统变量”:新建一个变量名为 “NODE_PATH”, 值为“D:\Program Files\nodejs\node_global”
    • “环境变量” -> “用户变量”:编辑用户变量里的Path,将相应npm的路径(“C:\Users\用户名\AppData\Roaming\npm”)改为:“D:\Program Files\nodejs\node_global”
  4. 测试npm
    安装npm(npm的china版,用的淘宝镜像,国内访问速度快)测试一下,在cmd里面运行:

    npm install cnpm -g

    安装完成后,在刚刚新建的两个文件夹node_globalnode_cache下面,会出现相应的文件。

5.4 运行第一个Node.js服务器

在你自己的工作目录下建一个app.js文件,内容如下:

const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

在cmd中,用node命令运行这个文件:

node app.js

file

这时,打开浏览器在地址栏输入:http://127.0.0.1:3000/看到Hello World就代表成功了!

file

6. Node.js在CentOS8下的安装(方法一)

6.1 下载源代码包至/usr/local/tmp

wget https://nodejs.org/dist/v12.15.0/node-v12.15.0.tar.gz

6.2 解压

tar zxvf node-v12.15.0.tar.gz

6.3 安装前置环境

Node.js的运行需要Python2,如果CentOS8中默认没有安装,需要先安装:

yum install python2 //安装python2

6.4 编译安装

cd node-v12.15.0
./configure --prefix=/usr/local/node/12.15.0
make
make install

7. Node.js在CentOS8下的安装(方法二)

7.1 下载编译好的二进制包至/usr/local/tmp

wget https://nodejs.org/dist/v12.15.0/node-v12.15.0-linux-x64.tar.xz

7.2 解压、移动

tar xvf node-v12.15.0-linux-x64.tar.xz
mv node-v12.15.0-linux-x64 /usr/local/node

7.3 创建node和npm的软连接

ln -s /usr/local/node/bin/node /usr/bin/node
ln -s /usr/local/node/bin/npm /usr/bin/npm

7.4 设置node环境变量

vim /etc/profile

增加以下两行:

export NODE_HOME=/usr/local/node
export PATH=NODE_HOME/bin:$PATH

source使生效:

source /etc/profile

7.5 npm测试

同样以安装npm作为测试:

npm install cnpm -g

/usr/local/node/lib/node_modules目录下出现cnpm目录代表安装成功。

7.6 node测试

在你自己的工作目录下建一个app.js文件,内容如下:

const http = require('http');

const hostname = '0.0.0.0';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

在bash中,用node命令运行这个文件:

node app.js

关掉CentOS8防火墙,或者放行3000端口,你就可以在外网访问了。

划重点

上面代码和在Windows中的代码有些不一样,hostname地址改为了'0.0.0.0'。
在Window中,我们是通过本机访问,而CentOS8安装在虚拟机中,实际上是通过外网访问,所以如果写'127.0.0.1'的话外网会访问不到。

Docker常用命令

1. 帮助命令

1.1 docker version

显示docker版本信息

1.2 docker info

显示docker详细信息

1.3 docker help

docker帮助

2. 镜像命令

2.1 docker images

显示本地的镜像信息
docker images -a:显示所有镜像(包含中间镜像层)
docker images -q:只显示当前镜像的IMAGE ID
docker images -qa:上面两个组合使用
docker images --digests:显示镜像摘要信息
docker images --no-trunc:显示完整的镜像信息

2.2 docker search

在docker hub上面查找镜像信息
比如:docker search tomcat
docker search -s 30 tomcat:显示star数量超过30的tomcat备选
docker search --no-trunc:显示完整镜像摘要信息
docker search --automated:只显示自动构建的镜像信息

2.3 docker pull

从Docker镜像源仓库中,向本地镜像库中拉取(下载)镜像。
docker pull tomcat:下载tomcat到docker中。

2.4 docker rmi

从本地镜像库中删除某个镜像
docker rmi hello-world:删除hello-world镜像
docker rmi -f hello-world:强制删除hello-world镜像

2.5 docker push

将镜像上传到镜像仓库。示例请见:http://www.moonlightgate.com/archives/270

2.6 docker commit

向本地仓库提交镜像

docker commit -m="描述信息" -a="作者信息" 容器ID 目标镜像名:[标签名]

比如:

docker commit -a="Leon" -m="firstcommit" firsttom royotech/secondtom:1.2
//royotech/secondtom:1.2 意思是 命名空间/镜像名:TAG内容

2.7 docker build

根据Dockerfile构建新的镜像,具体方法见:http://www.moonlightgate.com/archives/267

3. 容器命令

3.1 新建并启动容器

docker run [-OPTIONS] IMAGEID [COMMAND][ARG...]

[OPTIONS]
--name="容器新名字":为容器制定一个名称;
-d:后台运行容器,并返回容器ID,即启动守护式容器;
-i:以交互模式运行容器,通常与-t同时使用;
-t:为容器重新分配一个伪输入终端,通常与-i同时使用;
-P:随机映射端口;
-p:指定端口映射,有以下四种格式:
    - ip:hostPort:containerPort
    - ip::containerPort
    - hostPort:containerPort
    - containerPort

例如1:启动交互式容器:

docker run -it centos

file
例如2:启动守护式容器:

docker run -d centos

例如3:在新建容器的时候给新容器命名

docker run --name=firstdocker -it centos

例如4:后台运行tomcat容器

docker run -d -p 8888:8080 tomcat

例如5:已交互式的方式运行tomcat容器,并映射容器内的Tomcat端口8080至本机Docker的8888端口

docker run -it -p 8888:8080 tomcat

这时就可以通过Docker的IP地址:8888端口访问容器内的tomcat了。

注:关于端口映射后无法在主机访问的问题,请参考:http://www.moonlightgate.com/archives/265

3.2 列出当前所有正在运行的容器

dock ps [-OPTIONS]
-a:列出当前所有正在运行的容器+最近运行过的容器。
-l:显示最近创建的容器。
-n:显示最近n个创建的容器。
-q:静默模式,只显示容器编号。
--no-trunc:不截断输出。

如果运行的时候不加参数,

dock ps

则默认显示当前正在运行的容器。

3.3 退出容器

停止容器并退出:

exit

不停止容器退出:

ctrl+按P+再按Q

3.4 启动容器

docker start 容器ID或容器名

3.5 重启容器

docker restart 容器ID或容器名

3.6 停止容器

docker stop 容器ID或容器名

3.7 强制停止容器

docker kill 容器ID或容器名

3.8 删除已经停止的容器

docker rm 容器ID或容器名

或强制删除

docker rm -f 容器ID或容器名

3.9 查看容器日志

docker logs -f -t --tail 容器ID
-f:动态追加最新的日志
-t:加入时间戳
--tail:最后多少条

比如以追加和显示时间的方式、打印某容器的最后3条日志:

docker logs -f -t --tail 3 容器ID或容器名

3.10 查看容器内运行的进程

docker top 容器ID

3.11 查看容器内部的细节

docker inspect 容器ID

3.12 可以在不进入容器的情况下,在容器里执行命令并返回结果

docker exec -t 容器ID 需要执行的命令

如果需要进入容器,则可以使用以下命令:

docker exec -t 容器ID /bin/bash

3.13 进入容器,通过命令进行交互

进入容器,执行命令:

docker attach 容器ID

如果容器正在执行命令,比如tomcat,则此种方式无法进入命令行,还需要使用exec方式才能进入命令行。

3.14 从容器内复制文件到主机上

docker cp 容器ID:路径/文件 主机路径/文件

将Docker镜像推送至Aliyun详细步骤

1. 登陆Aliyun账号。

2. 开通镜像服务。

开通方法请见:http://www.moonlightgate.com/archives/250

3. 创建镜像仓库。

3.1 填写基本信息

file

3.2 创建本地仓库

file

4. 从管理信息里面找到push信息。

file
按照提示运行如下三行代码即可:

$ sudo docker login --username=leon@royotech.com registry.cn-beijing.aliyuncs.com
$ sudo docker tag [ImageId] registry.cn-beijing.aliyuncs.com/royotech/dev_repository:[镜像版本号]
$ sudo docker push registry.cn-beijing.aliyuncs.com/royotech/dev_repository:[镜像版本号]

注意:提示输入密码时要填写第2步开通镜像服务时设定的密码。

CentOS8中Docker容器端口映射后宿主机无法访问的问题

问题描述

  1. IP地址是 http://192.168.81.143 的主机上安装了CentOS8。
  2. CentOS8里面安装了Docker,并使用docker run命令从tomcat镜像创建新容器并映射端口:
    docker run --name=firsttom -it -p 8888:8080 tomcat
  3. 按道理,在主机使用 http://http://192.168.81.143:8888 应该能够访问firsttom容器的tomcat才对,然而却无法访问。

解决过程

  1. 首先想到的就是防火墙问题。于是我在主机上关闭了防火墙:
    systemctl stop firewalld

    别说,这样一来firsttom容器的tomcat还真可以访问了。

  2. 我不想关闭防火墙,所以就想到把8888端口在防火墙里面放行:
    firewall-cmd --zone=public --add-port=8066/tcp --permanent
    firewall-cmd --reload

    按道理这样就应该能访问了,然而防火墙打开后,发现仍然无法访问。

  3. 于是乎就开始了各种搜索,排除了各种不靠谱方案后,终于找到解决方法:
    # 把docker0网卡添加到trusted域
    firewall-cmd --permanent --zone=trusted --change-interface=docker0
    # 重启加载配置
    firewall-cmd --reload

注:这个方法对CentOS7也有效