supervisor

Linux的后台进程运行有好几种方法,例如nohup,screen等,但是一个服务程序要可靠地在后台运行,就需要把它做成daemon,最好还能监控进程状态,在意外结束时能自动重启。
Supervisor就是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,能做开机启动,并监控进程状态,异常退出时能自动重启,它还提供了web管理界面。

安装supervisor
$ sudo apt-get install supervisor
卸载supervisor
$ sudo apt-get remove supervisor
安装完成后,查看其配置文件
$ vi /etc/supervisor/supervisord.conf
查看到自定义配置存放目录为 files=/etc/supervisor/conf.d/*.conf
$ cd /etc/supervisor/conf.d
创建要自启动的服务配置
$ sudo vi service1.conf

配置解释:

[program:service1] #服务名称,在supervisor中可以用这个名字来管理该程序。
command=  #启动程序的命令
directory=/home/user1 #相当于在该目录下执行程序
autostart=true #设置随supervisor的启动而启动
autorestart=true #程序停止之后是否需要重新将其启动
startsecs=10 #重新启动时,等待的时间
startretries=36 #重启程序的次数
redirect_stderr=true #是否将程序错误信息重定向的到文件
stdout_logfile=/home/user1/%(program_name)s_log.txt #将程序输出重定向到该文件
stderr_logfile=/home/user1/%(program_name)s_err.txt #将程序错误信息重定向到该文件
numprocs = 2
numprocs_start = 8850
user = #系统用户名
process_name = 163gs-%(process_num)s

配置好后重启supervisor服务

sudo service supervisor restart

supervisorctl 是命令行管理工具,它的查数查看

supervisorctl help
supervisorctl version
default commands (type help ):
=====================================
add    clear  fg        open  quit    remove  restart   start   stop  update 
avail  exit   maintail  pid   reload  reread  shutdown  status  tail  version

Supervisor2.x版本有一些不同:

配置文件位置 /etc/supervisord.conf
需要在supervisord.conf尾部按示例添加服务配置
服务名称是 supervisord
sudo service supervisord restart

更多配置参考
http://supervisord.org/configuration.html
http://www.jianshu.com/p/65f31f5a4e84
http://www.jianshu.com/p/805977544d7f
http://www.linuxidc.com/Linux/2015-04/116701.htm
http://www.cnblogs.com/haoliansheng/p/6611714.html

nodejs

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
你编码不认真,java会给你丘,而nodejs会给你很多坑,使用WebStorm开发有的会错误会报错,有的则运行通过产生意料之外的行为。

socket.connect参数顺序

创建TCP客户端的坑之connect的参数顺序是先port再host:

var net = require('net');
var HOST = '127.0.0.1';
var PORT = 8888;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
    console.log('CONNECTED TO: ' + HOST + ':' + PORT);
    // 建立连接后立即向服务器发送数据,服务器将收到这些数据 
    client.write('message');
});

pm2

Nodejs开发中修改完代码以后需要重启服务才能看到效果。
forever可以通过对资源变化的检测做到变化后自动重启,并且可以在异常后重启,保证服务一直在线。
pm2 = P (rocess) M (anager)2,是可以用于生产环境的Nodejs的进程管理工具,并且它内置一个负载均衡。它不仅可以保证服务不会中断一直在线,并且提供0秒reload功能,还有其他一系列进程管理、监控功能。并且使用起来非常简单。

pm2的安装和使用

pm2 start app.js
pm2 save
pm2 startup
pm2 reload all
pm2 list
pm2 restart [id]

~# ls -a显示所有包括隐藏的文件,可以看到.pm2文件夹

更多pm2常用的命令用法介绍
http://i5ting.github.io/node-deploy-practice/
http://www.111cn.net/sys/linux/120062.htm
http://www.pangjian.info/2016/12/02/deploy-nodejs-pm2-1/?utm_medium=referral

缓存

nodejs通过文件名缓存加载过的模块,这里是全局缓存,不是页面内缓存。

grpc

安装grpc-tools
$ sudo npm install grpc-tools -g
把proto文件生成js文件
$ /usr/local/lib/node_modules/grpc-tools/bin/protoc --js_out=import_style=commonjs,binary:. --grpc_out=. --plugin=protoc-gen-grpc=/usr/local/lib/node_modules/grpc-tools/bin/grpc_node_plugin *.proto

http参数

参数名是区分大小写的,不存在的参数值是undefined
取get地址?后面的传参
var id=req.query.id;
取rest路径中的参数
var id = req.params.id;
取post时json对象中的参数
id=req.body.id;

express超时重复请求

3种解决办法
1.httpserver设置超时函数
var app = express();
var http = require(‘http’);
var server = http.createServer(app);
server.on(‘timeout’, onTimeout);
function onTimeout(err) {
}
2.加大超时时间
server.timeout=10*60*1000;
3.request或response设置超时处理方法
router.post(‘/xxx’,function(req,res,next){
req.setTimeout(240000,function () {
});
}
http://blog.csdn.net/puncha/article/details/9378197

async

npm install async –save,其中–save参数会在工程package.json中dependencies中增加一条依赖;
async主要实现了三个部分的流程控制功能:
集合: Collections
流程控制: Control Flow
工具类: Utils

Nodejs异步流程控制Async

常用的流程控制:
series 串行,保证顺序不依赖
parallel 并行
waterfall 依赖串行、瀑布流,之间需要传递结果时使用
auto 并行加依赖串行
apply 给函数预置第一个参数,然后返回一个新的函数。

Json Web Token(JWT)

传统的 cookie-session 机制可以保证的接口安全,在没有通过认证的情况下会跳转至登入界面或者调用失败。
在如今 RESTful 化的 API 接口下,cookie-session 已经不能很好发挥其余热保护好你的 API 。
更多的形式下采用的基于 Token 的验证机制,JWT 本质的也是一种 Token,但是其中又有些许不同。
http://blog.csdn.net/liuwenbiao1203/article/details/52351772
https://www.npmjs.com/package/jsonwebtoken
http://www.haomou.net/2014/08/13/2014_web_token/

跨域请求会先发出一个option请求,再发出一个业务上的get或post请求。

socket超时

var socket = new net.Socket(); 创建后
socket.setTimeout(10 * 1000, function () {
if(!idle) {
console.log(‘timeout not idle’);
if (callback) {
callback(false, {message: ‘请求超时’});
callback = null;
}
}else{
console.log(‘timeout idle’);
}
});
不执行connect或write,10秒后会打印timeout idle。
等待9秒后再执行connect,如果connect很久,会在connect开始10秒后打印timeout not idle。
即创建socket和connect或write会开始新一轮超时计时。但不能多次设置settimeout,会引发emit数量警告。
idle为自定义的状态,在connect或wirte时设置idle=false。

安装最新稳定版本
https://segmentfault.com/a/1190000007542620

反向代理

正向代理:代理服务器代理的是客户端,客户端知道服务器,也知道代理服务器。正向代理服务器帮助客户端连接目的服务端。
反向代理:代理服务器代理的是服务端,客户端不知道服务器,只知道代理服务器。反向代理服务器向客户端隐藏了真实的服务端。

TCP服务器

可选的TCP服务器有Mina、Netty、Twisted等,它们都是异步、事件驱动(asynchronous、event-driven)的网络编程框架。
其中MINA和Netty是基于Java语言的,Twisted是Python语言的。语言不是重点,重点的是理念。

  • 传统的BIO(Blocking IO/阻塞IO)进行网络编程时,进行网络IO读写时都会阻塞当前线程,使用BIO实现一个TCP服务器,需要对每个客户端连接开启一个线程,很多线程可能会阻塞住等待读写数据,系统资源消耗大。
  • NIO(Non-Blocking IO/非阻塞IO)或AIO(Asynchronous IO/异步IO)通过IO多路复用技术实现,不需要为每个连接创建一个线程,其底层实现是通过操作系统的一些特性如select、pool、epoll、iocp等。

Mina、Netty、Twisted一起学(一):实现简单的TCP服务器
Netty 4.x 用户指南
Netty in Action 学习
一起学Netty

Reactor 反应器模式

NIO 有一个主要的类Selector,类似一个观察者,只要我们把需要探知的socketchannel告诉Selector,我们接着做别的事情,当有事件发生时,他会通知我们,传回一组SelectionKey,我们读取这些Key,就会获得我们刚刚注册过的socketchannel,然后,我们从这个Channel中读取数据,接着我们可以处理这些数据。

Reactor模式主要是提高系统的吞吐量,在有限的资源下处理更多的事情。

Base 128 Varints

Google Protobuf3

Google Protobuf 官方文档之Language Guide (proto3)  
http://blog.163.com/lnsjc321@126/blog/static/5348428720154325730234/
https://developers.google.com/protocol-buffers/docs/proto3

整合nginx+tomcat

部署tomcat

到http://tomcat.apache.org/下载tomcat,下载后解压数据盘,执行bin/startup.sh来启动tomcat。注意设置startup.sh和catalina.sh的可执行权限。

./startup.sh
./shutdown.sh

shutdown后要等一会完全关闭后再重新启动

配置nginx

在conf/vhosts下新建一个.conf文件

server {
 listen 8888;
 server_name xxx.cn www.xxx.cn;
 index index.html index.htm index.jsp;
 root /xxx/tomcat-7.0.69/webapps/ROOT;
 location ~ .*\.(jsp)?$
 {
 #fastcgi_pass unix:/tmp/php-cgi.sock;
 #fastcgi_pass 127.0.0.1:9000;
 #fastcgi_index index.php;
 #include fastcgi.conf;
 proxy_pass http://127.0.0.1:8889; #主要在这里,设置一个代理
 }
 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
 {
 expires 30d;
 }
 location ~ .*\.(js|css)?$
 {
 expires 1h;
 }
 #伪静态规则
 include /xxx/nginx/conf/rewrite/default.conf;
 access_log /xxx/nginx/access/phpMyAdmin.log;
 }

其中,tomcat目录下的conf/server.xml中的8080端口修改为了8889,并注意在iptables中放开要使用的端口。
要赋予网站文件目录执行权限 简单的可以 chomd 777 -R www目录,否则可能出现页面不正常,在浏览器开发者工具中发现找不到静态资源。

遇到了tomcat异常挂掉的问题

有权限问题
java.util.logging.ErrorManager: 4
java.io.FileNotFoundException: /usr/local/tomcat/logs/catalina.2017-06-11.log (Permission denied)
有内存不够的问题
[root@VM_5_53_centos logs]# service tomcat restart
Stoping Tomcat
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/java/jdk1.8.0_92
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000eb550000, 178978816, 0) failed; error=’Cannot allocate memory’ (errno=12)
#
# There is insufficient memory for the Java Runtime Environment to continue.
# Native memory allocation (mmap) failed to map 178978816 bytes for committing reserved memory.
# An error report file with more information is saved as:
# //hs_err_pid14383.log
waiting for processes to exit

CentOS

df -h 发现,

/dev/mapper/vg_cloud-lv_root 已用100%,可用为0了,这是原因。

查看各目录占用磁盘大小

du -sh /* | sort -nr

占用空间大的目录

/var/spool/clientmqueue
/var/spool/mqueue
/var/log
/var/cache

du -sh *

查看邮件发送队列
mailq 或 sendmail -bp

删除所有队列
postsuper -d ALL

关闭空主机头,防止直接用ip访问,或者被别的域名恶意指向。

在nginx/conf/vhosts下新建一个xxx.conf,内容为
server {
listen 80 default;
return 500;
}

域名恶意指向有些隐患:
由于搜索引擎也会收录你的IP地址的页面,所以同一个页面搜索引擎会重复收录,造成页面的权重不如单个收录高。
假如那域名是不友善的域名,比如曾经指向非法网站,容易引发搜索引擎惩罚,连带IP受到牵连。即使域名没什么问题,但流量也会被劫持到别的域名,从而遭到广告联盟的封杀。

SSH远程登录

ssh root@ip
ssh Alias 快捷配置

vi ~/.ssh/config,输入

# 服务器1
Host 别名
    HostName IP地址
    Port 22
    User 用户名

连接时,使用ssh 别名,然后输入密码即可。

CentOS 6.5安装jdk1.8

centos上的邮件系统sendmail,可再次自主安装,会生成/etc/mail目录,安装方法可参考
http://seofangfa.com/shell/centos-sendmail.html
执行mailq命令后如果发现有很多邮件队列,可以清空/var/spool/mqueue中的文件。

/var/spool/clientmqueue目录下可能存在很多文件,删除方法

# cd /var/spool/clientmqueue
# ls | xargs rm -f

搭建rtmp服务器

安装web环境

安装阿里云web环境一键安装包
安装前需要注意要把数据盘挂载到alidata目录上。

下载nginx-rtmp-moudle

这里下载 ,上传解压到home目录,

重新生成nginx

修改/home/sh-1.4.4/nginx/install_nginx-1.4.4.sh,在–prefix=/alidata/server/nginx \下行增加

--add-module=/home/nginx-rtmp-module-master

然后执行/install_nginx-1.4.4.sh,重新编译生成nginx文件。

停止当前nginx,用上一步生成的文件替换。

/alidata/server/nginx-1.4.4/sbin/nginx

配置rtmp应用服务

在nginx.conf中和http块同级别增加rtmp块,如下:

rtmp_auto_push on;
rtmp {
server {
listen 1935;
chunk_size 4000;

application rtmp1 {
live on;
#allow play all;
#play /home;
}
application hls1 {
live on;
hls on;
hls_path /tmp/hls;
}
}
}

针对hls,在http里面增加一个location配置

location /hls {  
            types {  
                application/vnd.apple.mpegurl m3u8;  
                video/mp2t ts;  
            }  
            root /tmp;  
            add_header Cache-Control no-cache;  
}

重新启动nginx

安装ffmpeg

svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg
./configure --disable-yasm
make
sudo chmod 777 /usr/local/
make install 

测试推流

 ffmpeg -re -i /home/mm.MOV -vcodec copy -acodec copy -f flv rtmp://****:1935/myapp/test
 ffmpeg -re -i /home/test.264 -vcodec copy -f flv rtmp://****:1935/myapp/test
 ffmpeg -re -i /home/my.flv -f flv rtmp://****:1935/myapp/test

 

查看文档和播放示例

nginx-rtmp-module-master下的doc、test分别提供了文档说明向导和示例,示例使用了jwplayer flash播放rtmp。
再配置一个http vhost,root指向

root /home/nginx-rtmp-module-master/test/www;

修改指向目录中的index.html文件中的file后的内容为自己发布视频的地址,然后可以访问 http://****/index.html 播放视频。

nginx增加支持https

生成https证书

 
 $ cd /alidata/server/nginx/conf
 $ openssl genrsa -des3 -out wwkssl.key 1024
 $ openssl req -new -key wwkssl.key -out wwkssl.csr
 $ cp wwkssl.key wwkssl.key.org
 $ openssl rsa -in wwkssl.key.org -out wwkssl.key
 $ openssl x509 -req -days 3650 -in wwkssl.csr -signkey wwkssl.key -out wwkssl.crt

增加监听443端口

修改在vhosts中原来配置好的.conf文件

 server {
 listen 80;
 listen 443 ssl;
 server_name brogrammer.cn www.brogrammer.cn;
 index index.html index.htm index.php;
 root /alidata/www/brogrammer;

 ssl_certificate /alidata/server/nginx/conf/wwkssl.crt;
 ssl_certificate_key /alidata/server/nginx/conf/wwkssl.key;

location ~ .*\.(php|php5)?$
 {
 #fastcgi_pass unix:/tmp/php-cgi.sock;
 fastcgi_pass 127.0.0.1:9000;
 fastcgi_index index.php;
 include fastcgi.conf;
 }
 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
 {
 expires 30d;
 }
 location ~ .*\.(js|css)?$
 {
 expires 1h;
 }
 #伪静态规则
 include /alidata/server/nginx/conf/rewrite/brogrammer.htaccess;
 access_log /alidata/log/nginx/access/reading.log;
 }

重启nginx

 $ cd /alidata/server/nginx/sbin
 $ ./nginx -s reload

修改iptables规则

将https的443端口加入到iptables防火墙中允许访问

 $ iptables -I INPUT -p tcp --dport 443 -j ACCEPT
 $ service iptables save

前端身份验证

前端身份验证功能依靠后端,根据不同形式的前端,有不同的策略:
单页应用可以内部控制授权;
多页应用可以通过http_auth_request模块验证授权;
http://www.cnblogs.com/hao-dotnet/p/3477442.html

nginx命令

./nginx -s reload
nginx -v
nginx -V 包括查看安装的模块

部署LNMP

试用了一个月阿里云服务器,服务真不错,安装布署教程也很全,但最终我也没有积累够耐心和时间做域名备案。换一个香港的vps吧,付款后立即给了ip和密码,但没有任何预装布署和指导,没有布署经验,现搜索网上的资源又太繁杂,何不试试阿里云那套安装流程呢?

参考 阿里云服务器linux操作指南

挂载数据盘

  • 登录服务器,可以使用SecureCRT
  • 检查磁盘分区,fdisk -l
  • 对磁盘分区,用fdisk命令创建主分区
  • 格式化磁盘,mkfs .ext3 /dev/xvdb1
  • 挂载数据盘

注意,根据后面安装包的需要,挂载数据盘需要挂载到根目录下的alidata,挂载命令如下:

mount /dev/xvdb1 /alidata/
df -hp

下载安装包

下载安装包 点击这里 ,并上传到服务器的/home目录下,解压。

安装

……

数组

修改了vhosts,rewrite目录中的文件后,要重启nginx才生效。

./nginx -s reload