網關系統 apisix/kong 日志收集方案實施對比


目前在一個核心服務上應用一個網關系統,並后期推廣升級

網關調研方向包括spring,kong apisix,java棧的netty由於一些原因,不適合應用方向

同時考慮雲原生的友好程度,簡單說是否有配套的k8s ingress和k8s能使用同一套方案,減少技術團隊整體的學習和使用成本,主要考慮kong和apisix

kong + konga + kong ingress 個人深度使用了有3年多,整體比較滿意

k8s平台集成kong ingress 布署konga集成ui - 博客園 (cnblogs.com)

apisix官方和kong的性能對比,實際是比較的kong1.0,個人對apisix和kong的性能對比是有點疑問的,只不過一般的業務流量,所以在kong能滿足要求的前提下,對apisix只是有限了解


目前為加強基礎架構對各上層應用的全局支持,需要添加對request_body的請求日志收集,基礎的nginx都能做到這點,也許是kong的處理流程上做了較大調整,kong 官方居然不支持

官方插件庫 Kong Hub | Plugins and Integrations | Kong Docs (konghq.com)

1 首先官方的log類插件並不能簡單便捷的添加對request_body的收集

HTTP Log plugin | Kong Docs (konghq.com)

kong 免費版本提供的log相關插件,都不支持對request_body的收集上報

kong 插件上報一部分,再通過更改kong相關的nginx配置生成一部分,兩部分用flink做大數據處理雙流join實現,該方案不優雅

考慮直接通過kong 插件收集

准備找找有沒有第三方的方案,有必要的的話需要自己參照kong的官方插件寫插件了

整體看了下難度倒是不大,個人以前搞openwrt路由器luci時有點lua的開發經驗 lua https request 調用 - 博客園 (cnblogs.com)

EuphonyInc/kong-plugin-request-body-logger: A plugin for Kong which enables logging of request bodies over HTTP (github.com)

2 日志處理收集,寫入kafka的場景較為典型,通常結合大數據spark streaming/flink 做流式計算

https://docs.konghq.com/hub/kong-inc/kafka-log

kong 官方插件庫提供kafka 的日志收集,但是收費,同時有不能簡易收集request_body的問題

3 Kafka Upstream plugin | Kong Docs (konghq.com)

kong 有一個專門的上報kafka組件,

--data "config.forward_body=true" 簡單看了遍文檔,這個插件支持對request_body的日志收集,該組件也同樣收費

log類插件不支持request_body,kafka在日志收集上的應用,再看看這個收費插件,大概明白官方為什么沒有把request_body做在免費插件里了

在log插件代碼基礎上加上request_body 還算簡單,但在沒有官方代碼參照的基礎上(這些代碼官方未開源),實現寫kafka 難度和工作量會大很多,可以用多級上報,結合filebeat,logstash,prometheus之類的實現

基礎功能足夠日常使用,收費功能有效,但預算有限,因此轉頭看看其他方案有沒有替代,比如apisix


apisix 目前全開源,比較合胃口,開源則對一些官方不支持的特性做定制化開發比較方便,kong也開源了,但插件類同樣只開源了免費的部分

apisix官方插件庫

apisix/apisix/plugins at release/2.11 · apache/apisix (github.com)

請求日志收集至kafka

apisix/kafka-logger.lua at release/2.11 · apache/apisix (github.com)

看代碼,支持對request的收集

        include_req_body = {type = "boolean", default = false},
        include_req_body_expr = {
            type = "array",
            minItems = 1,
            items = {
                type = "array",
                items = {
                    type = "string"
                }
            }
        }

並未用kong2.0和apisix做基礎性能對比,但就日志request_body收集功能上,apisix和kong 基礎免費版,apisix強於kong

因此網關系統開始部分從kong遷移轉至apisix


以下是部分測試驗證的細節,啟動log-kafka插件收集

{
    "broker_list": {
        "192.168.11.22": 9092,
        "192.168.11.23": 9092,
        "192.168.11.24": 9092
    },
    "kafka_topic": "test_apisix",
    "key": "key1",
    "batch_max_size": 1,
    "name": "kafka logger",
    "include_req_body":true,
    "meta_format":"default",
    "log_format":""
}

meta_format支持兩種格式,為收集解析方便使用"default"

樣例日志
{
    "start_time": 1638185753246,
    "client_ip": "172.17.0.1",
    "latency": 0,
    "service_id": "127.0.0.1",
    "server": {
        "hostname": "fe053d1baf4a",
        "version": "2.9"
    },
    "response": {
        "status": 404,
        "headers": {
            "server": "APISIX/2.9",
            "connection": "close",
            "transfer-encoding": "chunked",
            "content-type": "text/plain; charset=utf-8"
        },
        "size": 223
    },
    "request": {
        "headers": {
            "host": "127.0.0.1:8280",
            "user-agent": "curl/7.29.0",
            "accept": "*/*"
        },
        "method": "GET",
        "size": 83,
        "url": "http://127.0.0.1:9080/hello",
        "querystring": {},
        "uri": "/hello"
    }
}

自定義格式

curl http://127.0.0.1:9080/apisix/admin/plugin_metadata/kafka-logger -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
{
    "log_format": {"host": "$host", "@timestamp": "$time_iso8601",    "client_ip":"$remote_addr","request_id":"$request_id","request_length":"$request_length","request_time":"$request_time","header_test_1":"$http_nothas","header_test_1":"$http_x-api-key","body":"$request_body"}
}'

apisix從測試和查看源碼上看,也有些待優化的點

1 "default"格式完全默認無法自定義,如果需要nginx原生的一些信息,則需要使用log_format

defautl信息為目前為硬編碼,如果需要一些別的信息,需要直接修改代碼
https://github.com/apache/apisix/blob/2.10.1.1/apisix/utils/log-util.lua

default格式實現,和上面的demo對應
local log =  {
        request = {
            url = url,
            uri = var.request_uri,
            method = ngx.req.get_method(),
            headers = ngx.req.get_headers(),
            querystring = ngx.req.get_uri_args(),
            size = var.request_length
        },
        response = {
            status = ngx.status,
            headers = ngx.resp.get_headers(),
            size = var.bytes_sent
        },
        server = {
            hostname = core.utils.gethostname(),
            version = core.version.VERSION
        },
        upstream = var.upstream_addr,
        service_id = service_id,
        route_id = route_id,
        consumer = consumer,
        client_ip = core.request.get_remote_client_ip(ngx.ctx.api_ctx),
        start_time = ngx.req.start_time() * 1000,
        latency = (ngx_now() - ngx.req.start_time()) * 1000
    }

#默認的default格式
_M.get_full_log = get_full_log
#自定義全局格式
_M.get_custom_format_log = get_custom_format_log               

2 log_format目前是全局生效的,即全局只能有一種log_format格式,若想對不同的路由配置不同的規則,則作不到

3 可以通過修改 https://github.com/apache/apisix/blob/2.10.1.1/apisix/utils/log-util.lua default格式的log內容,很簡單

apisix滿足網關的性能和日志收集需求

END


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM