分类 服务器架构 下的文章

阿里云CentOS6.5(nginx+PHP-fpm)及RDS初级使用指南和简单安全设置

新上了台阿里云云服务器ECS和云数据库RDS(美国硅谷节点),从零开始安全设置,环境安装,记录一下

首先开启云盾

选择的是CentOS6.5系统,另外有数据盘。

1.挂载数据盘

参考Linux 系统挂载数据盘

查看数据盘

df –h
fdisk -l

对数据盘进行分区

fdisk -S 56 /dev/xvdb

查看新的分区

fdisk -l

格式化新分区

mkfs.ext3 /dev/xvdb1

添加分区信息

echo '/dev/xvdb1  /mnt ext3    defaults    0  0' >> /etc/fstab

挂载新分区

mount -a
df -h

2.吸取以往经验,参考如何通过防火墙策略限制对外扫描行为

wget http://oss.aliyuncs.com/aliyunecs/linux_drop_port.sh
sh linux_drop_port.sh

Step 1.No lock file,begin to create lock file and continue.

Step 2.Begen to check the OS issue.

This OS is centos6.

Step 3.Begen to config firewall.

Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination 

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination 

Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination 
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           multiport dports 21,22,23,25,53,80,135,139,443,445
    0     0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           multiport dports 1433,1314,1521,2222,3306,3433,3389,4899,8080,18186
    0     0 DROP       udp  --  *      *       0.0.0.0/0            0.0.0.0/0   
Config firewall success,this script now exit!

通过阿里云提供的脚本,封禁对外发包的行为,以防主机出现恶意发包的情况被停封。

2015.06.02 修改:该脚本适用于linux系统,主要用于在云服务器被肉鸡后禁止对外攻击,留出时间进行分析和修复。该脚本将禁止对外发送UDP数据包和禁止对TCP的22、80、443、1314、3306、3433、3389、8080端口发送数据包。
并不需要一开始运行,否则服务器会访问不了外部网络。

3.禁止ping

参考ECS Linux禁止ping以及开启ping的方法

echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_all

4.关闭 SELinux

参考Linux 下为何要关闭 SELinux?

vim /etc/selinux/config

修改
SELINUX=disabled
发现阿里云默认已经关闭

5.注释掉系统不需要的用户和用户组

注意:不建议直接删除,当你需要某个用户时,自己重新添加会很麻烦。
cp /etc/passwd /etc/passwdbak #修改之前先备份
vi /etc/passwd #编辑用户,在前面加上#注释掉此行
#adm:x:3:4:adm:/var/adm:/sbin/nologin
#lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
#sync:x:5:0:sync:/sbin:/bin/sync
#shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
#halt:x:7:0:halt:/sbin:/sbin/halt
#uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
#operator:x:11:0:operator:/root:/sbin/nologin
#games:x:12:100:games:/usr/games:/sbin/nologin
#gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
#ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin #注释掉ftp匿名账号
cp /etc/group /etc/groupbak #修改之前先备份
vi /etc/group #编辑用户组,在前面加上#注释掉此行
#adm:x:4:root,adm,daemon
#lp:x:7:daemon,lp
#uucp:x:14:uucp
#games:x:20:
#dip:x:40:

6.配置防火墙

查看已有的IPTABLES设置

iptables -L -n

没设置的情况下为空,如下显示:
Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)

在此基础之上,
我们需要

#允许来自于lo接口的数据包,如果没有此规则,你将不能通过127.0.0.1访问本地服务,例如ping 127.0.0.1
/sbin/iptables -A INPUT -i lo -j ACCEPT 
#开放TCP协议22端口,以便能ssh,如果你是在有固定ip的场所,可以使用 -s 来限定客户端的ip
/sbin/iptables -A INPUT -p tcp --dport 22 -j ACCEPT
#ssh端口2222(为后面修改ssh端口做准备)
/sbin/iptables -A INPUT -p tcp --dport 2222 -j ACCEPT
#web服务端口80
/sbin/iptables -A INPUT -p tcp --dport 80 -j ACCEPT
#允许所有对外请求的返回包
#本机对外请求相当于OUTPUT,对于返回数据包必须接收啊,这相当于INPUT了
#这条规则参看:[http://www.netingcn.com/iptables-localhost-not-access-internet.html][5]
/sbin/iptables -A INPUT -m state --state ESTABLISHED -j ACCEPT
#屏蔽上述规则以为的所有请求,不可缺少,否则防火墙没有任何过滤的功能
/sbin/iptables -P INPUT DROP
#至此防火墙就算配置好,但是这是临时的,当重启iptables或重启机器,上述配置就会被清空,要想永久生效,还需要如下操作
service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

OUTPUT暂时设置为ACCEPT,可访问所有外部网络,可根据情况,再详细设置。
可参考http://johnwang.blog.51cto.com/474770/126388/

7.修改ssh端口

vi /etc/ssh/sshd_config

加上一行我们自己定义的端口,如2222,如下:
Port 22 //保留默认的22端口,去掉前面的#
Port 2222 //我们新加的
然后保存退出
执行

/etc/init.d/sshd restart //重启sshd服务 

然后使用ssh工具连接2222端口,来测试是否成功。
成功后再次编辑sshd_config和iptables,删除22端口/重启即可。

8.安装nginx

查看nginx相关信息

yum list | grep nginx
collectd-nginx.x86_64                        4.10.9-1.el6                   epel
munin-nginx.noarch                           2.0.25-2.el6                   epel
nginx.x86_64                                 1.0.15-11.el6                  epel
nginx-filesystem.noarch                      1.0.15-11.el6                  epel
owncloud-nginx.noarch                        7.0.5-2.el6                    epel
yum info nginx
Loaded plugins: security
Available Packages
Name        : nginx
Arch        : x86_64
Version     : 1.0.15
Release     : 11.el6
Size        : 404 k
Repo        : epel
Summary     : A high performance web server and reverse proxy server
URL         : http://nginx.org/
License     : BSD
Description : Nginx is a web server and a reverse proxy server for HTTP, SMTP, POP3 and
            : IMAP protocols, with a strong focus on high concurrency, performance and
            : low memory usage.

发现版本很低,于是追加 nginx 的 yum 仓库,创建一个文件 /etc/yum.repos.d/nginx.repo,并将下面的内容复制进去

[nginx]  
name=nginx repo  
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/  
gpgcheck=0  
enabled=1

编辑并保存/etc/yum.repos.d/nginx.repo文件后,在命令行下执行

yum list | grep nginx
collectd-nginx.x86_64                      4.10.9-1.el6                 epel
munin-nginx.noarch                         2.0.25-2.el6                 epel
nginx.x86_64                               1.6.3-1.el6.ngx              nginx
nginx-debug.x86_64                         1.6.3-1.el6.ngx              nginx
nginx-debuginfo.x86_64                     1.6.3-1.el6.ngx              nginx
nginx-filesystem.noarch                    1.0.15-11.el6                epel
nginx-nr-agent.noarch                      2.0.0-7.el6.ngx              nginx
owncloud-nginx.noarch                      7.0.5-2.el6                  epel

发现最新的稳定版1.6.3,于是直接执行

yum install nginx -y 

安装完成,下面直接就可以启动Nginx了:

/etc/init.d/nginx start
Starting nginx:                                            [  OK  ]

现在Nginx已经启动了,直接访问服务器就能看到Nginx欢迎页面了的。
Nginx的命令以及配置文件位置:

/etc/init.d/nginx start # 启动Nginx服务
/etc/init.d/nginx stop # 停止Nginx服务
/etc/nginx/nginx.conf # Nginx配置文件位置

9.安装php与php-fpm

参考实战Nginx与PHP(FastCGI)的安装、配置与优化
下载php最新稳定版本5.6.8

cd /usr/local/src/
wget http://php.net/distributions/php-5.6.8.tar.gz
cd php-5.6.8
./configure --prefix=/usr/local/php5 --with-config-file-path=/usr/local/php5/etc --enable-fpm --disable-ipv6 --enable-pdo --with-pdo-mysql --with-openssl --with-mcrypt --with-mhash --enable-json --enable-mbstring --with-gd --with-openssl-dir --with-jpeg-dir --with-png-dir --with-zlib-dir --with-freetype-dir --enable-gd-native-ttf --enable-gd-jis-conv --enable-zip

根据给出的错误提示,需要安装如下软件包:

yum install -y libxml2 libxml2-devel openssl-devel libjpeg libjpeg-devel libpng libpng-devel freetype freetype-devel libmcrypt libmcrypt-devel mcrypt mhash

当然也可以在configure之前,预先安装好上面这些依赖的软件包。
然后安装

make
make install

安装完成后,设置PHP-fpm
cp /usr/local/php-5.6.0/etc/php-fpm.conf.default /usr/local/php-5.6.0/etc/php-fpm.conf
vi php-fpm.conf
// 找到如下几行,确保如下几行前没有";"
pid = run/php-fpm.pid
error_log = log/php-fpm.log
log_level = notice
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500

pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态)。在更老一些的版本中,dynamic被称作apache-like。这个要注意看配置文件的说明。

下面4个参数的意思分别为:
pm.max_children:静态方式下开启的php-fpm进程数量。
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式下的最大php-fpm进程数量。

如果dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。
系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。

对于我们的服务器,选择哪种执行方式比较好呢?请移步PHP-FPM 配置优化
大体来说就是内存大的服务器(比如8G以上)使用static(静态)方式,内存小的使用dynamic(动态)方式。

利用php自带的php-fpm管理工具,可以很方便的start,stop,restart
把管理工具从源码包里放到php5/sbin文件夹里,方便使用

cp /usr/local/src/php-5.6.8/sapi/fpm/init.d.php-fpm /usr/local/php5/sbin/
cd /usr/local/php5/sbin/
chmod 755 init.d.php-fpm
./init.d.php-fpm start
Starting php-fpm  done

php-fpm安装完成

10.配置Nginx来支持PHP

cd /etc/nginx/
vi nginx.conf
#打开gzip
gzip    on;

配置vhost,假设域名为www.a.com

cd /etc/nginx/conf.d/
vi www.a.com.conf
#内容如下
server {
        listen 80;
        server_name www.a.com a.com;
        #让不带www的域名跳转到带www的域名
        if($host != 'www.a.com') {
                rewrite ^(.*)$ http://www.a.com/$1 permanent;
        }
        location / {
                #开启ssi支持shtml
                ssi on;
                ssi_silent_errors on;
                ssi_types text/shtml;
                index index.shtml index.php index.htm index.html;
                root /mnt/www/www.a.com;
                #框架路由设置
                if ( !-e $request_filename ) {
                        rewrite ^(.*)$ /index.php?url=$1 last;
                }
        }

        location ~\.php$ {
                root /mnt/www/www.a.com;
                fastcgi_pass 127.0.0.1:9000;
                fastcgi_index index.php;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include fastcgi_params;
        }

        location ~\.(jpg|jpeg|png|js|css) {
                root /mnt/www/www.a.com;
                expires 30d;
        }

}

测试一下 配置文件是否有错误

/etc/init.d/nginx configtest
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

在数据盘mnt上,新建文件夹/mnt/www/www.a.com,并新建info.php测试文件,内容为

<?php
phpinfo();
?>

修改本机host,将www.a.com及a.com都指向服务器IP,访问www.a.com/info.php,成功得到phpinfo信息,
访问a.com/info.php自动跳转到www.a.com/info.php
至此nginx+php-fpm设置完成。

**2015.06.24 安装完成后发现没有mysql扩展,php.ini文件也没有载入
phpinfo中
Loaded Configuration File (none)
解决办法 进入php源文件包
cd /usr/local/src/php-5.6.8
cp php.ini-production /usr/local/php5/etc/php.ini
然后重启php-fpm,可以在phpinfo里看到
Loaded Configuration File /usr/local/php5/etc/php.ini
yum install mysql-devel
由于之前没有安装mysql服务,也没有安装php的mysql扩展,用是PDO方式,为适应老版本的joomla程序,再添加mysql.so扩展
方法如下:
1、进入php源代码目录:
cd /usr/local/src/php-5.6.8/ext
cd mysql
yum install autoconf
调用已经编译好的php可执行程序phpize,phpize是用来扩展php扩展模块的,通过phpize可以建立php的外挂模块
phpize的规则:去哪个目录下运行phpize文件,那么就会在该目录下生成一个configure文件。

/usr/local/php5/bin/phpize
./configure --with-php-config=/usr/local/php5/bin/php-config --with-mysql --with-zlib-dir=/usr/local/php5/lib/php/extensions/no-debug-non-zts-20131226/
with-php-config 找到php5/bin目录下的php-config文件
with-mysql mysql安装的目录留空
/usr/local/php5/lib/php/extensions/no-debug-non-zts-20131226/ 为php扩展的动态库存放目录
make && make install
完成后,可以看到no-debug-non-zts-20131226目录下生成了mysql.so文件
修改php.ini,去掉;extension=php_mysql.so前面的分号。将php_mysql.so改成我们生成的mysql.so。
重启php-fpm后可以从phpinfo看到mysql扩展已经生效。**

11.连接云数据库RDS

首先进入RDS管理控制台,设置白名单只允许我们自己的ECS内网IP访问
然后新建账号及对应的数据库
然后登录数据库iDB Cloud,新建对应数据表

ECS上新建一个组及账号(如group_a,user_a),根目录为/mnt/www/www.a.com,通过sftp方式上传文件至服务器

groupadd group_a
useradd user_a -d /mnt/www/www.a.com -g group_a
chown user_a:group_a /mnt/www/www.a.com

RDS和普通MySQL连接方式一样,只要把连接地址改成RDS的数据实例链接名(如如example201108.mysql.alibabalabs.com)
具体方式 参考如何连接RDS数据库

alias rewrite 后出现404,应设置RewriteBase参数

Alias /mytest /www/mytest
<Directory /www/mytest>
AllowOverride all
Order allow,deny
Allow from all
</Directory>

为保证正常访问
需要在.htaccees文件里加入

RewriteBase /mytest

如下

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [L]
RewriteBase /mytest

从helloworld开始构建一个node.js+socket.io+express4实时应用示例

上一篇node.js环境配置

查看一下node.js和npm(模块管理)版本号

node -v
v0.12.0
npm -v
2.5.1

先运行个小例子

进入示例根目录,如/data/www/hello
新建helloworld.js文件,内容为:

console.log("Hello World");

通过 node命令来执行

node helloworld.js

程序执行后,正常的话,就会在终端输出 Hello World。

Hello World

测试成功后,可删除该文件

接下来

构建基础的 HTTP 服务器

引用教程http://www.w3cschool.cc/nodejs/nodejs-http-server.html

如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5模块和php-cgi。 从这个角度看,整个"接收 HTTP 请求并提供 Web 页面"的需求根本不需 要 PHP 来处理。 不过对Node.js 来说,概念完全不一样了。使用 Node.js 时,我们不仅仅 在实现一个应用,同时还实现了整个 HTTP服务器。事实上,我们的 Web 应用以及对应的 Web 服务器基本上是一样的。

创建server.js文件,内容如下

var http = require('http');
http.createServer(function (request, response) {
  response.writeHead(200, {'Content-Type': 'text/plain'});
  response.end('Hello World\n');
}).listen(8888);
console.log('Server running at http://127.0.0.1:8888/');

以上代码我们完成了一个可以工作的 HTTP 服务器。
使用 node命令 执行以上的代码:

node server.js
Server running at http://127.0.0.1:8888/

打开浏览器访问 http://127.0.0.1:8888/,你会看到一个写着 "Hello World"的网页,如不是本地环境127.0.0.1改为你的服务器IP

分析Node.js的HTTP服务器:第一行请求(require)Node.js自带的http模块,并且把它赋值给http变量。 接下来我们调用 http 模块提供的函数: createServer 。这个函数会返回 一个对象,这个对象有一个叫做 listen的方法,这个方法有一个数值参数, 指定这个 HTTP 服务器监听的端口号。

socket.io安装

npm install socket.io

用npm ls列出安装的package,看看socket.io是不是安装成功了
由于没有把socket.io加入package.json里的dependencies,npm ls报npm ERR! extraneous 的错误
将socket.io加入package.json的dependencies,如下:

"dependencies": {
    "body-parser": "~1.12.0",
    "cookie-parser": "~1.3.4",
    "debug": "~2.1.1",
    "express": "~4.12.2",
    "jade": "~1.9.2",
    "morgan": "~1.5.1",
    "serve-favicon": "~2.2.0",
    "socket.io": "~1.3.5"
  }

socket.io初体验

来自http://www.open-open.com/lib/view/open1337216216557.html

新建服务端server.js

var fs = require('fs')
    , http = require('http')
    , socketio = require('socket.io');
  
var server = http.createServer(function(req, res) {
    res.writeHead(200, { 'Content-type': 'text/html'});
    res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
    console.log('Listening at: http://localhost:8080');
});
  
socketio.listen(server).on('connection', function (socket) {
    socket.on('message', function (msg) {
        console.log('Message Received: ', msg);
        socket.broadcast.emit('message', msg);
    });
});

上述代码是一个超级简单的聊天服务器的实现,该服务器发送 index.html 并侦听所有 WebSockets 请求,通过message事件接收消息,收到格式如下的信息

{"name":"message","args":["hi"]}

则通过socket.broadcast.emit将此信息广播到所有socket端,如此实现了最简单的聊天室功能。
index.html则是通过send方法提交消息,也是通过message事件接收消息,代码如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        $(function(){
            var iosocket = io.connect('http://localhost:8080/');
  
            iosocket.on('connect', function () {
                $('#incomingChatMessages').append($('<li>Connected</li>'));
  
                iosocket.on('message', function(message) {
                    $('#incomingChatMessages').append($('<li></li>').text(message));
                });
                iosocket.on('disconnect', function() {
                    $('#incomingChatMessages').append('<li>Disconnected</li>');
                });
            });
  
            $('#outgoingChatMessage').keypress(function(event) {
                if(event.which == 13) {
                    event.preventDefault();
                    iosocket.send($('#outgoingChatMessage').val());
                    $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                    $('#outgoingChatMessage').val('');
                }
            });

            $('#submit_btn').click(function() {
                iosocket.send($('#outgoingChatMessage').val());
                $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                $('#outgoingChatMessage').val('');
            });
            
        });
    </script>
</head>
<body>
Incoming Chat:&nbsp;<ul id="incomingChatMessages"></ul>
<br />
<input type="text" id="outgoingChatMessage"><input type="button" name="submit_btn" id="submit_btn" value="发言">
</body>
</html>

运行server.js文件

node server.js

接下来打开两个浏览器,必须得是支持 WebSockets 的浏览器,例如 Chrome 或者 Safari,访问 http://localhost:8080/ 地址开始互聊。


Express 是一个简洁、灵活的 node.js Web 应用开发框架, 它提供一系列强大的特性,帮助你创建各种 Web 和移动设备应用。
下面我们通过Express4.x运行上面的例子。

Express4.x 安装

npm install -g express

如果是express 4.0之前版本,那么执行“express -V”就可以得到版本号了,可express 4.0之后还需要再安装express-generator包,如果没有安装还执行“express -V”命令会报错。

express4.0之后把创建一个APP的功能分离出来为express-generator,没它你创建不了应用程序

npm install -g express-generator

安装方法参考http://www.cnblogs.com/dacheng/p/nodejs.html

express -v
4.12.1

进入/data/www

express juneng
cd juneng

juneng是安装的文件夹名

npm install
npm start

这里需要注意 express 4.x 无法以 node app.js 为启动方式,而是用指令 npm start 作为启动
访问 http://localhost:3000/ 出现熟悉的Welcome to Express,证明安装成功。

修改bin/www文件

/**
 * Create HTTP server.
 */

//var server = http.createServer(app);

/**
 * Listen on provided port, on all network interfaces.
 */
//server.listen(port);
//server.on('error', onError);
//server.on('listening', onListening);

修改后:

var server = app.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + server.address().port);
});

require('../juneng_server').listen(server);

然后在根目录编写juneng_server.js文件:

var io = require('socket.io')();

io.on('connection', function (_socket) {
    console.log(_socket.id + ': connection');
    _socket.on('message', function (msg) {
        console.log('Message Received: ', msg);
        _socket.broadcast.emit('message', msg);
    });
});

exports.listen = function (_server) {
    return io.listen(_server);
};

修改模板文件,express使用的是jade模板引擎,找到view/layout.jade和view/index.jade,修改成如下
layout.jade

doctype html
html
    head
        title= title
        meta(http-equiv="Content-Type", content="text/html; charset=utf-8")
        link(rel='stylesheet', href='/stylesheets/style.css')
        script(src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js")
        script(src='/socket.io/socket.io.js')
        script.
            $(function(){
                var iosocket = io.connect('http://localhost:3000/');
  
                iosocket.on('connect', function () {
                    $('#incomingChatMessages').append($('<li>Connected</li>'));

                    iosocket.on('message', function(message) {
                        $('#incomingChatMessages').append($('<li></li>').text(message));
                    });
                    iosocket.on('disconnect', function() {
                        $('#incomingChatMessages').append('<li>Disconnected</li>');
                    });
                });
  
                $('#outgoingChatMessage').keypress(function(event) {
                    if(event.which == 13) {
                        event.preventDefault();
                        iosocket.send($('#outgoingChatMessage').val());
                        $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                        $('#outgoingChatMessage').val('');
                    }
                });

                $('#submit_btn').click(function() {
                    iosocket.send($('#outgoingChatMessage').val());
                    $('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
                    $('#outgoingChatMessage').val('');
                });
            
            });
    body
        block content

index.jade

extends layout

block content
    p Incoming Chat:&nbsp;
    ul#incomingChatMessages
    br
    input(
        type='text'
        name='outgoingChatMessage'
        id='outgoingChatMessage')
    input(
        type='button'
        name='submit_btn'
        id='submit_btn'
        value="发言")

注意,jade模板里的缩进可以用2个空格,也可以用tab,但是不能混用,会报错,我用的tab键

Express4结合socket.io部分,参考https://cnodejs.org/topic/53c385a1400ca4581bc0f0e4

CentOS一些操作命令及node.js安装

查看centos内核的版本

uname -a
uname -r

查看linux版本

cat /etc/issue

查看系统是64位还是32位

getconf LONG_BIT

安装node.js

因为node.js需要Python2.6以上

Note: Python 2.6 or 2.7 is required to build from source tarballs.

查看Python版本

python -V

安装依赖

yum -y install gcc make gcc-c++ openssl-devel wget

下载node.js源码及安装

wget http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
tar -zxf node-v0.12.0.tar.gz
cd node-v0.12.0
./configure && make && make install