Rumah >pembangunan bahagian belakang >Golang >Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD
editor php Baicao hari ini memperkenalkan kepada anda masalah biasa dalam pembangunan pemalam KrakenD: "Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD". KrakenD ialah gerbang API yang pantas dan berprestasi tinggi yang menyediakan fungsi yang kaya dan sistem pemalam yang fleksibel. Walau bagaimanapun, apabila membangunkan pemalam KrakenD, anda kadangkala menghadapi masalah jenis nod tidak sah, yang mungkin menyebabkan pemalam gagal berfungsi dengan betul. Dalam artikel ini, kami akan meneroka punca masalah ini serta penyelesaian untuk membantu pembangun mengatasi panik ini.
Saya sedang membangunkan pemalam tanpa ubah hala. Saya menggunakan krakend-ce 2.2.1 (menggunakan golang 1.19) dan saya panik:
gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.675 ? debug no_redirect_plugin: request received https://127.0.0.1:8443/abc gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.689 ? debug no_redirect_plugin: redirect detected https://127.0.0.1:8443/abc gw_krakend_1 | [krakend] 2023/03/15 - 21:09:06.689 ? debug status code 302 gw_krakend_1 | 2023/03/15 21:09:06 http: panic serving [::1]:54778: invalid node type gw_krakend_1 | goroutine 84 [running]: gw_krakend_1 | net/http.(*conn).serve.func1() gw_krakend_1 | /usr/local/go/src/net/http/server.go:1854 +0xbf gw_krakend_1 | panic({0x28cbb60, 0x34b5810}) gw_krakend_1 | /usr/local/go/src/runtime/panic.go:890 +0x263 gw_krakend_1 | github.com/gin-gonic/gin.(*node).findcaseinsensitivepathrec(0x0?, {0xc0016ac2ec?, 0x0?}, {0xc0010fe800?, 0xc0016ac2ed?, 0xc000ced928?}, {0x0, 0x0, 0x0, 0x0}, ...) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:862 +0xa9d gw_krakend_1 | github.com/gin-gonic/gin.(*node).findcaseinsensitivepath(0xc0016ac2ec?, {0xc0016ac2ec, 0x5}, 0x30?) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/tree.go:669 +0x9c gw_krakend_1 | github.com/gin-gonic/gin.redirectfixedpath(0xc000664300, 0xc0016ac2ec?, 0x60?) gw_krakend_1 | /go/pkg/mod/github.com/gin-gonic/[email protected]/gin.go:684 +0x5b gw_krakend_1 | github.com/gin-gonic/gin.(*engine).handlehttprequest(0xc000602b60, 0xc000664300)
Kelihatan serupa dengannya https://github.com/gin-gonic/gin/issues/2959, tetapi versi gin telah dinaik taraf pada versi krakend sebelumnya. Ia akan menjadi pelik jika ia benar-benar huruf besar, ia berfungsi dengan sempurna tanpa pemalam. Saya juga memangkas yang terakhir / (ia telah ditambah pada satu ketika atas sebab tertentu)
BTW, saya menggunakan versi krakend yang sama untuk menyusun pemalam.
package main import ( "context" "errors" "fmt" "io" "net/http" "net/url" "strings" ) func main() {} var clientregisterer = registerer("no_redirect_plugin") type registerer string type logger interface { debug(v ...interface{}) info(v ...interface{}) warning(v ...interface{}) error(v ...interface{}) critical(v ...interface{}) fatal(v ...interface{}) } var logger logger = nil func (registerer) registerlogger(v interface{}) { l, ok := v.(logger) if !ok { return } logger = l logger.info(fmt.sprintf("[plugin: %s] logger loaded", clientregisterer)) } func (r registerer) registerclients(f func( name string, handler func(context.context, map[string]interface{}) (http.handler, error), )) { f(string(r), r.registerclients) } func (r registerer) registerclients(_ context.context, extra map[string]interface{}) (http.handler, error) { name, ok := extra["name"].(string) if !ok { return nil, errors.new("wrong config") } if name != string(r) { return nil, fmt.errorf("unknown register %s", name) } httpclient := &http.client{ checkredirect: func(req *http.request, via []*http.request) error { // trim the last "/" character from the url if it exists urlstr := strings.trimright(req.url.string(), "/") req.url, _ = url.parse(urlstr) logger.debug("no_redirect_plugin: redirect detected", req.url.string()) return http.erruselastresponse }, } return http.handlerfunc(func(w http.responsewriter, req *http.request) { // trim the last "/" character from the url if it exists urlstr := strings.trimright(req.url.string(), "/") req.url, _ = url.parse(urlstr) logger.debug("no_redirect_plugin: request received", req.url.string()) resp, err := httpclient.do(req) if err != nil { logger.debug("error while proxying request", err.error()) http.error(w, err.error(), http.statusinternalservererror) return } defer resp.body.close() for k, hs := range resp.header { for _, h := range hs { w.header().add(k, h) } } w.writeheader(resp.statuscode) logger.debug("status code", resp.statuscode) if resp.body == nil { return } _, err = io.copy(w, resp.body) if err != nil { logger.debug("error while proxying request 2", err.error()) http.error(w, err.error(), http.statusinternalservererror) return } }), nil }
Titik akhir saya ditakrifkan seperti berikut:
{ "endpoint": "/", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": {}, "backend": [{ "url_pattern": "", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] },{ "endpoint": "/{level1}", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": { }, "backend": [{ "url_pattern": "/{level1}", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] },{ "endpoint": "/{level1}/{level2}", "input_headers":[ "*" ], "input_query_strings":[ "*" ], "method": "GET", "output_encoding": "no-op", "extra_config": { }, "backend": [{ "url_pattern": "/{level1}/{level2}", "encoding": "no-op", "sd": "static", "method": "GET", "extra_config": { "plugin/http-client": { "name": "no_redirect_plugin" } }, "host": [ "{{ env "HOST" }}" ], "disable_host_sanitize": false }] }
EDIT: Penyemak imbas saya masih menunjukkan /abc/ bukannya /abc, yang boleh mewujudkan kemungkinan perlanggaran antara laluan (seperti yang dilihat di sini: https://github.com/krakendio/krakend-ce/issues/386 ) Bagaimanapun, saya tidak tahu di mana untuk menambah garis miring (saya fikir saya memangkasnya secara kekal...nampaknya saya tidak melakukannya)
edit2: Saya menjumpai ini https://www.krakend.io/docs/service-settings/router-options/ dan menggunakan "disable_redirect_fixed_path": benar dan "disable_redirect_trailing_slash": benar, ia tidak panik lagi... Sekarang saya mempunyai masalah lain: ubah hala tidak terhingga (hanya 10 bergurau sahaja) apabila batu saya cuba mengubah hala ke /a/ atau apa-apa sahaja dengan laluan slash mengekor, ini dalam pemalam kerana krakend pernah mengendalikan ubah hala dengan cara tersendiri...
Saya rasa masalah utama di sini ialah konflik penghalaan, apabila /{level1} dan /{level1}/{level2} sepadan dengan /abc/ pada masa yang sama
Idea?
bagus, untuk menyelesaikan masalah ini, saya cuba mencipta pemalam wildcard+no_redirect menggunakan ini https://www.php.cn/link/ba530cdf0a884348613f2aaa3a5ba5e8, tetapi saya gagal konfigurasi, tetapi saya gagal untuk mencapai ini. Jadi saya menyelesaikan masalah dengan cara lain: Saya meletakkan gerbang di hadapan batu besar saya dan setiap kali permintaan gagal saya menambah laluan... kerana kami tidak mempunyai laluan log (* menangis). Ia berfungsi dengan baik untuk fail yang memerlukan pemalam tanpa ubah hala. Penyelesaian yang hebat tetapi ia telah berjaya setakat ini dan tidak seperti yang saya fikirkan
Atas ialah kandungan terperinci Panik jenis nod tidak sah apabila melaksanakan pemalam untuk KrakenD. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!