Giter Site home page Giter Site logo

ozontech / http-ringpop Goto Github PK

View Code? Open in Web Editor NEW
16.0 8.0 1.0 27 KB

HTTP ringpop makes it easy to transform your HTTP API to distributed application

License: Apache License 2.0

Dockerfile 0.61% Makefile 3.61% Go 95.79%
ringpop proxy sidecar distributed-systems load-balancing reverse-proxy

http-ringpop's Introduction

Ringpop sidecar for HTTP backend

Overview

Maintenance

http-ringpop is a small reverse-proxy that makes it easy to shard incoming requests across multiple backends. You decide what sharding logic you need.

Motivation

Initial issue - spread out incoming HTTP requests from different clients between different instances of application. Requests from one client should be handled on the same backend.

Features

  • http-ringpop works as a proxy (sidecar) in front of your HTTP backend instance
  • when it receives request - it decides what backend instance should handle this request (based on incoming IP)
  • if request should be hanlded on local backend - it forwards request to it.
  • if request should be hanlded on another instance - it forwards request to its ringpop sidecar.

Ringpop sidecar for HTTP backend could be useful if you already have HTTP backend, but you need to add sharding / caching / data aggregation.
Ringpop will take ownership of the scalability and availability.

Requests forwarding based on ringpop approach with gossip under the hood.

This application is based on Uber's Ringpop.

                          ┌───────────┐                         
                          │   Client  │                         
                          └───────────┘                         
                                │                               
         ┌──────────────────────┼──────────────────────┐        
         │                      │                      │        
         ▼                      ▼                      ▼        
┌────────────────┐     ┌────────────────┐     ┌────────────────┐
│  HTTP Ringpop  │◀───▶│  HTTP Ringpop  │◀───▶│  HTTP Ringpop  │
└────────────────┘     └────────────────┘     └────────────────┘
         │                      │                      │        
         │                      │                      │        
         ▼                      ▼                      ▼        
┌────────────────┐     ┌────────────────┐     ┌────────────────┐
│  HTTP Backend  │     │  HTTP Backend  │     │  HTTP Backend  │
│     shard 1    │     │     shard 2    │     │     shard 3    │
└────────────────┘     └────────────────┘     └────────────────┘

Quick start

Build

go build -o simple-backend cmd/backend-example/main.go
go build -o ringpop cmd/ringpop/main.go

Run 3 HTTP backends:

./simple-backend --listen.http=:4000
./simple-backend --listen.http=:4001
./simple-backend --listen.http=:4002

Run ringpop on 3 nodes locally:

./ringpop --listen.http="127.0.0.1:3000" --backend.url="http://127.0.0.1:4000/" --listen.ringpop="127.0.0.1:5000" --listen.debug=":6000" --discovery.json.file=./etc/hosts.json
./ringpop --listen.http="127.0.0.1:3001" --backend.url="http://127.0.0.1:4001/" --listen.ringpop="127.0.0.1:5001" --listen.debug=":6001" --discovery.json.file=./etc/hosts.json
./ringpop --listen.http="127.0.0.1:3002" --backend.url="http://127.0.0.1:4002/" --listen.ringpop="127.0.0.1:5002" --listen.debug=":6002" --discovery.json.file=./etc/hosts.json

Test

curl http://localhost:3000/ -i

You will see something like that (request received by one instance but handled by another):

HTTP/1.1 200 OK
Content-Length: 50
Content-Type: text/plain; charset=utf-8
X-Ringpop-Handled-By: 127.0.0.1:5002
X-Ringpop-Received-By: 127.0.0.1:5000

Ringpop over Kubernetes

You can find out examples in k8s directory.

If you're running ringpop over Kubernetes note following thing: each instance have to know on what real IP it's running (its critical). For example, when instances will be discovered from DNS records, it will be something like this: 10.27.27.42:5000 10.27.35.133:5000 Current IP could be detected correctly only in particular cases. So, if current IP will be detected automatically as 127.0.0.1 this node will try to join to itself.

Also, one important thing is that you should use ClusterIP: none for service, that will be used for DNS discovery, because in this case nslookup myawesomeservice will return list of A-records for all service endpoints.

Build & test

make test
make build
docker build -t http-ringpop:1.0.0 .

Pre-built image on Dockerhub: ozontech/http-ringpop:1.0.0

Flags

Flags:
      --listen.http= ...         hostPort to listen calls from incoming 
                                 http requests. By default ":3000".
      --backend.url= ...         URL of your http backend.
                                 By default "http://127.0.0.1:4000/".
      --listen.ringpop= ...      hostPort to listen gossip requests inside 
                                 hashring. By default ":5000".
      --listen.debug= ...        hostPort to listen calls from incoming debug 
                                 http requests (metrics, etc.).
                                 By default ":6000".
      --log.level= ...           Log level, by default - INFO (4).
      --discovery.json.file= ... Discovery hosts from static file.
      --discovery.dns.host= ...  Discovery hosts from DNS by hostname.
      --discovery.dns.port= ...  Ringpop port that will be added to discovered 
                                 hosts from DNS.

License

APACHE LICENSE, VERSION 2.0

http-ringpop's People

Contributors

mkabischev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

thanhlam2410

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.