借助Kong记录接口的请求和响应内容

和APISIX类似,Kong也是一个Api GateWay。

运行在调用Api之前,以插件的扩展方式为Api提供管理, 如 鉴权、限流、监控、健康检查等. Kong是基于Lua语言、Nginx以及OpenResty开发的,拥有动态路由、负载均衡、高可用、高性能、熔断(基于健康检查)等功能。

和APIXIS不同,不用etcd做存储,而使用PostgreSQL,最早用的是Apache Cassandra

基础使用

安装过程忽略,可使用docker一键搭建

假设我有一个服务A,对外提供多个接口。现在想要使用Kong对其进行管理

服务A所在的机器,和运行kong的机器不一定是一台.

Kong就是个网关,统一入口。

服务A如下,

go 复制代码
package main

import (
        "fmt"
        "net/http"
        "time"
)

func helloHandler(w http.ResponseWriter, r *http.Request) {
        if r.URL.Path == "/hello" {
                currentTime := time.Now().Format("2006-01-02 15:04:05")
                response := fmt.Sprintf("你好,当前时间是%s", currentTime)
                fmt.Fprint(w, response)
        } else {
                http.NotFound(w, r)
        }
}

func main() {
        http.HandleFunc("/", helloHandler)
        fmt.Println("Server is running on port 58888")
        err := http.ListenAndServe(":58888", nil)
        if err != nil {
                fmt.Println("Error starting server:", err)
        }
}

curl 服务所在机器的公网IP:58888/hello 会返回当前的时间

在kong的控制台, http://Kong所在机器的公网IP:8002 创建一个Gateway Service,

其中,Host写要代理的那个服务的地址(即A所在机器的公网IP),端口写相应的端口

如果是域名,则端口写默认的80

然后新建一条Routes

然后, 就可以通过 curl http://Kong服务的公网IP:8000/上图写的Paths/hello 来访问了

得到的结果还是一样的,但会先通过kong,就能做很多事情了...比如限流,鉴权,日志啥的...

记录接口的请求和响应内容

Kong也提供了很多直接可用的插件,下面以HTTP Log插件为例, 使用该插件,可以记录接口的请求和响应内容

在Plugins处点击New Plugin,

搜索HTTP

再写一个服务(该服务监听20017端口),提供一个接口,用来接收:58888 这个服务全部的请求和响应内容

go 复制代码
package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

func getRequestHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		w.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(w, "Error reading request body: %v", err)
		return
	}
	defer r.Body.Close()

	log.Printf("Received request: %s", string(body))

	// 在这里可以对请求体进行处理
	// ...

	// 如果需要响应内容,可以在这里写入响应体
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, "Request received successfully")
}

func main() {
	http.HandleFunc("/getrequest", getRequestHandler)

	log.Println("Starting server on port 20017...")
	err := http.ListenAndServe(":20017", nil)
	if err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}

然后执行 curl http://kong所在机器的公网IP:port/xxxx/hello\?1121312

:20017服务能够收到请求如下:

json 复制代码
{
	"service": {
		"retries": 5,
		"created_at": 1716538997,
		"updated_at": 1716551161,
		"write_timeout": 60000,
		"port": 58888,
		"name": "xxxxxxx",
		"protocol": "http",
		"connect_timeout": 60000,
		"read_timeout": 60000,
		"host": "111.222.222.111",
		"enabled": true,
		"ws_id": "7aa29e13-25cb-4920-992e-fe5b64576c21",
		"tags": ["xxxxx-test"],
		"id": "55bd77b4-b182-4e6b-87f1-a46608d27435"
	},
	"client_ip": "1.2.3.4",
	"route": {
		"created_at": 1716551271,
		"updated_at": 1716551271,
		"regex_priority": 0,
		"service": {
			"id": "55bd77b4-b182-4e6b-87f1-a46608d27435"
		},
		"paths": ["/xxxxx"],
		"name": "xxxxxxx123",
		"path_handling": "v0",
		"id": "8481a0d0-05c2-4631-89eb-19d9aad10642",
		"ws_id": "7aa29e13-25cb-4920-992e-fe5b64576c21",
		"protocols": ["http"],
		"strip_path": true,
		"preserve_host": false,
		"request_buffering": true,
		"response_buffering": true,
		"tags": [],
		"https_redirect_status_code": 426
	},
	"started_at": 1716555189008,
	"source": "upstream",
	"tries": [{
		"balancer_start": 1716555189008,
		"balancer_start_ns": 1.7165551890087e+18,
		"ip": "110.120.119.114",
		"balancer_latency": 0,
		"port": 58888,
		"balancer_latency_ns": 15616
	}],
	"response": {
		"size": 306,
		"status": 200,
		"headers": {
			"x-kong-request-id": "d32e6a5e11bec9085663513c9430565b",
			"date": "Fri, 24 May 2024 12:53:09 GMT",
			"via": "kong/3.6.1",
			"x-kong-proxy-latency": "0",
			"content-length": "41",
			"connection": "close",
			"x-kong-upstream-latency": "98",
			"content-type": "text/plain; charset=utf-8"
		}
	},
	"upstream_status": "200",
	"upstream_uri": "/hello",
	"latencies": {
		"kong": 0,
		"request": 98,
		"proxy": 98
	},
	"request": {
		"size": 94,
		"id": "d32e6a5e11bec9085663513c9430565b",
		"headers": {
			"user-agent": "curl/8.4.0",
			"host": "xxx.xxx.xxx.xxx:8000",
			"accept": "*/*"
		},
		"url": "http://xxxxxxxx:8000/xxxxx/hello",
		"querystring": {},
		"uri": "/xxxxx/hello",
		"method": "GET"
	}
}

但发现此时,request内容是比较详细的,但缺少response部分

参考 https://tech.aufomm.com/how-to-log-request-and-response-body-with-kong/

搜索Kong Functions (Pre-Plugins)插件,

并设置Access为: kong.log.set_serialize_value("request.body", kong.request.get_raw_body())

Body Filter为: kong.log.set_serialize_value("response.body", kong.response.get_raw_body())

再次执行 curl http://Kong所在机器公网IP:8000/xxxxx/hello\?1121312

此时就能获取到完整的response内容

本文由mdnice多平台发布

相关推荐
冲鸭ONE9 分钟前
for循环优化方式有哪些?
后端·性能优化
刘鹏37834 分钟前
深入浅出Java中的CAS:原理、源码与实战应用
后端
Lx35239 分钟前
《从头开始学java,一天一个知识点》之:循环结构:for与while循环的使用场景
java·后端
fliter39 分钟前
RKE1、K3S、RKE2 三大 Kubernetes 发行版的比较
后端
aloha_40 分钟前
mysql 某个客户端主机在短时间内发起了大量失败的连接请求时
后端
程序员爱钓鱼41 分钟前
Go 语言高效连接 SQL Server(MSSQL)数据库实战指南
后端·go·sql server
xjz184241 分钟前
Java AQS(AbstractQueuedSynchronizer)实现原理详解
后端
Victor35642 分钟前
Zookeeper(97)如何在Zookeeper中实现分布式协调?
后端
至暗时刻darkest42 分钟前
go mod文件 项目版本管理
开发语言·后端·golang
程序员爱钓鱼42 分钟前
Go 语言高效连接 MySQL 数据库:从入门到实战
后端·mysql·go