目前在一個核心服務上應用一個網關系統,並后期推廣升級
網關調研方向包括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)
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滿足網關的性能和日志收集需求