In der folgenden Kolumne erfahren Sie, wie Sie ein einfaches API-Gateway in Golang aus der Kolumne GolangTutorial implementieren. Ich hoffe, dass es für Freunde hilfreich ist, die es brauchen!
In einem aktuellen Projekt wurde das Microservice-Architektur-go-kit
für die Backend-Entwicklung verwendet. Im Microservice-Architekturstil wird eine große Anwendung in mehrere kleine Servicesysteme aufgeteilt, was bedeutet, dass diese kleinen Systeme ihre eigenen Datenbanken, Frameworks und sogar Sprachen haben können go-kit
进行后端的开发。在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,因此我们需要设计一个API 网关(API Gataway),其实网上已经有较多现成的实现框架,但是本项目的需求是比较简单的,因此将使用Golang
自行实现。
API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。
用于实现API网关的技术有很多,大致分为这么几类:
Nginx
、Haproxy
、……Netty
、Servlet
、……Spring Cloud Gateway
、Zuul
、Zuul2
、……API网关最基本的功能就是反向代理。其实现方式有很多,本文将基于标准库net/http/httputil
包中的ReverseProxy
类型来实现实现一个简单的反向代理。反向代理的实现主要涉及到func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
和type ReverseProxy
。
func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
// NewSingleHostReverseProxy returns a new ReverseProxy that routes// URLs to the scheme, host, and base path provided in target. If the// target's path is "/base" and the incoming request was for "/dir",// the target request will be for /base/dir.// NewSingleHostReverseProxy does not rewrite the Host header.// To rewrite Host headers, use ReverseProxy directly with a custom// Director policy.func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy { targetQuery := target.RawQuery director := func(req *http.Request) { req.URL.Scheme = target.Scheme req.URL.Host = target.Host req.URL.Path = singleJoiningSlash(target.Path, req.URL.Path) if targetQuery == "" || req.URL.RawQuery == "" { req.URL.RawQuery = targetQuery + req.URL.RawQuery } else { req.URL.RawQuery = targetQuery + "&" + req.URL.RawQuery } if _, ok := req.Header["User-Agent"]; !ok { // explicitly disable User-Agent so it's not set to default value req.Header.Set("User-Agent", "") } } return &ReverseProxy{Director: director}}
NewSingleHostReverseProxy
返回一个新的ReverseProxy
,将URLs
请求路由到targe
的指定的scheme
, host
, base path
。
// ReverseProxy is an HTTP Handler that takes an incoming request and// sends it to another server, proxying the response back to the// client.type ReverseProxy struct { // Director must be a function which modifies // the request into a new request to be sent // using Transport. Its response is then copied // back to the original client unmodified. // Director must not access the provided Request // after returning. Director func(*http.Request) Transport http.RoundTripper FlushInterval time.Duration ErrorLog *log.Logger BufferPool BufferPool // ModifyResponse is an optional function that modifies the // Response from the backend. It is called if the backend // returns a response at all, with any HTTP status code. // If the backend is unreachable, the optional ErrorHandler is // called without any call to ModifyResponse. // // If ModifyResponse returns an error, ErrorHandler is called // with its error value. If ErrorHandler is nil, its default // implementation is used. ModifyResponse func(*http.Response) error ErrorHandler func(http.ResponseWriter, *http.Request, error)}
ReverseProxy
类型有两个重要的属性,分别是Director
和ModifyResponse
,这两个属性都是函数类型,在接收到客户端请求时,ServeHTTP
函数首先调用Director
函数对接受到的请求体进行修改,例如修改请求的目标地址、请求头等;然后使用修改后的请求体发起新的请求,接收到响应后,调用ModifyResponse
函数对响应进行修改,最后将修改后的响应体拷贝并响应给客户端,这样就实现了反向代理的整个流程。
在NewSingleHostReverseProxy
中源码已经对传入的URLs
进行解析并且完成了Director
的修改,我们只需要调用NewSingleHostReverseProxy
函数并且传入目标服务器的URL即可,一个简单的反向代理就完成了啦。
实例代码只涉及微服务中
Tatsächlich gibt es im Internet viele vorgefertigte Implementierungsframeworks, aber die Anforderungen dieses Projekts sind relativ einfach, daher verwenden wiruser
与auth
API Gateway (API Gataway)Golang
, um es zu implementieren uns.
Das API-Gateway ist ein Server und der einzige Zugang zum System. Aus objektorientierter Gestaltungsperspektive ähnelt es dem Fassadenmuster. Das API-Gateway kapselt die interne Architektur des Systems und stellt für jeden Client eine angepasste API bereit. Es kann auch andere Aufgaben wie Authentifizierung, Überwachung, Lastausgleich, Caching, Anforderungs-Sharding und -Verwaltung sowie statische Antwortverarbeitung übernehmen. 🎜🎜🎜Es gibt viele Technologien, die zur Implementierung von API-Gateways verwendet werden, die grob in die folgenden Kategorien unterteilt werden: 🎜🎜Die grundlegendste Funktion des API-Gateways ist der Reverse-Proxy. Es gibt viele Möglichkeiten, es zu implementieren. In diesem Artikel wird ein einfacher Reverse-Proxy basierend auf dem Typ
- Allgemeiner Reverse-Proxy:
Nginx
,Haproxy
, ...- Netzwerkprogrammier-Framework:
Netty
,Servlet
, ...- API-Gateway-Framework:
Spring Cloud Gateway
,Zuul
,Zuul2
,...ReverseProxy
im Paket der Standardbibliotheknet/http/httputil
implementiert. Die Implementierung des Reverse-Proxy umfasst hauptsächlichfunc NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
undtype ReverseProxy
. 🎜rrreee🎜package mainimport ( "fmt" "log" "net/http" "net/http/httputil" "net/url" "strings")type handle struct { host string port string}type Service struct { auth *handle user *handle}func (this *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { var remote *url.URL if strings.Contains(r.RequestURI, "api/auth") { remote, _ = url.Parse("http://" + this.auth.host + ":" + this.auth.port) } else if strings.Contains(r.RequestURI, "api/user") { remote, _ = url.Parse("http://" + this.user.host + ":" + this.user.port) } else { fmt.Fprintf(w, "404 Not Found") return } proxy := httputil.NewSingleHostReverseProxy(remote) proxy.ServeHTTP(w, r)}func startServer() { // 注册被代理的服务器 (host, port) service := &Service{ auth: &handle{host: "127.0.0.1", port: "8081"}, user: &handle{host: "127.0.0.1", port: "8082"}, } err := http.ListenAndServe(":8888", service) if err != nil { log.Fatalln("ListenAndServe: ", err) }}func main() { startServer()}Nach dem Login kopierenNewSingleHostReverseProxy
gibt einen neuenReverseProxy
zurück, derURLs
-Anfragen an den angegebenendes <code>target
-Schemas,host
,base path
. 🎜rrreee🎜Der TypReverseProxy
hat zwei wichtige Attribute, nämlichDirector
undModifyResponse
. Beim Empfang handelt es sich um einen Bei einer Anfrage ruft die FunktionServeHTTP
zunächst die FunktionDirector
auf, um den empfangenen Anforderungstext zu ändern, z. B. die Zieladresse der Anforderung, den Anforderungsheader usw. und dann verwendet den geänderten Anforderungstext. Nach Erhalt der Antwort wird die FunktionModifyResponse
aufgerufen, um die Antwort zu ändern. Anschließend wird der geänderte Antworttext kopiert und dem Client geantwortet gesamten Reverse-Proxy-Prozess. 🎜🎜InNewSingleHostReverseProxy
hat der Quellcode die eingehendenURLs
analysiert und die Änderung vonDirector
abgeschlossen. Wir müssen nurNewSingleHostReverseProxy aufrufen
-Funktion verwenden und die URL des Zielservers übergeben, ist ein einfacher Reverse-Proxy abgeschlossen. 🎜Code
🎜Der Beispielcode betrifft nur die Moduleuser
undauth
im Microservice. Sie können einige davon entsprechend den tatsächlichen Anforderungen ändern Bedürfnisse🎜🎜rrreee🎜Das obige ist der detaillierte Inhalt vonSo implementieren Sie ein einfaches API-Gateway in Golang. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!