【APISIX源码探究】Windows下运行环境搭建

1,281 阅读3分钟

Windows

由于APISIX不支持在Windows环境下运行。刚开始想将源码移植到windows下,但是lua模块安装太麻烦算了。官方提供的Docker镜像很方便,于是尝试在Windows下使用Docker环境调试源码。

准备工作

# 将 Apache APISIX 的 Docker 镜像下载到本地
> git clone https://github.com/apache/apisix-docker.git
# 切换到`2.13.1`分支
# 将当前的目录切换到 apisix-docker/example 路径下
> cd apisix-docker/example
# 修改docker-compose.yml,这里将容器运行的lua代码替换成本地代码,实现方便修改查看
services->apisix->volumes:
+ [apisix源码根目录]\apisix:/usr/local/apisix/apisi
+ [apisix源码根目录]\conf:/usr/local/apisix/conf
+ [apisix源码根目录]\logs:/usr/local/apisix/logs
# 运行 docker-compose 命令,安装 Apache APISIX 
> docker-compose -p docker-apisix up -d

不出意外的话浏览器访问http://localhost:9000/就能看到APISIX的后台管理系统

修改源码运行

因为容器使用的本地代码在运行,所以我们可以直接修改本地代码,并重启APISIX就能看到效果

打开apisix/cli/apisix.lua,在ops.execute函数执行前加入下面代码:

  • print("hello local APISIX")

进入容器执行/usr/bin/apisix reload,可看到刚才修改的打印已经可以输出到控制台中

Dockerfile分析

上面我们运行的compose是官方已经构建好的运行环境,在/alpine/Dockerfile文件中,我们可以看到一个APISIX的运行环境是怎么构建起来的

# 定义一个变量是否需要使用代理下载apk,需要自己构建可以设置为true加速
ARG ENABLE_PROXY=false

# 基于以下镜像开始构建
FROM api7/apisix-base:1.19.9.1.5 AS production-stage

ARG ENABLE_PROXY
# set -x 将后续执行的命令打印出来
RUN set -x \
# 替换镜像源
    && (test "${ENABLE_PROXY}" != "true" || /bin/sed -i 's,http://dl-cdn.alpinelinux.org,https://mirrors.aliyun.com,g' /etc/apk/repositories) \
# 安装下面的依赖
    && apk add --no-cache --virtual .builddeps \
        build-base \
        automake \
        autoconf \
        make \
        libtool \
        pkgconfig \
        cmake \
        unzip \
        curl \
        openssl \
        git \
        pcre \
        pcre-dev \
        openldap-dev \
# 这里安装lua的依赖,具体可参考luarocks
    && luarocks install https://github.com/apache/apisix/raw/master/rockspec/apisix-master-0.rockspec --tree=/usr/local/apisix/deps \
    && cp -v /usr/local/apisix/deps/lib/luarocks/rocks-5.1/apisix/master-0/bin/apisix /usr/bin/ \
    && mv /usr/local/apisix/deps/share/lua/5.1/apisix /usr/local/apisix \
# lua依赖安装完成,继续安装其他东西
    && apk del .builddeps \
    && apk add --no-cache \
        bash \
        curl \
        libstdc++ \
        openldap \
        tzdata \
# 这里把日志重定向到docker处理
    && ln -sf /dev/stdout /usr/local/apisix/logs/access.log \
    && ln -sf /dev/stderr /usr/local/apisix/logs/error.log

# 设置工作目录
WORKDIR /usr/local/apisix

# 添加环境变量
ENV PATH=$PATH:/usr/local/openresty/luajit/bin:/usr/local/openresty/nginx/sbin:/usr/local/openresty/bin

# 导出端口
EXPOSE 9080 9443

# 容器启动时分别执行以下代码
# `/usr/bin/apisix init` 用于初始化nginx配置等
# `/usr/bin/apisix init_etcd` 用于初始化etcd相关内容
# `/usr/local/openresty/bin/openresty -p /usr/local/apisix` 启动openresty
# `-g 'daemon off;'` 使用了CMD后,使得在docker中以前台方式运行nginx,否则nginx会在docker启动后立即停止
CMD ["sh", "-c", "/usr/bin/apisix init && /usr/bin/apisix init_etcd && /usr/local/openresty/bin/openresty -p /usr/local/apisix -g 'daemon off;'"]

# 用于通知前台进程组终止进程
# 由于nginx结束任务的信号处理比较特殊,在接收到SIGQUIT才做优雅的退出,否则在用默认的退出信号SIGTERM会立即结束进程,导致正在连接的用户连接断开。
# 参考: https://ubuntu.com/blog/avoiding-dropped-connections-in-nginx-containers-with-stopsignal-sigquit
STOPSIGNAL SIGQUIT

APISIX入口执行

从上面Dockerfile可以了解到,启动APISIX的命令使用了/usr/bin/apisix,就是找到APISIX的真正启动代码/usr/bin/apisix/cli/apisix.lua,并用luajit执行。

# 根据启动方式获取到APISIX启动程序
if [ -s './apisix/cli/apisix.lua' ]; then
    # install via source
    APISIX_LUA=./apisix/cli/apisix.lua
elif ...
fi

# 这里获取openresty可执行文件的路径,如果没有就不赋值,此处值为`/usr/local/openresty/bin/openresty`
OR_BIN=$(command -v openresty || exit 1)
OR_EXEC=${OR_BIN:-'/usr/local/openresty-debug/bin/openresty'}
OR_VER=$(openresty -v 2>&1 | awk -F '/' '{print $2}' | awk -F '.' '{print $1"."$2}')
LUA_VERSION=$(lua -v 2>&1| grep -E -o  "Lua [0-9]+.[0-9]+")

if [[ -e $OR_EXEC && "$OR_VER" =~ "1.19" ]]; then
    # OpenResty version is 1.19, use luajit by default
    # find the luajit binary of openresty
    LUAJIT_BIN=$(${OR_EXEC} -V 2>&1 | grep prefix | grep -Eo 'prefix=(.*)/nginx\s+--' | grep -Eo '/.*/')luajit/bin/luajit

    # use the luajit of openresty
    echo "$LUAJIT_BIN $APISIX_LUA $*"
    exec $LUAJIT_BIN $APISIX_LUA $*
elif [[ "$LUA_VERSION" =~ "Lua 5.1" ]]; then
    # OpenResty version is not 1.19, use Lua 5.1 by default
    echo "lua $APISIX_LUA $*"
    exec lua $APISIX_LUA $*
else
    echo "ERROR: Please check the version of OpenResty and Lua, OpenResty 1.19 + LuaJIT or OpenResty before 1.19 + Lua 5.1 is required for Apache APISIX."
fi