最近笔者在开发一个图标包APP模版 NanoIconPack(开源),其中的图标申请适配板块需要服务器的支持。由于自己有 J2E 的开发经验,所以一开始打算通过 J2E 来实现。但在设计时发现接口并不多也不复杂,那么用 J2E 就有些麻烦了。恰好,此前听说过 Nodejs,用 JavaScript 来编写服务器代码,并且 Nodejs 自身就实现了整个服务器。很有趣,似乎也够简单够轻量,那么为什么不尝试一下呢,说干就干,带学带练。
Nodejs 的特征是单进程单线程,但几乎所有方法都是异步,接受请求后就交棒给下一环节去处理,马上又去服务下一个请求。这使得它的效率非常高。看来选它没错了。接下来就是数据库,毫无疑问,当然是 MySQL。另外,经过了解,Nodejs 属于脆弱性,一旦某处出错,将导致整体崩溃。要保证稳定运行,代码就要写得十分强悍,要考虑到各种异常处理。对于笔者这种入门者,有什么好的解决办法呢?笔者想到了做负载均衡的 Nginx,用在此处正合适。利用 Nodejs 轻量的优势,就可以在一台硬服上启动数个 Nodejs 软服,用 Nginx 来反向代理,避免一个 Nodejs 应用崩溃对 APP 端造成影响。
Nodejs + Nginx + MySQL,跑在 Ubuntu 上,再合适不过了。这样,即使从阿里购置一台最低配(有多低?1核/1G/1Mbps)的云服务器想来也是足够的,不过还是有待后期验证。下面就简要记录实现 NanoIconPack 服务器的过程。
一、设计 MysQL 库表
MySQL 的安装就不赘述了。SQL建表语句如下:
-- 申请表
CREATE TABLE req(
-- 根据APP名自动生成图标名(可能没有)
icon VARCHAR(128),
-- 目标APP名
label VARCHAR(128),
-- 目标APP名英文(可能没有)
label_en VARCHAR(128),
-- 包名
pkg VARCHAR(128),
-- 启动项
launcher VARCHAR(192),
-- 是否为系统APP
sys_app TINYINT(1) DEFAULT 0,
-- 归属图标包包名
icon_pack VARCHAR(64),
-- 设备ID(取 ANDROID_ID + SERIAL)
device_id CHAR(32),
-- 设备品牌
device_brand VARCHAR(32),
-- 设备型号
device_model VARCHAR(32),
-- 设备系统版本
device_sdk TINYINT(1) DEFAULT 0,
-- 申请时间
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(pkg, launcher, icon_pack, device_id)
);
-- 申请过滤表
CREATE TABLE req_filter(
-- 归属图标包包名
icon_pack VARCHAR(64),
-- 用户
user VARCHAR(64),
-- 包名
pkg VARCHAR(128),
-- 申请时间
time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(icon_pack, user, pkg)
);
二、Nodejs 的代码编写与配置
考虑到 Nodejs 是用 JS 做支撑,笔者索性就放弃了使用开发环境,而直接用文本编辑器(EditPlus)搞定。(开发环境的话,Eclipse 有相关插件,还有一些不错的 IDE。)
由于比较简单,也没有涉及HTML页面,也就没有选择通过 express-generator
来生成项目框架,而是直接几个简单的 .js
文件:
├ /logs
├ nano1.js
├ nano2.js
├ mysql.js
└ utils.js
笔者使用的电脑是 Windows 系统,幸运的是 Nodejs 有 Windows 版本(Nginx 也有),虽然性能差些,但测试足矣,最后部署到 Ubuntu 上即可。
Nodejs 的安装配置可以参考笔者此前的一篇笔记——Node.js 尝鲜笔记。
安装相关依赖:
npm install mysql
npm install express
npm install body-parser
npm install log4js
跑起来:
forever start nano8082.js
forever start nano8083.js
相关命令:forever list
、forever stop nano8082.js
三、Nginx 的配置与整个服务器的部署
笔者选择了最简单的方式来安装 Nginx。
apt-get install nginx
Nginx 默认使用了 80 端口,为了不对已经在使用80端口的其他服务器造成影响,先停了它:
service nginx stop
Usage: nginx {start|stop|restart|reload|force-reload|status|configtest|rotate|upgrade}
以上命令是针对从仓库安装 Nginx 的情况,与编译安装不同。更多信息可以去 Nginx 官网了解(包括 Windows 版的使用方法)。
配置反向代理 Nodejs:
配置 /etc/nginx/sites-enabled
,/etc/nginx/nginx.conf
可以不用修改。
# 指定工作的服务器
upstream nodejs_servers {
server 127.0.0.1:8082;
server 127.0.0.1:8083;
}
server {
# 为了避免与其他项目端口冲突,修改 80 端口为其他端口
listen 9090 default_server;
listen [::]:9090 default_server ipv6only=on;
}
# 增加服务器配置
server {
listen 8081;
server_name www.by-syk.com;
location / {
proxy_pass http://nodejs_servers;
# 解决getRequestURL、getServerName、getServerPort
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 解决getScheme、isSecure、sendRedirect
proxy_set_header X-Forwarded-Proto $scheme;
}
}
启动 Nginx
service nginx start
测试,包括两台同时工作的情况,以及手动停掉一台的情况。均正常。