APISIX 预研
nginx + lua + etcd = apisix
APISIX 预研
https://apisix.apache.org/zh/docs/apisix/getting-started
当前架构
组件
-
openrestry-1.11.2.5 , 基于 nginx 的反向代理
- ngx_http_dyups_module, dynamic upstreams 动态变更 upsteam, 用来支持 web app 的动态上下线
- ngx_brotli, 压缩算法
-
flume, 日志收集
入站流量
DNS -> FW ----dnat----> NGINX(4 实例)G
日志收集
flume 配合定时任务将 nginx log 发送到 kafka。
其他细节
- log_format, 自定义的 log_format.
log_format time_sessionid_json '{'
'"nginx_hostname": "$hostname",'
'"remote_addr": "$remote_addr",'
'"auth_user_id": "$auth_user_id",'
'"username": "$username",'
'"sessionid": "$sessionid",'
'"time_local": "$time_local",'
'"time_iso8601": "$time_iso8601",'
'"request_method": "$request_method",'
'"uri": "$uri",'
'"request_uri": "$request_uri",'
'"request_length": $request_length,'
'"server_protocol": "$server_protocol",'
'"server_name": "$server_name",'
'"host_domain": "$host",'
'"msec": $msec,'
'"status": $status,'
'"body_bytes_sent": $body_bytes_sent,'
'"http_referer": "$http_referer",'
'"http_user_agent": "$http_user_agent",'
'"request_time": "$request_time",'
'"upstream_addr": "$upstream_addr",'
'"upstream_response_time": "$upstream_response_time",'
'"scheme": "$scheme",'
'"pipe": "$pipe"'
'}';
其中 $auth_user_id, $username, $sessionid 是动态从请求的 Cookie 中取得。
set $sessionid "null";
if ( $http_cookie ~* "sessionid=(\S+)(;.*|$)" ){
set $sessionid $1;
}
set $username "null";
if ( $http_cookie ~* "username=(\S+)(;.*|$)" ){
set $username $1;
}
set $auth_user_id "null";
if ( $http_cookie ~* "_auth_user_id=(\S+)(;.*|$)" ){
set $auth_user_id $1;
}
# nginx.conf
limit_req_zone $binary_remote_addr zone=web:100m rate=30r/s;
limit_req_zone $binary_remote_addr zone=home:100m rate=1r/s;
#limit_req_zone $binary_remote_addr zone=api:100m rate=2r/s;
limit_req_zone $cookie_sessionid zone=api_w:200m rate=1r/s;
limit_req_zone $spider_user_agent zone=baidu_spider:100m rate=100r/s; # 防止百度过去爬取爬虫
limit_req_zone $binary_remote_addr zone=stop_crawler:100m rate=6r/m; # 暂缓爬取蜜罐的爬虫
# xxx.conf
limit_req zone=baidu_spider burst=30;
- auth_request
include includes/sso_com.conf;
auth_request /sso_auth;
APISIX
基于 openresty 与 etcd 组合而成。
openresty (nginx + lua)
运行时细节
nginx 请求处理流程
- NGX_HTTP_POST_READ_PHASE
- NGX_HTTP_SERVER_REWRITE_PHASE
- NGX_HTTP_FIND_CONFIG_PHASE
- NGX_HTTP_REWRITE_PHASE
- NGX_HTTP_POST_REWRITE_PHASE
- NGX_HTTP_PREACCESS_PHASE
- NGX_HTTP_ACCESS_PHASE
- NGX_HTTP_TRY_FILES_PHASE
- NGX_HTTP_CONTENT_PHASE
- NGX_HTTP_LOG_PHASE
openresty 请求处理流程
- init_by_lua
- set_by_lua
- rewrite_by_lua
- access_by_lua
- content_by_lua
- header_filter_by_lua
- body_filter_by_lua
- log_by_lua

apisix 请求处理流程
server {
listen 0.0.0.0:9080 default_server reuseport;
listen [::]:9080 default_server reuseport;
listen 0.0.0.0:9443 ssl default_server http2 reuseport;
listen [::]:9443 ssl default_server http2 reuseport;
server_name _;
ssl_certificate_by_lua_block {
apisix.http_ssl_phase()
}
proxy_ssl_name $upstream_host;
proxy_ssl_server_name on;
location / {
access_by_lua_block {
apisix.http_access_phase()
}
proxy_pass $upstream_scheme://apisix_backend$upstream_uri;
header_filter_by_lua_block {
apisix.http_header_filter_phase()
}
body_filter_by_lua_block {
apisix.http_body_filter_phase()
}
log_by_lua_block {
apisix.http_log_phase()
}
}
---
upstream apisix_backend {
server 0.0.0.1;
balancer_by_lua_block {
apisix.http_balancer_phase()
}
keepalive 320;
keepalive_requests 1000;
keepalive_timeout 60s;
}
nginx.conf 流程相关的关键配置。
关键点在两个地方
- apisix.http_access_phase()
- apisix.http_balancer_phase()
apisix.http_access_phase
1. 查到 route
2. 执行 plugin (rewrite, access)
3. 通过 route 查找关联的 upstream
4. 尝试获取后端 server
apisix.http_balancer_phase
1. 使用 http_access_phase 得到的 upstream,访问后端节点
基本结论
- auth_request 暂不支持
-
apisix 默认配置和现配置有些不一样,需要对比测试。
-
日志收集可以通过 kafka-logger 来做,不需要打到本地之后通过 flume 处理后发送到 kafka。
-
dashboard 需要搭配 etcd, 没有 etcd 就相当与原生的 openresty, 没啥优势。
-
性能不会比 openresty 更好。
-
如何实现应用的平滑上下线,可通过主动+被动的健康探测来实现,而不是通过主动修改 upstream.
- 缩扩容时需要修改 upstream
备注
- 现有配置基于 nginx_web(3fe066ca369781b3300ea634ffd2df6e76f52918)
- apisix lts (2.10.0)