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

Refactoring #8

Open
wants to merge 5 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,6 @@ _testmain.go
sentinel_tunnel
log.txt
commit.txt

.idea/
sentinel_tunnel_configuration.json
32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,30 @@ For example, the following config file contains two Sentinel addresses and two d

```json
{
"Sentinels_addresses_list":[
"node1.local:8001",
"node2.local:8001"
],
"Databases":[
{
"Name":"db1",
"Local_port":"12345"
},
{
"Name":"db2",
"Local_port":"12346"
}
]
"sentinels": [
"127.0.0.1:26381",
"127.0.0.1:26382",
"127.0.0.1:26383"
],
"databases": [
{
"name": "my_redis_master",
"port": 36381
},
{
"name": "my_redis_master2",
"port": 36382
}
]
}
```

## Run
In order to run `sentinel_tunnel`:

```bash
$ ./sentinel_tunnel <config_file_path> <log_file_path>
$ ./sentinel_tunnel <config_file_path>
```
Set `log_file_path` to `/dev/null` for no logs.

## License

Expand Down
67 changes: 67 additions & 0 deletions build/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
version: '2.1'
services:

redis1:
image: redis:3.2-alpine
ports:
- 6381:6379
networks:
testnet:
ipv4_address: 172.22.1.10

sentinel1:
image: redis:3.2-alpine
ports:
- 26381:26379
volumes:
- ./sentinel1.conf:/etc/sentinel.conf
command: redis-server /etc/sentinel.conf --sentinel
networks:
testnet:
ipv4_address: 172.22.1.11

redis2:
image: redis:3.2-alpine
ports:
- 6382:6379
networks:
testnet:
ipv4_address: 172.22.1.20

sentinel2:
image: redis:3.2-alpine
ports:
- 26382:26379
volumes:
- ./sentinel2.conf:/etc/sentinel.conf
command: redis-server /etc/sentinel.conf --sentinel
networks:
testnet:
ipv4_address: 172.22.1.21

redis3:
image: redis:3.2-alpine
ports:
- 6383:6379
networks:
testnet:
ipv4_address: 172.22.1.30

sentinel3:
image: redis:3.2-alpine
ports:
- 26383:26379
volumes:
- ./sentinel3.conf:/etc/sentinel.conf
command: redis-server /etc/sentinel.conf --sentinel
networks:
testnet:
ipv4_address: 172.22.1.31

networks:
testnet:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.22.1.0/24
14 changes: 14 additions & 0 deletions build/sentinel1.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sentinel myid 6f45f9b7c4c2af2cb99cb00150dab6073b006918
sentinel monitor my_redis_master 172.22.1.30 6379 3
sentinel down-after-milliseconds my_redis_master 3000
sentinel failover-timeout my_redis_master 10000
# Generated by CONFIG REWRITE
port 26379
dir "/data"
sentinel config-epoch my_redis_master 4
sentinel leader-epoch my_redis_master 4
sentinel known-slave my_redis_master 172.22.1.10 6379
sentinel known-slave my_redis_master 172.22.1.20 6379
sentinel known-sentinel my_redis_master 172.22.1.21 26379 250456d4cda480fe092f2eeb5ca5dbc95fbe831d
sentinel known-sentinel my_redis_master 172.22.1.31 26379 d42bdac9dc1957e80284f454cc7731e96c432d11
sentinel current-epoch 4
14 changes: 14 additions & 0 deletions build/sentinel2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sentinel myid 250456d4cda480fe092f2eeb5ca5dbc95fbe831d
sentinel monitor my_redis_master 172.22.1.30 6379 3
sentinel down-after-milliseconds my_redis_master 3000
sentinel failover-timeout my_redis_master 10000
sentinel config-epoch my_redis_master 4
# Generated by CONFIG REWRITE
port 26379
dir "/data"
sentinel leader-epoch my_redis_master 4
sentinel known-slave my_redis_master 172.22.1.20 6379
sentinel known-slave my_redis_master 172.22.1.10 6379
sentinel known-sentinel my_redis_master 172.22.1.31 26379 d42bdac9dc1957e80284f454cc7731e96c432d11
sentinel known-sentinel my_redis_master 172.22.1.11 26379 6f45f9b7c4c2af2cb99cb00150dab6073b006918
sentinel current-epoch 4
14 changes: 14 additions & 0 deletions build/sentinel3.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
sentinel myid d42bdac9dc1957e80284f454cc7731e96c432d11
sentinel monitor my_redis_master 172.22.1.30 6379 3
sentinel down-after-milliseconds my_redis_master 3000
sentinel failover-timeout my_redis_master 10000
sentinel config-epoch my_redis_master 4
# Generated by CONFIG REWRITE
port 26379
dir "/data"
sentinel leader-epoch my_redis_master 4
sentinel known-slave my_redis_master 172.22.1.10 6379
sentinel known-slave my_redis_master 172.22.1.20 6379
sentinel known-sentinel my_redis_master 172.22.1.11 26379 6f45f9b7c4c2af2cb99cb00150dab6073b006918
sentinel known-sentinel my_redis_master 172.22.1.21 26379 250456d4cda480fe092f2eeb5ca5dbc95fbe831d
sentinel current-epoch 4
36 changes: 36 additions & 0 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package config

import (
"encoding/json"
"github.com/rs/zerolog/log"
"io/ioutil"
)

type Config struct {
Sentinels []string `json:"sentinels"`
Databases []*DatabaseConfig `json:"databases"`
}

type DatabaseConfig struct {
Name string `json:"name"`
Port uint16 `json:"port"`
}

func CreateFromFile(path string) (*Config, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
log.Error().Err(err).Msgf("read config file: %s", path)

return nil, err
}

conf := &Config{}
err = json.Unmarshal(b, conf)
if err != nil {
log.Error().Err(err).Msgf("parse config file: %s", path)

return nil, err
}

return conf, err
}
41 changes: 41 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"fmt"
"github.com/DivPro/sentinel_tunnel/cmd/config"
"github.com/DivPro/sentinel_tunnel/cmd/resolver"
"github.com/DivPro/sentinel_tunnel/cmd/server"
Comment on lines +5 to +7

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not the right package reference

"github.com/rs/zerolog/log"
"os"
)

func main() {
if len(os.Args) < 2 {
fmt.Println("usage : sentinel_tunnel <config_file_path>")
return
}

conf, err := config.CreateFromFile(os.Args[1])
if err != nil {
log.Fatal().Err(err).Msg("init config")
}

sentinels, err := resolver.CreateSentinels(conf.Sentinels)
if err != nil {
log.Fatal().Err(err).Msg("connect to sentinels")
}
srv := server.NewServer(
resolver.NewResolver(sentinels),
conf.Databases,
)
go func() {
err := srv.Start()
if err != nil {
log.Fatal().Err(err).Msg("starting server")
}
}()

ctx := server.GetShutdownCtx()
<-ctx.Done()
srv.Stop()
}
18 changes: 18 additions & 0 deletions cmd/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"fmt"
"github.com/go-redis/redis"
"testing"
"time"
)

func TestServer(t *testing.T) {
cl := redis.NewClient(&redis.Options{
Addr: "127.0.0.1:36381",
})
for {
fmt.Println(cl.Ping().String())
time.Sleep(time.Millisecond * 200)
}
}
33 changes: 33 additions & 0 deletions cmd/resolver/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package resolver

import (
"errors"
"github.com/go-redis/redis"
"github.com/rs/zerolog/log"
)

func CreateSentinels(addrs []string) ([]*redis.SentinelClient, error) {
sentinels := make([]*redis.SentinelClient, 0, len(addrs))
for _, addr := range addrs {
sentinel, err := createSentinel(addr)
if err != nil {
continue
}
sentinels = append(sentinels, sentinel)
}
if len(sentinels) == 0 {
return nil, errors.New("error connecting to all sentinels")
}

return sentinels, nil
}

func createSentinel(addr string) (*redis.SentinelClient, error) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's impossible to return an error here, maybe remove the last return argument

sentinel := redis.NewSentinelClient(&redis.Options{
Addr: addr,
})

log.Debug().Msgf("connected to sentinel: %s", addr)

return sentinel, nil
}
37 changes: 37 additions & 0 deletions cmd/resolver/resolver.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package resolver

import (
"github.com/go-redis/redis"
"github.com/pkg/errors"
"github.com/rs/zerolog/log"
"strings"
)

type Resolver interface {
Resolve(dbName string) (string, error)
}

type resolver struct {
sentinels []*redis.SentinelClient
}

func NewResolver(sentinels []*redis.SentinelClient) Resolver {
return &resolver{sentinels: sentinels}
}

func (r *resolver) Resolve(dbName string) (string, error) {
for _, sentinel := range r.sentinels {
result, err := sentinel.GetMasterAddrByName(dbName).Result()
if err != nil {
continue
}

ip := strings.Join(result, ":")

log.Info().Msgf("'%s' resolved to master: %s", dbName, ip)

return ip, nil
}

return "", errors.New("all sentinels failed")
}
Loading