最近工作上需要本地开发机模拟服务器的环境, 最初的需求考虑是 需要搭建 Nginx + Luajit + Redis 组合的配置, 因为本博客所在主机 中使用的是一样的方式配置, 当时就直接参考自己的操作笔记, 重新 搭建一套在开发机上. 因为这些都是基础的系统配置信息,干脆

最近工作上需要本地开发机模拟服务器的环境, 最初的需求考虑是
需要搭建 Nginx + Luajit + Redis 组合的配置, 因为本博客所在主机
中使用的是一样的方式配置, 当时就直接参考自己的操作笔记, 重新
搭建一套在开发机上. 因为这些都是基础的系统配置信息,干脆分享
出来,也希望从读者中收获建议和改善的方案 :)

首先是说明配置的方式和原因:

其实是选择最终二进制文件部署的路径,
我选择的是 /opt/下:
eg:
/opt/nginx /opt/redis /opt/luajit 部署的详情

1. 下载源码包编译安装

Makefile 及脚本里通常的 PREFIX 变量(编译后的路径)
在/usr/local/下,因为我经常更新自己使用的工具或者依赖库(非系统命令安装),
所以我选择在 /opt/下统一放置.
例如工具类: nginx ffmpeg redis mysql luajit lua
他们的配置是
/opt/nginx /opt/ffmpeg /opt/redis
/opt/mysql /opt/luajit /opt/lua

如果是纯库文件 (lib) 例如: boost libevent libev
那么统一放在 /opt/libs/ 下:
/opt/libs/boost /opt/libs/libevent /opt/libs/libev

2. 版本的指定和更新: 经常更新软件, 我会遇到以下问题:

开发项目A依赖 redis 2.6
开发项目B依赖 redis 3.0
其他项目多数依赖 redis 2.8
版本需求不一样, 那么可以这么玩:
/opt/redis/2.6.0
/opt/redis/3.0.0
/opt/redis/2.8.0 同时在 /opt/redis/ 下做一个软链接
即 default -> 2.8.0:
cd /opt/redis
ln -sfn 2.8.0 default Note: ln 参数 n 是在文件夹软链重定向时生效, 否则链接失败

/etc/profile 下定义工具的环境变量
/etc/ld.so.conf.d/ 文件下定义依赖库的路径
基本上是公式化的:
eg:
/opt/nginx/default
/opt/redis/default
/opt/libs/libev/default
/opt/libs/boost/default
default 其实是具体编译版本的文件夹软链接


前提描述完毕, 下面是版本选择:

Nginx 1.6.2
Redis 2.8.17
LuaJIT 2.0.3

Ubuntu 14.04
需要提前安装的库有:
pcre zlib openssl build-essential

1. 编译 Redis 2.8.17

mkdir -p /opt/redis/2.8.17 # 先定义好编译后的路径

进入源码目录

cd redis-2.8.17 make && make install

将 源码目录下编译生成的 src/redis-server src/redis-client
放置在 /opt/redis/2.8.17 下, 其他的辅助工具根据需求配置
(如 redis-benchmark)

cd /opt/redis/
sudo ln -sfn 2.8.17 default

/opt/redis 下定义启动脚本

mkdir init
添加 init/redis-server 脚本 脚本内容看 [gist 传送门] 做 init 脚本软连接到 /etc/init.d
因为 service 命令寻找的是 /etc/init.d 下的脚本名字:
ln -sf /opt/redis/init/redis-server /etc/init.d/

2. 编译 LuaJIT

cd LuaJIT-2.0.3
vim Makefile # 修改
内容如下:
export PREFIX= /opt/luajit/2.0.3
保存退出编译
make
sudo make install
cd /opt/luajit/
ln -sfn 2.0.3 default # 建立软链接

3. 编译 nginx

cd /your_build_path/ # 找一个用于编译工作的目录
1) 首先下载nginx 第三方模块
nginx 开发模块, 目录名是 ngx_devel_kit

git clone https://github.com/simpl/ngx_devel_kit.git
nginx lua 模块, 目录名是 lua-nginx-modul

git clone https://github.com/chaoslawful/lua-nginx-module.git
nginx lua调用的 redis 接口脚本, 目录名是 lua-resty-redis

git clone https://github.com/agentzh/lua-resty-redis.git
nginx lua调用的上传模块脚本, 目录名是 lua-resty-upload

git clone https://github.com/openresty/lua-resty-upload.git
mkdir -p /opt/nginx/1.6.2

放置 init 脚本的路径, 稍后会做软链接
mkdir -p /opt/nginx/init

放置 pid 文件, init 脚本判断状态阅读需要
mkdir -p /opt/nginx/run

daemon 模式时, init 脚本以文件方式上锁, 防止重复 start 进程
mkdir -p /opt/nginx/lock

tmp 文件, nginx client buffer 缓存文件会在这里生成,
以及进程产生的临时文件
mkdir -p /opt/nginx/tmp/client
mkdir -p /opt/nginx/tmp/proxy
mkdir -p /opt/nginx/tmp/fcgi

nginx 启动时加载配置文件 /opt/nginx/default/conf/nginx.conf
里面会调用 include 语法, 加载指定的配置文件, 为了方便管理和规划,
建议自己自定义文件统一放在规划目录下:
eg:
nginx.conf 里配置: include /opt/nginx/sites-available/*.conf;

存放合法的配置文件或者生效的
mkdir /opt/nginx/sites-available

存放暂时不需要的或者已经废弃的配置(可做备份)
mkdir -p /opt/nginx/sites-disable

存放 Lua 依赖脚本的路径
mkdir -p /opt/nginx/lua/share
存放 Lua c lib
mkdir -p /opt/nginx/lua/lib
存放业务的lua脚本(开发人员自己编写的)
mkdir -p /opt/nginx/lua/app

因此在 nginx conf 配置文件中, http 模块或者 server 模块
添加上如下配置信息(Lua 依赖的路径, 假设 Lua5.1版本):
lua_package_path “/opt/nginx/lua/share/?.lua;”;
lua_package_cpath “/opt/nginx/lua/lib/?.so;/opt/luajit/default/lib/lua/5.1/?.so;”;
而在location 块中执行的 Lua 脚本, 出现 content_by_lua_file 语法,
则可以指定执行的脚本存在 /opt/nginx/lua/app 路径下

日志路径
mkdir -p /var/log/nginx

下载的源码包也在与上面模块一样的根目录下, 然后解压, 进入源码文件夹:
cd nginx-1.6.2
configure 编译:

# configure 编译  
./configure \
    --prefix=/opt/nginx/1.6.2/ \
    --error-log-path=/var/log/nginx/error.log \
    --pid-path=/opt/nginx/run/nginx.pid  \
    --lock-path=/opt/nginx/lock/nginx.lock \
    --user=nginx \
    --group=nginx \
    --with-http_ssl_module \
    --with-http_realip_module \
    --with-http_flv_module \
    --with-http_gzip_static_module \
    --http-log-path=/var/log/nginx/access.log \
    --http-client-body-temp-path=/opt/nginx/tmp/client/ \
    --http-proxy-temp-path=/opt/nginx/tmp/proxy/ \
    --http-fastcgi-temp-path=/opt/nginx/tmp/fcgi/ \
    --add-module=../ngx_devel_kit \
    --add-module=../lua-nginx-module 
登录后复制

编译执行:
make && sudo make install

部署 Lua 依赖脚本:
mkdir /opt/nginx/lua/share/restry
cp lua-restry-redis/lib/restry/redis.lua /opt/nginx/lua/share/restry/
cp lua-restry-upload/lib/restry/upload.lua /opt/nginx/lua/share/restry/

在 /opt/nginx/default/conf/nginx.conf 里配置的例子:

# 主配置文件的参数例子
# 进程数设置是 cpu核数-2, nginx master 进程只accept连接
# 例如4cpu, processes 数3
worker_processes  3; 
# 根据生产服务场景设置, 基于 LuaJIT 的nginx, lua vm 内存最大承载 1G, 
# 占用内存有限, 连接数尽量设置在合理范围之内, 待测试
events {
 worker_connections  1024;   
}
# http 块设置
http {
    lua_code_cache on; # debug 情况下 off, 方便调试
    lua_package_path "/opt/nginx/lua/share/?.lua;";
    # 如果有luajit支持,需要添加该路径
    lua_package_cpath "/opt/nginx/lua/lib/?.so;/opt/luajit/default/lib/lua/5.1/?.so;"; 
    server_tokens off; # 关闭 nginx 的版本信息(对外)
    include       mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    error_log /var/log/nginx/error.log error;
    sendfile off; #
    # 禁止了nagle算法, 即数据即时发送出去, 而不是刻意控制拥塞
    tcp_nopush off; 
    keepalive_timeout 65;
    
    gzip on;
    
    # 业务配置
    include /opt/nginx/sites-available/*.conf;
}  
登录后复制

nginx 服务的启动文件 [gist 传送门] 存放在 /opt/nginx/init/nginx
做软链接:
ln -sf /opt/nginx/init/nginx /etc/init.d/

Nginx + LuaJIT + Redis 的配置大致的手工流程描述完毕.

总结源码编译服务工具的思路:

1. 了解 Makefile 里通常会有 PREFIX 这样的关键字,
它定义了最终的编译生成路径, 无论是 configure 指定 –prefix 参数
还是Makefile 里直接修改都是可以的.

2. 尽量不安装在默认的 /usr/local/ 下, 建议选择 /opt/ 或者
/your_self_define/ 自定义的路径, 统一放置, 无论是开发环境还是
生产环境, 干净的依赖环境有利于调试和部署.

3. 工具版本的依赖里定义一个 default 软链接, 以方便版本切换, 这是一个建议习惯.


题外话:

0. 今年4月份 曾经在自己主机上 Nginx + Lua + Redis, Lua基于
LuaJIT解释器, 使用apache jmeter做并发连接测试, 在 512M内存的虚拟主机
同时 1000的连接, 每个连接一次请求对主机的cpu也只是瞬时的90%, 而所有请求都
正常返回结果, 承载高并发的 http 短连接请求稳定性在主机上测试还是可靠的, 而用
Node.js 跑了同样的服务, 会发生请求失败, 失败次数在5%左右. 当然, 测试的
环境条件也有其他影响, 比如 js的代码和依赖的库相比于 Lua的代码复杂. 如果
业务简单, 使用 Node.js + Redis 是成本最低的解决方案. 而 Nginx
方案主要在配置精力上和迁移性(Nginx bin文件, LuaJIT解释器), 做 Demo
或者需求经常变化的场景, Node.js 的部署是较为方便的.

1. 部署工具在不断更新, 也有了 Docker 这样的工具, 减少了开发者了解发行版
之间的差异的成本, 运维工程师这个职业也会有新的挑战和认识, 也许会转向更
后台和底层的方向发展, 或者以 DevOps 的方式出现.

2. 互联网行业创业是一个流行的活动, 以开发工程师为主的初创团队在运维上
经验不足, 在人力成本和招人困难的情况下会优先选择对开发者友好的开源运维
工具. 例如常用的运维开源工具就有:
部署工具 SaltStack, Puppet, Jenkins
监测工具 Nagios Zabbix
日志收集 Logstash
进程管理工具 Supervisor
然而这并不表示不需要合格的运维工程师, 或者是为开发者服务的工程师. 至于
需要的程度, 每一位开发者都会根据自己的工作经历和体会去感受 :)

原创文章,转载请注明: 转载自kaka_ace's blog

本文链接地址: Nginx + LuaJIT + Redis 编译配置教程

09-02 03:02