Gilles has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/264084

Change subject: Add HAProxy in front of Thumbors
......................................................................

Add HAProxy in front of Thumbors

This get us consistent hash load balancing as well as
abuse throttling.

Bug: T123461
Change-Id: Ibe44bc16262f81cebcbd7c7bfa02c5f7255f065f
---
M puppet/hieradata/common.yaml
M puppet/modules/role/settings/thumbor.yaml
M puppet/modules/thumbor/manifests/init.pp
A puppet/modules/thumbor/templates/haproxy-upstart.erb
A puppet/modules/thumbor/templates/haproxy.conf.erb
R puppet/modules/thumbor/templates/thumbor-upstart.erb
M puppet/modules/thumbor/templates/thumbor.conf.erb
M puppet/modules/thumbor/templates/varnish.vcl.erb
8 files changed, 144 insertions(+), 14 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/vagrant 
refs/changes/84/264084/1

diff --git a/puppet/hieradata/common.yaml b/puppet/hieradata/common.yaml
index af91aa7..e6dfcc8 100644
--- a/puppet/hieradata/common.yaml
+++ b/puppet/hieradata/common.yaml
@@ -329,6 +329,7 @@
 
 thumbor::deploy_dir: "%{hiera('mwv::vendor_dir')}/thumbor"
 thumbor::cfg_file: /etc/thumbor.conf
+thumbor::haproxy_cfg_file: /etc/haproxy-thumbor.conf
 thumbor::statsd_port: "%{hiera('statsd::port')}"
 thumbor::sentry_dsn_file: "%{hiera('sentry::dsn_file')}"
 
diff --git a/puppet/modules/role/settings/thumbor.yaml 
b/puppet/modules/role/settings/thumbor.yaml
index 0565c23..71bad5f 100644
--- a/puppet/modules/role/settings/thumbor.yaml
+++ b/puppet/modules/role/settings/thumbor.yaml
@@ -1,5 +1,8 @@
 vagrant_ram: 512
 forward_ports:
-  8888: 8888 # thumbor
+  8888: 8888 # haproxy pointing to thumbors
+  8889: 8889 # haproxy stats
+  8890: 8890 # thumbor1
+  8891: 8891 # thumbor2
   6081: 6081 # varnish
   8040: 8040 # swift
\ No newline at end of file
diff --git a/puppet/modules/thumbor/manifests/init.pp 
b/puppet/modules/thumbor/manifests/init.pp
index 8241b44..407a7f3 100644
--- a/puppet/modules/thumbor/manifests/init.pp
+++ b/puppet/modules/thumbor/manifests/init.pp
@@ -13,6 +13,9 @@
 # [*cfg_file*]
 #   Thumbor configuration file. The file will be generated by Puppet.
 #
+# [*haproxy_cfg_file*]
+#   HAProxy configuration file. The file will be generated by Puppet.
+#
 # [*statsd_port*]
 #   Port the statsd instance runs on.
 #
@@ -22,6 +25,7 @@
 class thumbor (
     $deploy_dir,
     $cfg_file,
+    $haproxy_cfg_file,
     $statsd_port,
     $sentry_dsn_file,
 ) {
@@ -58,10 +62,17 @@
     # For Ghostscript engine (PDF)
     require_package('ghostscript')
 
+    # For load-balancing
+    require_package('haproxy')
+
     $statsd_host = 'localhost'
     $statsd_prefix = 'Thumbor'
 
     group { 'thumbor':
+        ensure => present,
+    }
+
+    group { 'haproxy':
         ensure => present,
     }
 
@@ -70,6 +81,13 @@
         home    => '/var/run/thumbor',
         gid     => 'thumbor',
         require => Group['thumbor'],
+    }
+
+    user { 'haproxy':
+        ensure  => present,
+        home    => '/var/run/haproxy',
+        gid     => 'haproxy',
+        require => Group['haproxy'],
     }
 
     virtualenv::environment { $deploy_dir:
@@ -114,28 +132,46 @@
         require   => User['thumbor'],
     }
 
+    file { $haproxy_cfg_file:
+        ensure    => present,
+        group     => 'haproxy',
+        owner     => 'haproxy',
+        content   => template('thumbor/haproxy.conf.erb'),
+        mode      => '0640',
+        require   => User['haproxy'],
+    }
+
     cgroup::config { 'thumbor':
         limits  => "perm { task { uid = thumbor; gid = thumbor; } admin { uid 
= thumbor; gid = thumbor; } } memory { memory.limit_in_bytes = \"1048576000\"; 
}", # 1GB
         cgrules => '@thumbor memory thumbor',
     }
 
-    file { '/etc/init/thumbor.conf':
+    thumbor::service { '8890':
+        deploy_dir => $deploy_dir,
+        cfg_file   => $cfg_file,
+    }
+
+    thumbor::service { '8891':
+        deploy_dir => $deploy_dir,
+        cfg_file   => $cfg_file,
+    }
+
+    file { '/etc/init/haproxy-thumbor.conf':
         ensure  => present,
-        content => template('thumbor/upstart.erb'),
+        content => template('thumbor/haproxy-upstart.erb'),
         mode    => '0444',
     }
 
-    service { 'thumbor':
+    service { 'haproxy':
         ensure    => running,
         enable    => true,
         provider  => 'upstart',
-        require   => [
-            Virtualenv::Environment[$deploy_dir],
-            User['thumbor'],
-        ],
+        require   => User['haproxy'],
         subscribe => [
-            File["${deploy_dir}/tinyrgb.icc", $cfg_file, 
'/etc/init/thumbor.conf'],
-            Cgroup::Config['thumbor'],
+            File[
+                $haproxy_cfg_file,
+                '/etc/init/haproxy-thumbor.conf'
+            ],
         ],
     }
 
@@ -156,3 +192,32 @@
         order   => 49, # Needs to be before default for vcl_recv override
     }
 }
+
+define thumbor::service (
+    $deploy_dir,
+    $cfg_file,
+) {
+    file { "/etc/init/thumbor-${title}.conf":
+        ensure  => present,
+        content => template('thumbor/thumbor-upstart.erb'),
+        mode    => '0444',
+    }
+
+    service { "thumbor-${title}":
+        ensure    => running,
+        enable    => true,
+        provider  => 'upstart',
+        require   => [
+            Virtualenv::Environment[$deploy_dir],
+            User['thumbor'],
+        ],
+        subscribe => [
+            File[
+                "${deploy_dir}/tinyrgb.icc",
+                $cfg_file,
+                "/etc/init/thumbor-${title}.conf"
+            ],
+            Cgroup::Config['thumbor'],
+        ],
+    }
+}
diff --git a/puppet/modules/thumbor/templates/haproxy-upstart.erb 
b/puppet/modules/thumbor/templates/haproxy-upstart.erb
new file mode 100644
index 0000000..ef0e5e2
--- /dev/null
+++ b/puppet/modules/thumbor/templates/haproxy-upstart.erb
@@ -0,0 +1,13 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+#####################################################################
+
+description "HAProxy"
+
+start on mediawiki-ready
+respawn
+
+setuid haproxy
+setgid haproxy
+
+exec /usr/sbin/haproxy -f <%= @haproxy_cfg_file %>
\ No newline at end of file
diff --git a/puppet/modules/thumbor/templates/haproxy.conf.erb 
b/puppet/modules/thumbor/templates/haproxy.conf.erb
new file mode 100644
index 0000000..7cd8494
--- /dev/null
+++ b/puppet/modules/thumbor/templates/haproxy.conf.erb
@@ -0,0 +1,42 @@
+#####################################################################
+### THIS FILE IS MANAGED BY PUPPET
+#####################################################################
+
+global
+  maxconn 256
+
+defaults
+  mode http
+  timeout connect 5000ms
+  timeout client 50000ms
+  timeout server 50000ms
+  option http-server-close
+
+listen stats
+  bind *:8889
+  stats uri /stats
+
+frontend fe_thumbs
+  bind *:8888
+  default_backend be_thumbor
+
+  # A client cannot send more than 10 connection per second
+  acl too_fast fe_sess_rate ge 10
+
+  rspadd X-Backend-Server:\ thumbor1 if { srv_id 1 }
+  rspadd X-Backend-Server:\ thumbor2 if { srv_id 2 }
+
+  # Accept connections that aren't too fast
+  tcp-request content accept unless too_fast
+
+  # Add a delay for badly behaved requests (which weren't accepted by the 
previous command)
+  tcp-request inspect-delay 5s
+
+  # Accept throttled connections after the wait
+  tcp-request content accept if WAIT_END
+
+backend be_thumbor
+  balance hdr(xkey)
+  hash-type consistent
+  server thumbor1 127.0.0.1:8890 check id 1
+  server thumbor2 127.0.0.1:8891 check id 2
\ No newline at end of file
diff --git a/puppet/modules/thumbor/templates/upstart.erb 
b/puppet/modules/thumbor/templates/thumbor-upstart.erb
similarity index 85%
rename from puppet/modules/thumbor/templates/upstart.erb
rename to puppet/modules/thumbor/templates/thumbor-upstart.erb
index 4b7260d..0d69745 100644
--- a/puppet/modules/thumbor/templates/upstart.erb
+++ b/puppet/modules/thumbor/templates/thumbor-upstart.erb
@@ -2,7 +2,7 @@
 ### THIS FILE IS MANAGED BY PUPPET
 #####################################################################
 
-description "Thumbor"
+description "Thumbor on port <%= @title %>"
 
 start on mediawiki-ready
 respawn
@@ -12,4 +12,4 @@
 
 # Wrapping this with cgexec fails silently, which is why we rely on cgrulesengd
 # to put the thumbor process into a cgroup
-exec <%= @deploy_dir %>/bin/thumbor -c <%= @cfg_file %> -a tc_core.app.App
\ No newline at end of file
+exec <%= @deploy_dir %>/bin/thumbor -c <%= @cfg_file %> -a tc_core.app.App -p 
<%= @title %>
\ No newline at end of file
diff --git a/puppet/modules/thumbor/templates/thumbor.conf.erb 
b/puppet/modules/thumbor/templates/thumbor.conf.erb
index 1ebab85..4f5d5c3 100644
--- a/puppet/modules/thumbor/templates/thumbor.conf.erb
+++ b/puppet/modules/thumbor/templates/thumbor.conf.erb
@@ -133,7 +133,7 @@
 ## The loader thumbor should use to load the original image. This must be the
 ## full name of a python module (python must be able to import it)
 ## Defaults to: thumbor.loaders.http_loader
-LOADER = 'wikimedia_thumbor.loader.proxy'
+#LOADER = 'wikimedia_thumbor.loader.proxy'
 
 ## The file storage thumbor should use to store original images. This must be 
the
 ## full name of a python module (python must be able to import it)
@@ -558,7 +558,7 @@
 ################################## Extensions 
##################################
 
 COMMUNITY_EXTENSIONS = [
-    'wikimedia_thumbor.handler.multi'
+#    'wikimedia_thumbor.handler.multi'
 ]
 
 EXIFTOOL_PATH = '/usr/bin/exiftool'
diff --git a/puppet/modules/thumbor/templates/varnish.vcl.erb 
b/puppet/modules/thumbor/templates/varnish.vcl.erb
index aa6270c..c6263d8 100644
--- a/puppet/modules/thumbor/templates/varnish.vcl.erb
+++ b/puppet/modules/thumbor/templates/varnish.vcl.erb
@@ -14,6 +14,12 @@
         set req.http.X-Url = req.url;
     }
 
+    if (req.http.X-Url ~ "^/images/thumb/") {
+        set req.http.xkey = "File:" + regsub(req.http.X-Url, 
"^/images/thumb/[^/]+/[^/]+/([^/]+)/[^/]+$", "\1");
+    } else if (req.http.X-Url ~ "^/images/") {
+        set req.http.xkey = "File:" + regsub(req.http.X-Url, 
"^/images/[^/]+/[^/]+/(.*)", "\1");
+    }
+
     # Since we expose varnish on the default port (6081) we need to rewrite
     # requests that are generated using the default wiki port (8080)
     # This needs to be done early because it's needed for PURGE calls

-- 
To view, visit https://gerrit.wikimedia.org/r/264084
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibe44bc16262f81cebcbd7c7bfa02c5f7255f065f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/vagrant
Gerrit-Branch: master
Gerrit-Owner: Gilles <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to