Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3.0 branch #8

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v5

- uses: actions/setup-go@v5
with:
Expand Down Expand Up @@ -40,7 +40,7 @@ jobs:
comment-on-alert: true

- name: Save benchmark JSON to cache
uses: actions/cache/save@v4
uses: actions/cache/save@v5
with:
path: ./cache/benchmark-data.json
# Save with commit hash to avoid "cache already exists"
Expand Down
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ $(GOLANGCI_LINT): ## Download Go linter
lint: $(GOLANGCI_LINT) ## Run Go linter
$(GOLANGCI_LINT) run -v -c .golangci.yml ./...

.PHONY: tidy
tidy:
go mod tidy && git diff --exit-code

.PHONY: validate
validate: tidy lint test bench
@echo
@echo "\033[32mEVERYTHING PASSED!\033[0m"

.PHONY: test
test: ## Run unit tests and measure code coverage
(go test -v -race -p=1 -count=1 -tags holster_test_mode -coverprofile coverage.out ./...; ret=$$?; \
Expand All @@ -24,7 +33,7 @@ test: ## Run unit tests and measure code coverage

.PHONY: bench
bench: ## Run Go benchmarks
go test ./... -bench . -benchtime 5s -timeout 0 -run='^$$' -benchmem
go test ./... -bench . -timeout 6m -run='^$$' -benchmem

.PHONY: docker
docker: ## Build Docker image
Expand All @@ -45,7 +54,6 @@ clean-proto: ## Clean the generated source files from the protobuf sources
@find . -name "*.pb.go" -type f -delete
@find . -name "*.pb.*.go" -type f -delete


.PHONY: proto
proto: ## Build protos
./buf.gen.yaml
Expand Down
52 changes: 15 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ Gubernator is a distributed, high performance, cloud native and stateless rate-l
kubernetes or nomad trivial.
* Gubernator holds no state on disk, It’s configuration is passed to it by the
client on a per-request basis.
* Gubernator provides both GRPC and HTTP access to the API.
* It Can be run as a sidecar to services that need rate limiting or as a separate service.
* It Can be used as a library to implement a domain-specific rate limiting service.
* Supports optional eventually consistent rate limit distribution for extremely
Expand All @@ -38,8 +37,10 @@ $ docker-compose up -d
```
Now you can make rate limit requests via CURL
```
# Hit the HTTP API at localhost:9080 (GRPC is at 9081)
$ curl http://localhost:9080/v1/HealthCheck
# Hit the HTTP API at localhost:9080
$ curl http://localhost:9080/v1/health.check

# TODO: Update this example

# Make a rate limit request
$ curl http://localhost:9080/v1/GetRateLimits \
Expand All @@ -59,7 +60,7 @@ $ curl http://localhost:9080/v1/GetRateLimits \

### ProtoBuf Structure

An example rate limit request sent via GRPC might look like the following
An example rate limit request sent with protobuf might look like the following
```yaml
rate_limits:
# Scopes the request to a specific rate limit
Expand Down Expand Up @@ -214,7 +215,7 @@ limiting service.

When you use the library, your service becomes a full member of the cluster
participating in the same consistent hashing and caching as a stand alone
Gubernator server would. All you need to do is provide the GRPC server instance
Gubernator server would. All you need to do is provide the server instance
and tell Gubernator where the peers in your cluster are located. The
`cmd/gubernator/main.go` is a great example of how to use Gubernator as a
library.
Expand All @@ -238,21 +239,13 @@ to support rate limit durations longer than a minute, day or month, calls to
those rate limits that have durations over a self determined limit.

### API
All methods are accessed via GRPC but are also exposed via HTTP using the
[GRPC Gateway](https://github.com/grpc-ecosystem/grpc-gateway)

#### Health Check
Health check returns `unhealthy` in the event a peer is reported by etcd or kubernetes
as `up` but the server instance is unable to contact that peer via it's advertised address.

###### GRPC
```grpc
rpc HealthCheck (HealthCheckReq) returns (HealthCheckResp)
```

###### HTTP
```
GET /v1/HealthCheck
GET /v1/health.check
```

Example response:
Expand All @@ -269,14 +262,8 @@ Rate limits can be applied or retrieved using this interface. If the client
makes a request to the server with `hits: 0` then current state of the rate
limit is retrieved but not incremented.

###### GRPC
```grpc
rpc GetRateLimits (GetRateLimitsReq) returns (GetRateLimitsResp)
```

###### HTTP
```
POST /v1/GetRateLimits
POST /v1/rate-limit.check
```

Example Payload
Expand All @@ -285,7 +272,7 @@ Example Payload
"requests": [
{
"name": "requests_per_sec",
"uniqueKey": "account:12345",
"unique_key": "account:12345",
"hits": "1",
"limit": "10",
"duration": "1000"
Expand Down Expand Up @@ -314,20 +301,10 @@ Example response:
```

### Deployment
NOTE: Gubernator uses `etcd`, Kubernetes or round-robin DNS to discover peers and
NOTE: Gubernator uses `memberlist` Kubernetes or round-robin DNS to discover peers and
establish a cluster. If you don't have either, the docker-compose method is the
simplest way to try gubernator out.


##### Docker with existing etcd cluster
```bash
$ docker run -p 8081:81 -p 9080:80 -e GUBER_ETCD_ENDPOINTS=etcd1:2379,etcd2:2379 \
ghcr.io/gubernator-io/gubernator:latest

# Hit the HTTP API at localhost:9080
$ curl http://localhost:9080/v1/HealthCheck
```

##### Kubernetes
```bash
# Download the kubernetes deployment spec
Expand All @@ -346,14 +323,15 @@ you can use same fully-qualified domain name to both let your business logic con
instances to find `gubernator` and for `gubernator` containers/instances to find each other.

##### TLS
Gubernator supports TLS for both HTTP and GRPC connections. You can see an example with
self signed certs by running `docker-compose-tls.yaml`
Gubernator supports TLS. You can see an example with self-signed certs by running
`docker-compose-tls.yaml`
```bash
# Run docker compose
$ docker-compose -f docker-compose-tls.yaml up -d

# Hit the HTTP API at localhost:9080 (GRPC is at 9081)
$ curl --cacert certs/ca.cert --cert certs/gubernator.pem --key certs/gubernator.key https://localhost:9080/v1/HealthCheck
# Hit the HTTP API at localhost:9080
+$ curl -X POST --cacert certs/ca.cert --cert certs/gubernator.pem \
--key certs/gubernator.key https://localhost:9080/v1/health.check
```

### Configuration
Expand Down
Loading
Loading