How Combatant Gentlemen Solved Service Discovery Using Heroku Private Spaces

Scott Raio is Co-Founder and CTO of Combatant Gentlemen, a design-to-delivery menswear e-commerce brand. Read our Combatant Gentlemen customer story to learn more about how Heroku helped them build a successful online business.

What microservices are you running in Heroku Private Spaces?

We’ve written an individual service for every business use case. For example, we have services for order processing, product catalog, account management, authentication, swatch display, POs, logistics, payments, etc.

With all these different services, we chose Heroku Private Spaces as a way to make service discovery easier. We’re currently running about 25 services, which is a relatively small number compared to Netflix or Twitter (who employ hundreds of services). But we’re growing, and we’re always evaluating our services to determine which ones are too large and need to be broken out.

Most of our services work autonomously and share nothing between them. When the services are isolated and containerized, then changes are much simpler. It’s a very clean approach.

Read more →

RabbitMQ Add-on Now Available on Heroku

Today we're proud to announce the availability in beta of RabbitMQ add-on by VMWare. RabbitMQ is an open source implementation of the AMQP protocol that provides a robust, scalable and easy-to-use messaging system built for the needs of cloud application developers.

Getting Started

With the add-on, provisioning a fully managed RabbitMQ instance couldn't be easier to do:

$ cd rabbitdemo
$ heroku addons:add rabbitmq
-----> Adding rabbitmq to rabbitdemo... done, v2 (free)

$ heroku config
RABBITMQ_URL  => amqp://

Your application's environment will now have the RABBITMQ_URL set pointing to your new instance. Most modern AMQP clients such as Bunny for Ruby will accept a connection string in URI format, making configuration a breeze. The following is a simple Sinatra app that demonstrates posting and getting messages from the default RabbitMQ exchange. You can grab the source from Github here. Let's have a look:

Entering a message and hitting "post" will send a message to a RabbitMQ queue, where it will sit until we tell the app to fetch the oldest message from the queue by clicking "get". Examining the application code, the first place to look is in "lib/sinatra_rabbitmq.rb" where we set up the connection from the environment variable, and declare a queue called "messages":


require 'sinatra/base'
require 'bunny'

module Sinatra
  module RabbitMQ
    def rabbitmq_client
      return @rabbitmq_client if @rabbitmq_client
      @rabbitmq_client =["RABBITMQ_URL"])

    def rabbitmq_exchange
      @rabbitmq_exchange ||="")

    def rabbitmq_messages_queue
      @rabbitmq_messages_queue ||= rabbitmq_client.queue("messages")

  register RabbitMQ

Note that in RabbitMQ a message is never sent directly to a queue. Instead, it passes through an exchange, the type of which defines how messages are distributed to one or more client queues. In this case, we're side-stepping the concept of exchanges by using the default nameless exchange, which allows us to specify the target queue for our messages using a routing key. Once you get into more advanced usage of RabbitMQ such a broadcasting messages to set of known queues, you'll definitely want to learn more about exchanges.

With our connection established and queue defined, the main part of our app looks like this:


require 'sinatra/base'
require "#{File.dirname(__FILE__)}/lib/sinatra_rabbitmq"

class RabbitmqDemo < Sinatra::Base
  register Sinatra::RabbitMQ

  get "/" do
    haml :index

  post "/" do
    self.class.rabbitmq_exchange.publish params["message"], :key => "messages"
    @notice = "Message has been published."
    haml :index

  get "/message" do
    msg = self.class.rabbitmq_messages_queue.pop
    if msg[:payload] == :queue_empty
      @notice = "No more messages."
      @message = msg[:payload]
    haml :index

The first interesting part here is post to "/" where we send the message you typed in to the default exchange, using "messages" as the routing key. Then we pick up any outstanding at "/messages" by popping off the queue, which follows the FIFO principle. The rest, as they say, is just a bit of HTML.

Why would you want to use a messaging system?

The distribution of workloads across different process types is an essential aspect of modern web application architecture. For example, if your app handles file uploads, your web process might receive the upload and signal a background worker to do some processing on it via a queue. While you could use Delayed Job or another database-backed queueing library to do this, a true messaging system gives you much more flexibility, reliability and scalability in defining how your signals are distributed and received by your worker pool.

Finally, messaging is an important tool for the polyglot programmer. Having a language agnostic, data-centric message bus that can orchestrate communications between, say, a web app in Ruby, workers in Java and a chat server in Node.js is a key enabler in allowing application developers choose the right tool for any specific job.

Over the past few years RabbitMQ has emerged as one of the most popular, open source choices for messaging with clients in all major languages, and thousands of enterprises trusting it for mission-critical apps. We're excited to offer it as a cloud service through the Add-ons Catalog, fully managed and operated by the team who created it.

Browse the blog archives, subscribe to the full-text feed, or visit the engineering blog.