Tengine一键编译脚本可选lua并配置负载均衡

1,611 阅读3分钟

Tengine是什么

Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。

总的来说,Tengine在nginx基础上增加了一些功能模块,具备某些nginx(免费开源版)不具备的功能,使得用起来更方便。Tengine官网链接: tengine.taobao.org/

为什么要用Tengine

​ 前段时间业务上有这样一个需求: ServerA调用ServerB的接口,ServerB接口比较耗费性能,所以在此基础上ServerB加了内存缓存,使其变成了一个有状态的服务。对于有状态的服务,我们希望调用接口时,同样的参数只会访问同一台机器。所以这样就需要对参数做一下hash处理,确保每次都会hash到那台机器。

​ 思来想去还是选择了Tengine,不过实现效果还是相对比较理想的。实现方式是:所有相关的api都加一个相同的query参数,value是我们要hash的值,这样Tengine模块每次都会对这个参数进行一致性hash处理,从而达到我们的目的。

​ 不过Tengine安装时不能使用系统自带的包管理器去安装,比如:apt install | yum install 所以需要自己编译需要的模块。

​ 因为需要配合prometheus的状态码监控模板用到了ruby,所以在此基础上又增加了ruby编译模块,所以相对复杂一些,需要Ruby的童鞋可以执行脚本时加入 -r 参数

安装步骤:

  1. 直接安装: 不需要ruby的请直接执行

    curl -fsSL https://fff.dev/extras/tengine_install.sh | bash
    

    需要ruby的请直接执行

    curl -fsSL https://fff.dev/extras/tengine_install.sh | bash -s --  -r
    
  2. 保存一下脚本命名为 tengine_install.sh 然后执行 chmod +x tengine_install.sh && ./tengine_install.sh -r
    #!/usr/bin/env bash
    
    # tengine 安装, 支持编译lua
    cd "$(dirname $0)" || exit 0
    # lua模块安装位置, 可以更改为其他文件夹
    BASE_DIR="/data/nginx"
    
    # 安装相关编译模块
    apt update && apt-get -y install wget libpcre3 libpcre3-dev libssl-dev g++ zlib1g-dev
    if [[ ! -d ${BASE_DIR} ]]; then
      mkdir -p ${BASE_DIR}
    fi
    
    cd "${BASE_DIR}" || (echo "${BASE_DIR} not exists, exit" && exit 0)
    # 安装luagit
    if [[ ! -d "luajit" ]]; then
      wget https://github.com/openresty/luajit2/archive/v2.1-20190626.tar.gz
      tar zxf v2.1-20190626.tar.gz && mv luajit2-2.1-20190626 luajit
    fi
    # 安装 ngx_devel_kit 模块
    if [[ ! -d "ngx_devel_kit" ]]; then
      wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1rc1.tar.gz
      tar zxvf v0.3.1rc1.tar.gz && mv ngx_devel_kit-0.3.1rc1 ngx_devel_kit
    fi
    
    if [[ ! -d "lua-nginx-module-0.10.15" ]]; then
      wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz
      tar zxf v0.10.15.tar.gz
    fi
    
    cd luajit && make && make install PREFIX=${BASE_DIR}/luajit/lualib
    cd "${BASE_DIR}" || (echo "${BASE_DIR} not exists, exit" && exit 0)
    
    export LUAJIT_LIB=${BASE_DIR}/luajit/lualib/lib
    export LUAJIT_INC=${BASE_DIR}/luajit/lualib/include/luajit-2.1
    
    # 下载 tengine
    if [[ ! -d "tengine-2.3.1" ]]; then
      wget https://tengine.taobao.org/download/tengine-2.3.1.tar.gz
      tar zxvf ./tengine-2.3.1.tar.gz
    fi
    
    cd tengine-2.3.1 || (echo "tengine-2.3.1 not exists, exit" && exit 0)
    
    ruby=false
    
    while getopts "r" opt; do
        case $opt in
        r)
          ruby=true
          ;;
        ?)
          echo "invalid option -$OPTARG" >&2
          ;;
        esac
    done
    base='./configure \
      --with-http_v2_module \
      --prefix=/etc/nginx \
      --sbin-path=/usr/sbin/nginx \
      --error-log-path=/var/log/nginx/error.log \
      --http-log-path=/var/log/nginx/access.log \
      --pid-path=/var/run/nginx.pid \
      --lock-path=/var/run/nginx.lock \
      --with-http_stub_status_module \
      --with-http_ssl_module \
      --add-dynamic-module=./modules/ngx_http_concat_module \
      --add-dynamic-module=./modules/ngx_http_footer_filter_module \
      --add-dynamic-module=./modules/ngx_http_proxy_connect_module \
      --add-dynamic-module=./modules/ngx_http_reqstat_module \
      --add-dynamic-module=./modules/ngx_http_sysguard_module \
      --add-dynamic-module=./modules/ngx_http_trim_filter_module \
      --add-dynamic-module=./modules/ngx_http_upstream_check_module \
      --add-dynamic-module=./modules/ngx_http_upstream_consistent_hash_module \
      --add-dynamic-module=./modules/ngx_http_upstream_dynamic_module \
      --add-dynamic-module=./modules/ngx_http_upstream_session_sticky_module \
      --add-dynamic-module=./modules/ngx_http_user_agent_module \
      --add-dynamic-module=./modules/ngx_slab_stat \
      --add-dynamic-module=./modules/ngx_http_slice_module \'
    
    ruby_extra="
      --add-module=${BASE_DIR}/ngx_devel_kit \\
      --add-module=${BASE_DIR}/lua-nginx-module-0.10.15 \\
      --with-ld-opt="-Wl,-rpath,${BASE_DIR}/luajit/lualib/lib" \\
      --add-dynamic-module=./modules/ngx_http_lua_module"
    
    if ${ruby}; then
        echo "adding ruby params"
        base="${base}${ruby_extra}"
    fi
    
    eval "${base}"
    
    make && make install
    
    rm -rf ./${0}
    rm -rf tengine-2.3.1*
    
    echo 'ALL DONE, 请开始你的表演'
    

Tengine配置解释

​ 详细文档可见 tengine.taobao.org/documentati…

  • –with-http_v2_module: 支持http2, Tengine默认是不支持HTTP2的

  • prefix tengine: 配置文件保存位置

  • sbin-path: nginx bin文件保存路径

  • error-log-path: 错误日志保存路径

  • http-log-path: 正常访问日志保存路径

  • pid-path: pid文件路径

  • lock-path: lock文件路径

  • with-http_stub_status_module:

    状态监测模块。使用方式如下

    1. 将下面代码块添加至nginx.conf server块中

      location /nginx_status {
          # Turn on nginx stats
          stub_status on;
          # I do not need logs for stats
          access_log   off;
          # Security: Only allow access from 192.168.1.100 IP #
          #allow 192.168.1.100;
          # Send rest of the world to /dev/null #
          #deny all;
      }
      
    2. nginx -t 先 监测下配置是否正确,没问题的话执行nginx -s reload重新加载配置文件
    3. curl {ip}:{端口号}/nginx_status 获取检测信息,返回结果类似于

      Active connections: 3 
      server accepts handled requests request_time
       108026 108026 1595888 15222629
      Reading: 0 Writing: 1 Waiting: 2
      
  • with-http_ssl_module: SSL模块,默认自带

  • ngx_http_concat_module: 该模块类似于apache中的mod_concat模块,用于合并多个文件在一个响应报文中。

  • ngx_http_footer_filter_module: 在请求的响应末尾输出一段内容。输出内容可配置,并支持内嵌变量。详见 tengine.taobao.org/document_cn…
  • ngx_http_upstream_check_module: 主动式后端服务器健康检查模块,一般用于负载均衡

  • ngx_http_upstream_consistent_hash_module: 一致性hash模块,

    支持针对 header、query参数、ip等做hash。详见 tengine.taobao.org/document_cn…
  • ngx_http_user_agent_module: UA解析模块

  • ngx_http_upstream_session_sticky_module:黏性session模块,一般用于负载均衡时有状态服务

  • ngx_http_reqstat_module:状态监视模块 详见 tengine.taobao.org/document_cn…

​编译完成后可以直接访问 cd /etc/nginx/conf 来配置相关的config,配置参数和nginx一致。

负载均衡相关配置

upstream server-test {
  			# 一致性hash配置, 以xxx作为hash的key, 不需要此功能注释掉即可
  			consistent_hash $arg_xxx;
  			# server list  weight为权重,值越大访问比例越大
        server server001:8000 id=1004  weight=2;
        server server002:8000 id=1005  weight=2;
  
        # 黏性session
        # session_sticky;
        # 每隔3秒检测一次状态, 两次成功则server可用,5次失败表示server不可用,检测使用http协议
        check interval=3000 rise=2 fall=5 timeout=1000 type=http;
        # 该指令可以配置一个连接发送的请求数,其默认值为1,表示Tengine完成1次请求后即关闭连接。
        check_keepalive_requests 1;
				# 该指令可以配置http健康检查包发送的请求内容。为了减少传输数据量,推荐采用"HEAD"方法
        check_http_send "HEAD / HTTP/1.1\r\nConnection: keep-alive\r\n\r\n";
  			# 该指令指定HTTP回复的成功状态,默认认为2XX和3XX的状态是健康的
        check_http_expect_alive http_2xx http_3xx;
}

server {
        listen       8100;
        server_name  localhost;

        location / {
    						# 由此引入上边的upstream
                proxy_pass http://server-test;
        }

        location /status {
               check_status;
               access_log off;
         }

}