Windows
由于APISIX不支持在Windows环境下运行。刚开始想将源码移植到windows下,但是lua模块安装太麻烦算了。官方提供的Docker镜像很方便,于是尝试在Windows下使用Docker环境调试源码。
准备工作
-
APISIX 源码下载 源码标注版本下载地址
-
APISIX 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
复制代码