从零开始部署小程序服务器(腾讯云)
话说目前云已经很便宜了,腾讯有一个月的试用期,不过阿里云也有,而且对于学生认证的用户 9.9元一个月的最低配置,这让 Lefe 才有可能尝试配置一个线上的服务器。从一个小白开始,感觉都是新的东西,有时候碰到问题,很难,无从下手,不过通过网上的各种资料最终都解决了,下面主要讲一讲过程,这些知识对于服务器端的同学来说,应该很简单,但我只想记录下这一路走来所经历的!
服务器是什么
服务器是什么?啥,你竟然不知道服务器是啥,你每天都和服务器打交道。以 lefe 自己的理解,服务器和本地一台笔记本差不多,所以配置服务器也就是和配置本地的环境差不多,唯一不同的是各种操作,都需要终端命令来替代我们的图形化界面,比如建立文件夹,下载,解压等等。
购买腾讯云
到腾讯云官网上购买【云服务器CVM】,购买后分派两个ip地址,公网和内网的。我们做一些配置基本都是基于外网ip。Lefe 购买的是 Ubuntu
外网IP,就是公网IP,可以给外面人用的,例如做网站,或给其它人下载等。
肉网IP,就是局网IP,如果你有几台以上的云主机,可以局网传输数据,局网传输数据不占用外部带宽限制,传输大文件速度会快很多很多。
配置服务器
一、如何登录到服务器:
我已经有ip地址了,可是我咋么才能登录到服务器上,来配置我们的环境呢?这里一般官方文档到会有写,不过一般写的比较粗略,对于我这个小白用户来说,看不太明白。这里主要介绍一种登录方式:
ssh的方式登录,这种方式相信很多同学都见过,比如 git。它需要把一台PC上生成的公钥传到服务器后台(腾讯云后台管理中心),这样服务器就可以信任当前的PC了。
- PC端生成公钥:
打开终端输入:ssh-keygen , 一路回车,这时会生成一个公钥和一个私钥; - 终端输入:cat .ssh/id_rsa.pub,复制公钥,上传到腾讯云后台管理中心;
- 终端输入:ssh ubuntu@118.89.23.181,ubuntu 这个会管理员账号,不同系统可能会不同,比如有的是 root,阿里云好像都是 root,118.89.23.181 这个是公网的 ip 地址。
登录成功后,你就可以随心所欲了,不要怕搞坏哦,终端显示如下:
很简单吧,这样就可以登录到服务器上了。这里 lefe 推荐终端软件 iTerm
注意:下面所讲到的都是基于登录到服务器后的操作。
二、安装 Node.js
主人公该上场了,有个 Node 我们才能开启我们基本的 Http 服务。
终端输入:
curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get install nodejs
报错:
The program 'node' is currently not installed. You can install it by typing:
sudo apt install nodejs-legacy
执行下面语句:
sudo apt install nodejs-legacy
终端输入:
node -v ,查看你所安装 Node的版本号;
嗯,这样 Node 就安装好了,还记得你第一安装 Node 吗?
三、开启 Node 服务
这时候需要把 Lefe 写好的 Node 服务克隆到服务器上,想想当你刚接触 git 的时候,你是如何把 github 上的代码克隆到自己电脑上的,如果是别人帮你弄的,lefe 建议读者自行实践一下。
- 生成一个公钥,和登录时的生成方式一样,只不过这里是在服务器上生成的
- 把生成好的公钥上传到 git 服务器上
- 执行 git clone https://github.com/iMetalk/TCZNodeServer
当然 lefe 这时候克隆的是一个自己写好的 Node;
克隆后在服务器上的目录为:
/home/ubuntu/nodeserver/WJCar_node
- 执行 node app.js,这样服务就起来了。
Lefe:哎,不对哦,我有数据库啊,好吧,还需要安装数据库,不然我的数据从哪来?搞个假数据,你这也能想的出来。
四、安装 mongodb
Lefe:咋么安装呢?呵呵,都是 linux 系统,记得本地以前配置过,哎对了,以前还写过一片博客,翻了翻以前的博客,哎真有啊,开心坏了。不一会就安装好了。可以参考这篇文章
Mongodb安装。
关了几次终端,出现了一个问题:
ubuntu@VM-68-186-ubuntu:/usr/local/mongodb/bin$ ./mongod --dbpath=/usr/local/mongodb/data/db/
2017-05-14T11:09:50.823+0800 I CONTROL [initandlisten] MongoDB starting : pid=21537 port=27017 dbpath=/usr/local/mongodb/data/db/ 64-bit host=VM-68-186-ubuntu
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] db version v3.2.9
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] git version: 22ec9e93b40c85fc7cae7d56e7d6a02fd811088c
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.2g 1 Mar 2016
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] allocator: tcmalloc
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] modules: none
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] build environment:
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] distmod: ubuntu1404
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] distarch: x86_64
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] target_arch: x86_64
2017-05-14T11:09:50.826+0800 I CONTROL [initandlisten] options: { storage: { dbPath: "/usr/local/mongodb/data/db/" } }
2017-05-14T11:09:50.880+0800 E NETWORK [initandlisten] listen(): bind() failed errno:98 Address already in use for socket: 0.0.0.0:27017
2017-05-14T11:09:50.882+0800 E NETWORK [initandlisten] addr already in use
2017-05-14T11:09:50.882+0800 E STORAGE [initandlisten] Failed to set up sockets during startup.
2017-05-14T11:09:50.882+0800 I CONTROL [initandlisten] dbexit: rc: 48
这下坏了,纠结啊!!!看了看错误,好像是某个端口已经被占用了,98 Address already in use for socket: 0.0.0.0:27017
,别怕 Google一下吧,果然很多人遇到了同样的问题,绕了一圈,最终得以解决。这种情况一般是不正常的退出 Mongodb 导致的。简单粗暴:sudo killall mongod
,直接杀掉。
哈哈,大功告成了,正高兴这呢。哎不对呀,如果我把终端关闭了,那我 Node 服务就死了,那还要服务器干吗呢?突然脑海中浮现出一个 PM2(你咋这么聪明呢,我咋只知道 PM2.5),这个家伙经常听后台的同学说,我一开始还以为是 pm2.5呢?抱着试一试的心态,Google 了一下,太神奇了,原来 PM2 就是解决这个问题的。
五、PM2 安装
看了看 官方文档 很快就安装好了,原来它可以使用 NPM 安装。
试一试吧:就是把 node app.js 换成 pm2 start app.js
原来看到后端同学屏幕上显示的原来就是这个东西。呀!不对呀,那我 mongodb 数据库关闭终端后也就会被挂起了,是不也可以使用 PM2 呢?最终发现不可以,那咋么办呢?估计和这个原理差不多,也开启一个守护进程。果不其然,启动 mongodb 还有其他的一种方式:
sudo mongod --fork --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/logs/mongodb2.log --logappend
Lefe 开心的登录微信小程序后台,哎,不对,微信小程序必须使用域名而不是ip地址,好吧,只好妥协了,申请一个域名吧。
六、申请域名
都这么贵,.com, .cn,那就找一个最便宜的吧,哎有一个,lefe.wang,这个不错,天意呀,lefe 我的笔名,wang 我的姓,果断就选它了,登录腾讯云后台解析了下,很快的我的接口可以使用域名访问了。把域名配置到小程序后台,哎,不对呀,人家要求的是 https 的,这下悲剧了,好吧,我妥协。
七、HTTPS 配置
Lefe 记得自己的后台不支持 Https,赶快支持一下吧。且慢,我还没有 https 证书呢,咋么让我的 Node 服务支持 Https 呢,自签名的腾讯肯定不可以,果断放弃了这种自签名的方式。Google 了一下免费的 Https 证书,收费的真的太贵了。哎,不错,有免费的,最终选择了腾讯云免费的 https证书,这里有一个坑,使用域名申请证书的时候要用与 ip 地址绑定的那个子域名而不是根域名。比如 lefe 申请的根域名是 lefe.wang,与 ip 绑定的是 wqjp.lefe.wang,那么申请 Https 证书要用域名 wqjp.lefe.wang ,证书也有了,开始配置服务器了,代码如下:
var express = require('express');
var bodyparser = require('body-parser');
var router = require('./router.js');
var mongodb = require('./db/mongodb.js');
var fs = require('fs');
var https = require('https');
var http = require('http');
var app = express();
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({
extended: true
}));
var privateKey = fs.readFileSync('./res/2_wqjp.lefe.wang.key', 'utf8');
var certificate = fs.readFileSync('./res/1_wqjp.lefe.wang_bundle.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var httpsServer = https.createServer(credentials, app);
var httpServer = http.createServer(app);
var SSLPORT = 4000;
var PORT = 4001;
var routeCB = function routeCallBack(req, res, next){
if(req.url=="/favicon.ico"){
res.end();
}
else
{
next()
}
}
var dealCB = function dealCallBack(req, res){
// 解析post参数
router.routed(req, res)
}
app.all('*', [routeCB, dealCB]);
// app.listen(4000);
httpsServer.listen(SSLPORT, function() {
console.log('HTTPS Server is running on: https://localhost:%s', SSLPORT);
});
httpServer.listen(PORT, function() {
console.log('HTTP Server is running on: http://localhost:%s', PORT);
});
Lefe 打开小程序编辑器,模拟器数据一切请求正确,没问题,用真机预览一下吧,啊,咋么没数据呢,后台也没报错啊!到小程序论坛上查了查,不能使用端口。我说呢,我的请求和服务端的同学不一样呢。我的请求是 https://wqjp.lefe.wang:400/api/store/get
,请求本应该是 https://wqjp.lefe.wang/api/store/get
没端口,这可咋办呢?Google 了一下,可以使用 Nginx,啥 Nginx,一直听到后端的同学在说,没想到我也能用到,好吧,我妥协!
八、配置 Nginx
Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行。由俄罗斯的程序设计师Igor Sysoev所开发,供俄国大型的入口网站及搜索引擎Rambler(俄文:Рамблер)使用。其特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。
好吧,一字一句看了,还是不懂。Lefe 的理解是,它可以把你的请求根据不同的需要请求到不同的服务器上。它的作用就是反向代理和负载均衡,不明白也没关系。继续往下看吧。
安装 Nginx:
gcc、g++依赖库
apt-get install build-essential apt-get install libtool安装 pcre依赖库(http://www.pcre.org/)
sudo apt-get install libpcre3 libpcre3-dev安装 zlib依赖库(http://www.zlib.net)
apt-get install zlib1g-dev安装
cd /usr/local/src wget http://nginx.org/download/nginx-1.4.2.tar.gz tar -zxvf nginx-1.4.2.tar.gz cd nginx-1.4.2./configure
--sbin-path=/usr/local/nginx/nginx
--conf-path=/usr/local/nginx/nginx.conf
--pid-path=/usr/local/nginx/nginx.pid
--with-http_ssl_module
--with-pcre=/opt/app/openet/oetal1/chenhe/pcre-8.37
--with-zlib=/opt/app/openet/oetal1/chenhe/zlib-1.2.8
--with-openssl=/opt/app/openet/oetal1/chenhe/openssl-1.0.1tmake
执行完一大堆后,就算安装完成了。那么如何才能 让https://wqjp.lefe.wang:400/api/store/get
的请求指向https://wqjp.lefe.wang/api/store/get
。只能修改配置文件了。Lefe 的配置文件如下,它同时支持 http 和 https。安装完后的 Nginx 在 /usr/local/
目录下,找到配置文件 /usr/local/nginx/conf/nginx.conf
,编辑这个配置文件,在编辑配置文件时,有几个坑需要注意一下:
- # 是配置文件的注释,所以有些地方需要去掉
- server_name 不需要加前缀,比如
http
或https
- proxy_pass 需要是一个完整的地址,包含
http
或https
- 修改完配置文件一定要重启,lefe 不知道从那个地方看到,说
nginx -s reload
这个可以重启,可把我害惨了,一直以为是配置文件的问题,原来是没有重启,重启用这个sudo nginx -c /usr/local/nginx/conf/nginx.conf
- 如果报pid错误,使用
Nginx killall -9 nginx
来解决
#user nobody;
worker_processes 1;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
# 这个是你所申请的域名
server_name wqjp.lefe.wang;
location / {
root /home/ubuntu/nodeserver/WJCar_node/WJCar;
index app.js;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:4001;
proxy_redirect off;
}
}
# HTTPS server
server {
listen 443;
server_name wqjp.lefe.wang;
ssl on;
# 申请https证书的位置
ssl_certificate /home/ubuntu/nodeserver/WJCar_node/WJCar/res/1_wqjp.lefe.wang_bundle.crt;
# 申请https公钥的位置
ssl_certificate_key /home/ubuntu/nodeserver/WJCar_node/WJCar/res/2_wqjp.lefe.wang.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
root /home/ubuntu/nodeserver/WJCar_node/WJCar;
index app.js;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass https://118.89.23.181:4000;
}
}
}
恭喜你完成了!呀,这就完成了,嗯,是的,这下用真机预览,就可以看到漂亮的界面了。想看吗?等等给你看!!!
结尾
写了这么多,也没看到小程序长上样,可以看看吗?好吧,满足你们,放几张漂亮的图,长的丑吗?还好吧,感觉没那么垃圾吧,虽然是小白设计,但是有 sketch 这款强大的设计软件,让 lefe 少走很多弯路。
总结
第一次部署服务器,一步一步下来,花了不少时间,几乎用光了我所有的业余时间,从产品的需要,到设计,到切图,到服务器,到小程序。可以说是经历了一个软件开发的大部分过程。也体会到了工作中各个部门的难处,所以工作中我们需要体谅别人,不要只耕自己的一亩三分地,出现问题找各种理由。作为一个小白,难免会有不得当的地方,有什么问题欢迎反馈,谢谢。
参考
===== 我是有底线的 ======
喜欢我的文章,欢迎关注我的新浪微博 Lefe_x,我会不定期的分享一些开发技巧