synapse 0.2.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.mailmap +3 -0
- data/LICENSE.txt +2 -2
- data/Makefile +6 -0
- data/README.md +42 -13
- data/bin/synapse +29 -21
- data/config/hostheader_test.json +71 -0
- data/config/svcdir_test.json +46 -0
- data/config/synapse.conf.json +26 -32
- data/config/synapse_services/service1.json +24 -0
- data/config/synapse_services/service2.json +24 -0
- data/lib/synapse.rb +39 -24
- data/lib/synapse/base.rb +1 -1
- data/lib/synapse/haproxy.rb +579 -22
- data/lib/synapse/log.rb +24 -0
- data/lib/synapse/service_watcher.rb +10 -6
- data/lib/synapse/service_watcher/base.rb +33 -11
- data/lib/synapse/service_watcher/dns.rb +28 -20
- data/lib/synapse/service_watcher/docker.rb +108 -0
- data/lib/synapse/service_watcher/ec2tag.rb +1 -1
- data/lib/synapse/service_watcher/zookeeper.rb +25 -28
- data/lib/synapse/version.rb +1 -1
- data/spec/spec_helper.rb +2 -2
- data/synapse.gemspec +2 -3
- metadata +15 -25
- data/Vagrantfile +0 -112
- data/chef/converge +0 -4
- data/chef/cookbooks/lxc/recipes/default.rb +0 -2
- data/chef/cookbooks/synapse/attributes/default.rb +0 -1
- data/chef/cookbooks/synapse/recipes/default.rb +0 -6
- data/chef/run.json +0 -8
- data/chef/run.rb +0 -2
- data/client/.RData +0 -0
- data/client/.Rhistory +0 -294
- data/client/bench_rewrite_config.dat +0 -2013
- data/client/benchmark-client.iml +0 -20
- data/client/pom.xml +0 -45
- data/client/src/main/java/ClientArsch.java +0 -68
- data/client/src/main/java/META-INF/MANIFEST.MF +0 -3
- data/haproxy.pid +0 -1
- data/lib/gen-rb/endpoint_types.rb +0 -65
- data/lib/gen-rb/thrift.rb +0 -65
- data/test.sh +0 -3
data/.gitignore
CHANGED
data/.mailmap
ADDED
data/LICENSE.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c)
|
1
|
+
Copyright (c) 2013 Airbnb, Inc.
|
2
2
|
|
3
3
|
MIT License
|
4
4
|
|
@@ -19,4 +19,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
19
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
20
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
21
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Makefile
ADDED
data/README.md
CHANGED
@@ -54,10 +54,7 @@ Add a hash under `services` that looks like this:
|
|
54
54
|
|
55
55
|
```json
|
56
56
|
{"services":
|
57
|
-
{
|
58
|
-
"name": "proddb",
|
59
|
-
"local_port": 3219,
|
60
|
-
"server_options": "check inter 2000 rise 3 fall 2",
|
57
|
+
"proddb": {
|
61
58
|
"default_servers": [
|
62
59
|
{
|
63
60
|
"name": "default-db",
|
@@ -70,8 +67,16 @@ Add a hash under `services` that looks like this:
|
|
70
67
|
"tag": "proddb",
|
71
68
|
"value": "true"
|
72
69
|
},
|
73
|
-
"
|
74
|
-
|
70
|
+
"haproxy": {
|
71
|
+
"port": 3219,
|
72
|
+
"server_options": "check inter 2000 rise 3 fall 2",
|
73
|
+
"frontend": [
|
74
|
+
"mode tcp",
|
75
|
+
],
|
76
|
+
"backend": [
|
77
|
+
"mode tcp",
|
78
|
+
],
|
79
|
+
},
|
75
80
|
},
|
76
81
|
...
|
77
82
|
```
|
@@ -114,15 +119,13 @@ The second is the `haproxy` section, which specifies how to configure and intera
|
|
114
119
|
|
115
120
|
### Configuring a Service ###
|
116
121
|
|
117
|
-
|
122
|
+
The services are a hash, where the keys are the `name` of the service to be configured.
|
123
|
+
The name is just a human-readable string; it will be used in logs and notifications.
|
124
|
+
Each value in the services hash is also a hash, and should contain the following keys:
|
118
125
|
|
119
|
-
* `name`: a human-readable name for the service, this is used in logs and notifications
|
120
|
-
* `local_port`: the port (on localhost) where HAProxy will listen for connections to the serivce
|
121
126
|
* `discovery`: how synapse will discover hosts providing this service (see below)
|
122
127
|
* `default_servers`: the list of default servers providing this service; synapse uses these if none others can be discovered
|
123
|
-
* `
|
124
|
-
* `server_options`: the haproxy options for each `server` line of the service in HAProxy config; may be left out
|
125
|
-
* `listen`: additional lines passed to the HAProxy config in the `listen` stanza of this service
|
128
|
+
* `haproxy`: how will the haproxy section for this service be configured
|
126
129
|
|
127
130
|
#### Service Discovery ####
|
128
131
|
|
@@ -149,6 +152,17 @@ The watcher assumes that each node under `path` represents a service server.
|
|
149
152
|
Synapse attempts to decode the data in each of these nodes using JSON and also using Thrift under the standard Twitter service encoding.
|
150
153
|
We assume that the data contains a hostname and a port for service servers.
|
151
154
|
|
155
|
+
##### Docker #####
|
156
|
+
|
157
|
+
This watcher retrieves a list of [docker](http://www.docker.io/) containers via docker's [HTTP API](http://docs.docker.io/en/latest/api/docker_remote_api/).
|
158
|
+
It takes the following options:
|
159
|
+
|
160
|
+
* `method`: docker
|
161
|
+
* `servers`: a list of servers running docker as a daemon. Format is `{"name":"...", "host": "..."[, port: 4243]}`
|
162
|
+
* `image_name`: find containers running this image
|
163
|
+
* `container_port`: find containers forwarding this port
|
164
|
+
* `check_interval`: how often to poll the docker API on each server. Default is 15s.
|
165
|
+
|
152
166
|
#### Listing Default Servers ####
|
153
167
|
|
154
168
|
You may list a number of default servers providing a service.
|
@@ -162,6 +176,17 @@ The `default_servers` list is used only when service discovery returns no server
|
|
162
176
|
In that case, the service proxy will be created with the servers listed here.
|
163
177
|
If you do not list any default servers, no proxy will be created.
|
164
178
|
|
179
|
+
#### The `haproxy` Section ####
|
180
|
+
|
181
|
+
This section is it's own hash, which should contain the following keys:
|
182
|
+
|
183
|
+
* `port`: the port (on localhost) where HAProxy will listen for connections to the service.
|
184
|
+
* `server_port_override`: the port that discovered servers listen on; you should specify this if your discovery mechanism only discovers names or addresses (like the DNS watcher). If the discovery method discovers a port along with hostnames (like the zookeeper watcher) this option may be left out, but will be used in preference if given.
|
185
|
+
* `server_options`: the haproxy options for each `server` line of the service in HAProxy config; it may be left out.
|
186
|
+
* `frontend`: additional lines passed to the HAProxy config in the `frontend` stanza of this service
|
187
|
+
* `backend`: additional lines passed to the HAProxy config in the `backend` stanza of this service
|
188
|
+
* `listen`: these lines will be parsed and placed in the correct `frontend`/`backend` section as applicable; you can put lines which are the same for the frontend and backend here.
|
189
|
+
|
165
190
|
### Configuring HAProxy ###
|
166
191
|
|
167
192
|
The `haproxy` section of the config file has the following options:
|
@@ -172,6 +197,9 @@ The `haproxy` section of the config file has the following options:
|
|
172
197
|
* `do_reloads`: whether or not Synapse will reload HAProxy (default to `true`)
|
173
198
|
* `global`: options listed here will be written into the `global` section of the HAProxy config
|
174
199
|
* `defaults`: options listed here will be written into the `defaults` section of the HAProxy config
|
200
|
+
* `bind_address`: force HAProxy to listen on this address (default is localhost)
|
201
|
+
|
202
|
+
Note that a non-default `bind_address` can be dangerous: it is up to you to ensure that HAProxy will not attempt to bind an address:port combination that is not already in use by one of your services.
|
175
203
|
|
176
204
|
## Contributing
|
177
205
|
|
@@ -188,7 +216,8 @@ If you'd like to create a new service watcher:
|
|
188
216
|
1. Create a file for your watcher in `service_watcher` dir
|
189
217
|
2. Use the following template:
|
190
218
|
```ruby
|
191
|
-
|
219
|
+
require 'synapse/service_watcher/base'
|
220
|
+
|
192
221
|
module Synapse
|
193
222
|
class NewWatcher < BaseWatcher
|
194
223
|
def start
|
data/bin/synapse
CHANGED
@@ -3,18 +3,18 @@
|
|
3
3
|
require 'json'
|
4
4
|
require 'optparse'
|
5
5
|
|
6
|
-
|
6
|
+
require 'synapse'
|
7
7
|
|
8
8
|
options={}
|
9
9
|
|
10
10
|
# set command line options
|
11
11
|
optparse = OptionParser.new do |opts|
|
12
|
-
opts.banner
|
12
|
+
opts.banner =<<-EOB
|
13
13
|
Welcome to synapse
|
14
14
|
|
15
15
|
Usage: synapse --config /path/to/synapse/config
|
16
|
-
EOB
|
17
|
-
|
16
|
+
EOB
|
17
|
+
|
18
18
|
options[:config] = ENV['SYNAPSE_CONFIG']
|
19
19
|
opts.on('-c config','--config config', String, 'path to synapse config') do |key,value|
|
20
20
|
options[:config] = key
|
@@ -24,31 +24,39 @@ EOB
|
|
24
24
|
puts opts
|
25
25
|
exit
|
26
26
|
end
|
27
|
-
|
28
27
|
end
|
29
28
|
|
30
|
-
|
31
29
|
# parse command line arguments
|
32
30
|
optparse.parse!
|
33
31
|
|
34
|
-
|
35
|
-
# parse synapse config file
|
36
|
-
begin
|
37
|
-
|
38
|
-
rescue Errno::ENOENT => e
|
39
|
-
|
40
|
-
rescue Errno::EACCES => e
|
41
|
-
|
42
|
-
rescue JSON::ParserError => e
|
43
|
-
|
32
|
+
def parseconfig(filename)
|
33
|
+
# parse synapse config file
|
34
|
+
begin
|
35
|
+
c = JSON::parse(File.read(filename))
|
36
|
+
rescue Errno::ENOENT => e
|
37
|
+
raise ArgumentError, "config file does not exist:\n#{e.inspect}"
|
38
|
+
rescue Errno::EACCES => e
|
39
|
+
raise ArgumentError, "could not open config file:\n#{e.inspect}"
|
40
|
+
rescue JSON::ParserError => e
|
41
|
+
raise "config file #{filename} is not json:\n#{e.inspect}"
|
42
|
+
end
|
43
|
+
return c
|
44
44
|
end
|
45
45
|
|
46
|
+
config = parseconfig(options[:config])
|
47
|
+
config['services'] ||= {}
|
46
48
|
|
47
|
-
|
48
|
-
|
49
|
+
if config.has_key?('service_conf_dir')
|
50
|
+
cdir = File.expand_path(config['service_conf_dir'])
|
51
|
+
if ! Dir.exists?(cdir)
|
52
|
+
raise "service conf dir does not exist:#{cdir}"
|
53
|
+
end
|
54
|
+
cfiles = Dir.glob(File.join(cdir, '*.json'))
|
55
|
+
cfiles.each { |x| config['services'][File.basename(x[/(.*)\.json$/, 1])] = parseconfig(x) }
|
56
|
+
end
|
49
57
|
|
50
|
-
#
|
58
|
+
# run synapse
|
59
|
+
s = Synapse::Synapse.new(config)
|
51
60
|
s.run
|
52
61
|
|
53
|
-
|
54
|
-
puts "exiting synapse"
|
62
|
+
puts "synapse has exited"
|
@@ -0,0 +1,71 @@
|
|
1
|
+
{
|
2
|
+
"services": {
|
3
|
+
"service1": {
|
4
|
+
"default_servers": [
|
5
|
+
{ "name": "default1", "host": "localhost", "port": 8080 }
|
6
|
+
],
|
7
|
+
"discovery": {
|
8
|
+
"method": "dns",
|
9
|
+
"nameserver": "127.0.0.1",
|
10
|
+
"servers": [
|
11
|
+
"0.www.example.com",
|
12
|
+
"1.www.example.com"
|
13
|
+
]
|
14
|
+
},
|
15
|
+
"haproxy": {
|
16
|
+
"server_options": "check inter 2s rise 3 fall 2",
|
17
|
+
"listen": [
|
18
|
+
"mode http",
|
19
|
+
"option httplog"
|
20
|
+
],
|
21
|
+
"backend": [
|
22
|
+
"mode http",
|
23
|
+
"option httpchk GET /health HTTP/1.0"
|
24
|
+
]
|
25
|
+
}
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"haproxy": {
|
29
|
+
"reload_command": "sudo service haproxy reload",
|
30
|
+
"config_file_path": "/etc/haproxy/haproxy.cfg",
|
31
|
+
"socket_file_path": "/var/haproxy/stats.sock",
|
32
|
+
"do_writes": true,
|
33
|
+
"do_reloads": true,
|
34
|
+
"do_socket": true,
|
35
|
+
"global": [
|
36
|
+
"daemon",
|
37
|
+
"user haproxy",
|
38
|
+
"group haproxy",
|
39
|
+
"maxconn 4096",
|
40
|
+
"log 127.0.0.1 local0",
|
41
|
+
"log 127.0.0.1 local1 notice",
|
42
|
+
"stats socket /var/haproxy/stats.sock mode 666 level admin"
|
43
|
+
],
|
44
|
+
"defaults": [
|
45
|
+
"log global",
|
46
|
+
"option dontlognull",
|
47
|
+
"maxconn 2000",
|
48
|
+
"retries 3",
|
49
|
+
"timeout connect 5s",
|
50
|
+
"timeout client 1m",
|
51
|
+
"timeout server 1m",
|
52
|
+
"option redispatch",
|
53
|
+
"balance roundrobin"
|
54
|
+
],
|
55
|
+
"extra_sections": {
|
56
|
+
"listen stats :3212": [
|
57
|
+
"mode http",
|
58
|
+
"stats enable",
|
59
|
+
"stats uri /",
|
60
|
+
"stats refresh 5s"
|
61
|
+
],
|
62
|
+
"frontend http-generic-in": [
|
63
|
+
"bind 127.0.0.1:80",
|
64
|
+
"acl is_service1 hdr_dom(host) -i service1.lb",
|
65
|
+
"acl is_cache hdr_dom(host) -i cache.lb",
|
66
|
+
"use_backend service1 if is_service1",
|
67
|
+
"use_backend cache if is_cache"
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
71
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
{
|
2
|
+
"service_conf_dir": "config/synapse_services",
|
3
|
+
"haproxy": {
|
4
|
+
"reload_command": "sudo service haproxy reload",
|
5
|
+
"config_file_path": "/etc/haproxy/haproxy.cfg",
|
6
|
+
"socket_file_path": "/var/haproxy/stats.sock",
|
7
|
+
"do_writes": true,
|
8
|
+
"do_reloads": true,
|
9
|
+
"do_socket": true,
|
10
|
+
"global": [
|
11
|
+
"daemon",
|
12
|
+
"user haproxy",
|
13
|
+
"group haproxy",
|
14
|
+
"maxconn 4096",
|
15
|
+
"log 127.0.0.1 local0",
|
16
|
+
"log 127.0.0.1 local1 notice",
|
17
|
+
"stats socket /var/haproxy/stats.sock mode 666 level admin"
|
18
|
+
],
|
19
|
+
"defaults": [
|
20
|
+
"log global",
|
21
|
+
"option dontlognull",
|
22
|
+
"maxconn 2000",
|
23
|
+
"retries 3",
|
24
|
+
"timeout connect 5s",
|
25
|
+
"timeout client 1m",
|
26
|
+
"timeout server 1m",
|
27
|
+
"option redispatch",
|
28
|
+
"balance roundrobin"
|
29
|
+
],
|
30
|
+
"extra_sections": {
|
31
|
+
"listen stats :3212": [
|
32
|
+
"mode http",
|
33
|
+
"stats enable",
|
34
|
+
"stats uri /",
|
35
|
+
"stats refresh 5s"
|
36
|
+
],
|
37
|
+
"frontend http-generic-in": [
|
38
|
+
"bind 127.0.0.1:80",
|
39
|
+
"acl is_service1 hdr_dom(host) -i service1.lb",
|
40
|
+
"acl is_cache hdr_dom(host) -i cache.lb",
|
41
|
+
"use_backend service1 if is_service1",
|
42
|
+
"use_backend cache if is_cache"
|
43
|
+
]
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
data/config/synapse.conf.json
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
{
|
2
|
-
"services":
|
3
|
-
{
|
4
|
-
"name": "service1",
|
5
|
-
"local_port": 3213,
|
6
|
-
"server_options": "check inter 2s rise 3 fall 2",
|
2
|
+
"services": {
|
3
|
+
"service1": {
|
7
4
|
"default_servers": [
|
8
5
|
{
|
9
6
|
"name": "default1",
|
@@ -13,22 +10,23 @@
|
|
13
10
|
],
|
14
11
|
"discovery": {
|
15
12
|
"method": "zookeeper",
|
16
|
-
"path": "/
|
13
|
+
"path": "/services/service1",
|
17
14
|
"hosts": [
|
18
|
-
"
|
19
|
-
"zk1.airbnb.com:2181"
|
15
|
+
"localhost:2181"
|
20
16
|
]
|
21
17
|
},
|
22
|
-
"
|
23
|
-
"
|
24
|
-
"
|
25
|
-
"
|
26
|
-
|
18
|
+
"haproxy": {
|
19
|
+
"port": 3213,
|
20
|
+
"server_options": "check inter 2s rise 3 fall 2",
|
21
|
+
"listen": [
|
22
|
+
"mode http",
|
23
|
+
"option httpchk /health",
|
24
|
+
"http-check expect string OK"
|
25
|
+
]
|
26
|
+
}
|
27
|
+
|
27
28
|
},
|
28
|
-
{
|
29
|
-
"name": "service2",
|
30
|
-
"local_port": 3214,
|
31
|
-
"server_options": "check inter 2s rise 3 fall 2",
|
29
|
+
"service2": {
|
32
30
|
"default_servers": [
|
33
31
|
{
|
34
32
|
"name": "default1",
|
@@ -38,18 +36,21 @@
|
|
38
36
|
],
|
39
37
|
"discovery": {
|
40
38
|
"method": "zookeeper",
|
41
|
-
"path": "/
|
39
|
+
"path": "/services/service2",
|
42
40
|
"hosts": [
|
43
|
-
"
|
44
|
-
"zk1.airbnb.com:2181"
|
41
|
+
"localhost:2181"
|
45
42
|
]
|
46
43
|
},
|
47
|
-
"
|
48
|
-
"
|
49
|
-
"
|
50
|
-
|
44
|
+
"haproxy": {
|
45
|
+
"port": 3214,
|
46
|
+
"server_options": "check inter 2s rise 3 fall 2",
|
47
|
+
"listen": [
|
48
|
+
"mode http",
|
49
|
+
"option httpchk /health"
|
50
|
+
]
|
51
|
+
}
|
51
52
|
}
|
52
|
-
|
53
|
+
},
|
53
54
|
"haproxy": {
|
54
55
|
"reload_command": "sudo service haproxy reload",
|
55
56
|
"config_file_path": "/etc/haproxy/haproxy.cfg",
|
@@ -85,12 +86,5 @@
|
|
85
86
|
"stats refresh 5s"
|
86
87
|
]
|
87
88
|
}
|
88
|
-
},
|
89
|
-
"synapse": {
|
90
|
-
"self_check_port": 3210,
|
91
|
-
"self_check_proxy_port": 3211,
|
92
|
-
"zk_servers": [
|
93
|
-
"localhost:2181"
|
94
|
-
]
|
95
89
|
}
|
96
90
|
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
{
|
2
|
+
"default_servers": [
|
3
|
+
{ "name": "default1", "host": "localhost", "port": 8080 }
|
4
|
+
],
|
5
|
+
"discovery": {
|
6
|
+
"method": "dns",
|
7
|
+
"nameserver": "10.10.1.13",
|
8
|
+
"servers": [
|
9
|
+
"0.www.example.com",
|
10
|
+
"1.www.example.com"
|
11
|
+
]
|
12
|
+
},
|
13
|
+
"haproxy": {
|
14
|
+
"server_options": "check inter 2s rise 3 fall 2",
|
15
|
+
"listen": [
|
16
|
+
"mode http",
|
17
|
+
"option httplog"
|
18
|
+
],
|
19
|
+
"backend": [
|
20
|
+
"mode http",
|
21
|
+
"option httpchk GET /health HTTP/1.0"
|
22
|
+
]
|
23
|
+
}
|
24
|
+
}
|