다음 칼럼에서는 Golangtutorial 칼럼에서 Golang으로 간단한 API 게이트웨이를 구현하는 방법을 소개하겠습니다. 필요한 친구들에게 도움이 되길 바랍니다!
최근 프로젝트에서는 백엔드 개발에 마이크로서비스 아키텍처인 go-kit
을 사용했습니다. 마이크로서비스 아키텍처 스타일에서는 대규모 애플리케이션이 여러 개의 소규모 서비스 시스템으로 분할됩니다. 이러한 소규모 시스템은 자체 시스템을 구성할 수 있습니다. 이는 이러한 소규모 시스템이 자체 데이터베이스, 프레임워크, 심지어 언어까지 가질 수 있음을 의미합니다. 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即可,一个简单的反向代理就完成了啦。
实例代码只涉及微服务中
실제로 인터넷에는 기성 구현 프레임워크가 많이 있지만 이 프로젝트의 요구 사항은 비교적 간단하므로user
与auth
API 게이트웨이(API Gataway)Golang
을 사용하여 구현하겠습니다. 우리 스스로.
API 게이트웨이는 서버이자 시스템에 대한 유일한 입구입니다. 객체지향 디자인 관점에서는 파사드 패턴과 유사합니다. API 게이트웨이는 시스템의 내부 아키텍처를 캡슐화하고 각 클라이언트에 대해 맞춤형 API를 제공합니다. 또한 인증, 모니터링, 로드 밸런싱, 캐싱, 요청 샤딩 및 관리, 정적 응답 처리와 같은 다른 책임도 가질 수 있습니다. 🎜🎜🎜API 게이트웨이를 구현하는 데 사용되는 많은 기술이 있으며 대략 다음 범주로 나뉩니다. 🎜🎜API 게이트웨이의 가장 기본적인 기능은 역방향 프록시입니다. 이를 구현하는 방법은 다양합니다. 이 기사에서는 표준 라이브러리
- 일반 역방향 프록시:
Nginx
,Haproxy
, ...- 네트워크 프로그래밍 프레임워크:
Netty
,Servlet
, ...- API 게이트웨이 프레임워크:
Spring Cloud Gateway
,Zuul
,Zuul2
,...net/http/httputil
패키지의ReverseProxy
유형을 기반으로 간단한 역방향 프록시를 구현합니다. 역방향 프록시 구현에는 주로func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy
및type 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()}로그인 후 복사NewSingleHostReverseProxy
는URL
요청을 지정된의 <code>target
체계ReverseProxy를 반환합니다. /code>,호스트
,기본 경로
. 🎜rrreee🎜ReverseProxy
유형에는Director
및ModifyResponse
라는 두 가지 중요한 속성이 있습니다. 두 속성 모두 클라이언트가 수신할 때 함수 유형입니다. 요청이 있으면ServeHTTP
함수는 먼저Director
함수를 호출하여 요청의 대상 주소, 요청 헤더 등을 수정하는 등 수신된 요청 본문을 수정합니다. 수정된 요청을 사용합니다. 본문은 응답을 받은 후ModifyResponse
함수를 호출하여 응답을 수정합니다. 마지막으로 수정된 응답 본문이 복사되어 클라이언트에 응답됩니다. 전체 역방향 프록시 프로세스. 🎜🎜NewSingleHostReverseProxy
에서 소스 코드는 수신URL
을 구문 분석하고Director
수정을 완료했습니다.NewSingleHostReverseProxy만 호출하면 됩니다.
함수에 대상 서버의 URL을 전달하면 간단한 역방향 프록시가 완성됩니다. 🎜코드
🎜예제 코드에는 마이크로서비스의user
및auth
모듈만 포함됩니다. 실제에 따라 일부를 수정할 수 있습니다. 필요🎜🎜rrreee🎜위 내용은 Golang에서 간단한 API 게이트웨이를 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!