It is a Golang implementation of Crank4j, which derived from Cranker. the follow introduction is quoted from the origin project:
It consists of 2 executables that together act as a reverse proxy. What it allows is for cases where there is a firewall between your inside network and a DMZ zone.
For a normal reverse proxy, a port would need to be open allowing traffic from the DMZ to the internal network. Crank4j allows you to reverse this: Just open a port from the internal network to the DMZ, and Crank4j will tunnel HTTP traffic over the opened network.
So there are two pieces:
- The router that faces the internet, and accepts client HTTP requests
- The connector that opens connections to the router, and then passes tunneled requests to target servers.
The connections look like this:
Browser | DMZ | Internal Network
GET --------> router <-------- connector ---> HTTP Service
| |
But from the point of view of the browser, and your HTTP service, it just looks like a normal reverse proxy.
this 2 picture are quoted from Cranker
Websockets with cranker:
- go mod tidy
- open
test/e2etest/dryrun_router_test.go
run the test and a router will be started - open
test/e2etest/connector_manual_test.go
, a connector and a web-service will be started and connector to the router - open
https://localhost:9000
in your browser , it is the side facing to usershttps://localhost:9070/api/registrations
shows the registration status of routerhttp://0.0.0.0:12439/health
shows the health status of router
go get -v github.com/torchcc/crank4go
- create a web-service with a path prefix (context-path concept in java) e.g.
/my-service/...
- start the web-service listening on a random port
- register your web server with one or more routers:
package main
import (
"fmt"
. "github.com/torchcc/crank4go/connector"
"net/http"
"net/url"
)
func HelloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello Crank4go")
}
func main() {
targetURI, _ := url.Parse("http://localhost:5000")
routerURI, _ := url.Parse("wss://localhost:9070") // should be the port which your Router Registration server listens on
connectorConfig := NewConnectorConfig2(targetURI, "my-service", []*url.URL{routerURI}, "my-service-component-name", nil).
SetSlidingWindowSize(2)
_ = CreateAndStartConnector(connectorConfig)
http.HandleFunc("/my-service", HelloHandler)
http.ListenAndServe(":5000", nil)
// and then you can query your api gateway to access your service.
// e.g. if your router listens on https://localhost:9000, then you can access https://localhost:9000/my-service
}
- here is example of deploying the API Gateway crank4go router
- if you want more functionalities, you might want to refer to
crank4go/test/e2etest/cranker_with_all_extention_single_service_test.go
-
Less dependencies: only use 4 (all of which are quite small and light ):
google/uuid
,gorilla/websocket
,julienschmidt/httprouter
,op/go-logging
-
Horizontally scalable architecture:
we can deploy multiple Router instance on the loadBalancer side. Each web-service can be registered to multiple router -
Multi-language supported: communication between router and connector is through websocket, so apart from crank4go-connector, other connectors written by other language can also be registered to Go-router. such as
- java
- python (making it convenient to play micro-service with python)
- java script
-
Hooks supported: hooks are preset in the form of plugin and interceptor to monitor the connection activity of router and connector.
- add request rate control plugin.