zoukankan      html  css  js  c++  java
  • 网关系统 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

  • 相关阅读:
    My SQL
    弹窗
    DBDA
    ThinkPHP验证码与文件上传
    ThinkPHP表单验证
    ThinkPHP增删改
    ThinkPHP模型(查询)
    ThinkPHP跨控制器调用方法
    Superset安装
    Presto资源组配置
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/15674011.html
Copyright © 2011-2022 走看看