< Return to Video

RailsConf 2014 - Rack-AMQP: Ditch HTTP Inside SOA! by Josh Szmajda

  • 0:17 - 0:23
    JOSH SZMAJDA: All right. You guys ready to
    talk about SOA? Woo!
  • 0:23 - 0:30
    I'm Josh. Hi. How you doing? I'm the CTO
  • 0:31 - 0:33
    at Optoro. We make software for retailers.
    Help them
  • 0:33 - 0:36
    deal with their stuff at scale. I'm working
    on
  • 0:36 - 0:41
    a project called RACK-AMQP. RACK-AMQP is a
    collection of
  • 0:41 - 0:47
    different projects, including an RC, some
    client libraries, and
  • 0:47 - 0:51
    most notably, Jackalope, which is a new Ruby
    web
  • 0:51 - 0:56
    application server, like Unicorn, Passenger,
    Thin, or, or anything
  • 0:56 - 0:59
    like that. Except that it's special-purpose.
    It's for service-oriented
  • 0:59 - 1:04
    architectures. And it doesn't actually speak
    HTTP at all.
  • 1:04 - 1:08
    So. Why am I doing this crazy thing? Well,
  • 1:08 - 1:11
    my app drove me to it. My app is
  • 1:11 - 1:14
    huge. It's really complicated. This is kind
    of a
  • 1:14 - 1:16
    services diagram of my app. Or where we'd
    like
  • 1:16 - 1:18
    to go with it.
  • 1:18 - 1:21
    There's over three-hundred and fifty models
    in one Rails
  • 1:21 - 1:25
    application. The test suite takes over eight
    hours. It's
  • 1:25 - 1:30
    kind of a headache. You could put it. So
  • 1:30 - 1:31
    we decided the way to move forward with it
  • 1:31 - 1:34
    is to break it up into smaller applications
    that
  • 1:34 - 1:37
    work together. And, of course, that means
    SOA.
  • 1:37 - 1:41
    Now, I mean, SOA is really wrapped up in
  • 1:41 - 1:45
    a lot of pretty awful baggage, when you come
  • 1:45 - 1:49
    down to it. SOA, you think about enterprise
    service
  • 1:49 - 1:53
    buses. You think about strict interface definitions.
    Versions. I
  • 1:53 - 1:55
    mean it's a lot of complexity that you have
  • 1:55 - 2:00
    to worry about. Extra load balancers. More
    configuration. More
  • 2:00 - 2:02
    distributed tracing and monitoring. I mean,
    it's a, it's
  • 2:02 - 2:04
    a real pain.
  • 2:04 - 2:07
    So I, I hate SOA, right. It makes me
  • 2:07 - 2:12
    feel like this. So, but when you get down
  • 2:12 - 2:15
    to it, SOA is actually not all of that.
  • 2:15 - 2:20
    SOA is really just independent actors communicating.
    They're working
  • 2:20 - 2:25
    together to get something useful done. So,
    really, SOA
  • 2:25 - 2:30
    can mitigate complexity by enforcing simplification.
    Each service only
  • 2:30 - 2:33
    has to think about its own little bubble.
    It
  • 2:33 - 2:34
    only has to worry about its little component.
    And
  • 2:34 - 2:35
    it doesn't have to think about anything else
    that
  • 2:35 - 2:38
    goes on in its entire system.
  • 2:38 - 2:40
    You can let your system architect worry about
    what's
  • 2:40 - 2:41
    going on across the whole thing. All you have
  • 2:41 - 2:42
    to do is pay attention to your one little
  • 2:42 - 2:45
    service and you can be pretty happy.
  • 2:45 - 2:48
    So, when you get down to it again, SOA
  • 2:48 - 2:52
    is really just independent actors communicating.
    Now that communicating
  • 2:52 - 2:54
    bit is important. How they communicate actually
    determines how
  • 2:54 - 2:58
    your application behaves. And the kinds of
    communication you
  • 2:58 - 3:01
    can use impacts the kind of application you
    can
  • 3:01 - 3:02
    write.
  • 3:02 - 3:05
    So, the typical communication pattern that
    we're most familiar
  • 3:05 - 3:08
    with as programmers is sort of direct messaging.
    I
  • 3:08 - 3:11
    am an object. I can send a message to
  • 3:11 - 3:13
    my friend. My friend is gonna give me back
  • 3:13 - 3:16
    a response. It's very normal. It's what, in
    fact,
  • 3:16 - 3:19
    we use all the time with HTTP. But when
  • 3:19 - 3:20
    you think about it, what we actually want
    to
  • 3:20 - 3:22
    do is be able to send different kinds of
  • 3:22 - 3:25
    messaging structures. We want to publish that
    something happened
  • 3:25 - 3:27
    in my system and have people subscribe to
    that
  • 3:27 - 3:30
    event and take some interesting action.
  • 3:30 - 3:32
    It's all about decoupling. I don't have to
    know
  • 3:32 - 3:34
    about my neighbor anymore. I just need to
    know
  • 3:34 - 3:36
    that I did something, and then somebody else
    might
  • 3:36 - 3:38
    care that, oh, you did something. That's great.
    Let
  • 3:38 - 3:39
    me do something about that.
  • 3:39 - 3:42
    But again, like I said, let me. We're Rails
  • 3:42 - 3:45
    developers. We're used to writing web applications.
    We speak
  • 3:45 - 3:48
    HTTP all the time. HTTP allows us to do
  • 3:48 - 3:50
    direct messaging, so that's what we tend to
    do.
  • 3:50 - 3:52
    I'd say most SOAs out there, when they get
  • 3:52 - 3:54
    off the ground, they start building web applications
    that
  • 3:54 - 3:57
    speak with each other through HTTP. It's what
    we're
  • 3:57 - 3:58
    familiar with.
  • 3:58 - 4:01
    But what would we actually like our transport
    mechanism
  • 4:01 - 4:05
    to be? We want it to be, you know,
  • 4:05 - 4:09
    data structure independent. HTTP specifies
    that there be a
  • 4:09 - 4:11
    body, but it doesn't specify the format of
    the
  • 4:11 - 4:13
    body. We want it to be fast. We want
  • 4:13 - 4:18
    it to be open, transparent, understandable,
    clear. You know,
  • 4:18 - 4:20
    debuggable. Observable. And flexible.
  • 4:20 - 4:26
    So, is HTTP all of those things. We also
  • 4:26 - 4:30
    need, not only direct request response type
    of messaging,
  • 4:30 - 4:34
    like RPC, but we also need pub, subscribe,
    and
  • 4:34 - 4:38
    broadcast. Additionally, we don't need more
    load balancers. More
  • 4:38 - 4:43
    SSL certificates. Distributed logging. Trying
    to figure out what's
  • 4:43 - 4:45
    going on in this service over here versus
    that
  • 4:45 - 4:47
    one over there. It's a nightmare.
  • 4:47 - 4:50
    And, you know, looking up the various services
    in
  • 4:50 - 4:52
    your system, it's a pain. So, again, I mean,
  • 4:52 - 4:55
    HTTP, you know, it has, it is blind. It's
  • 4:55 - 4:58
    fast. It's open, clear, it's well-understood.
    It's what we
  • 4:58 - 5:02
    know. It's really great for RPC. It's a better
  • 5:02 - 5:02
    alternative.
  • 5:02 - 5:08
    And that's AMQP. AMQP is blind, also. It doesn't
  • 5:08 - 5:10
    care what data you're transmitting across
    it. It's extremely
  • 5:10 - 5:13
    fast. It's an open system. It's great for
    all
  • 5:13 - 5:16
    messaging pattern. Not just direct messaging,
    but pub/sub, and
  • 5:16 - 5:21
    queue-based messaging. It's centralized, which
    in terms of a
  • 5:21 - 5:24
    service-oriented architecture is very beneficial,
    in that you have
  • 5:24 - 5:26
    one point to manage, one point to pay attention
  • 5:26 - 5:29
    to everything at. And the only issue is that
  • 5:29 - 5:30
    it's not what we're familiar with. It's not
    what
  • 5:30 - 5:32
    we know. You know, again, we're web developers.
    We're
  • 5:32 - 5:34
    not AMQP developers. At least not the most
    of
  • 5:34 - 5:35
    us.
  • 5:35 - 5:36
    So it's a challenge.
  • 5:36 - 5:40
    So the RACK-AMQP project that I'm working
    on is
  • 5:40 - 5:44
    really designed to make AMQP simple. We are
    trying
  • 5:44 - 5:47
    to introduce as few opinions as absolutely
    necessary in
  • 5:47 - 5:50
    order to make this possible. And to give you
  • 5:50 - 5:51
    a stepping stone into the world of AMQP where
  • 5:51 - 5:54
    you can start to integrate more advanced concepts
    into
  • 5:54 - 6:01
    the system, without having to relearn your
    entire world.
  • 6:01 - 6:04
    So it also lets us continue to build what
  • 6:04 - 6:07
    we know. Because it's built on Rack, you know,
  • 6:07 - 6:10
    we're web-developers. We can continue to use
    the web
  • 6:10 - 6:12
    concepts that we're familiar with. We can
    developer locally
  • 6:12 - 6:14
    on our web machines using the systems that
    we're
  • 6:14 - 6:16
    comfortable with. And then when we deploy,
    we simply
  • 6:16 - 6:18
    deploy it to Jackalope, instead of to Unicorn
    or
  • 6:18 - 6:22
    Passenger or whatever, and it's magically
    in this world
  • 6:22 - 6:24
    of AMQP.
  • 6:24 - 6:28
    So. How does that work? Well, let's look at
  • 6:28 - 6:29
    AMQP a little bit more in depth, first. So
  • 6:29 - 6:32
    AMQP is the advanced messaging queue, message
    queueing protocol.
  • 6:32 - 6:34
    It is an open standard. It's developed by
    Oasis,
  • 6:34 - 6:38
    which is an open standards body. It, again,
    like
  • 6:38 - 6:42
    I said, uses a centralized distribution pattern.
    That centralized
  • 6:42 - 6:44
    distribution pattern allows you to do the
    various kinds
  • 6:44 - 6:47
    of messaging that are really handy for us.
    The
  • 6:47 - 6:50
    pub/sub and the other interesting thing. This
    implies that
  • 6:50 - 6:52
    we have a broker in the center that all
  • 6:52 - 6:55
    of our services connect to and transmit messages
    through
  • 6:55 - 6:57
    that broker. And that broker can make intelligent
    decisions
  • 6:57 - 6:59
    about how to route those messages.
  • 6:59 - 7:03
    AMQP messages themselves, they have headers
    and bodies, just
  • 7:03 - 7:06
    like HTTP. There are well-known fields, like
    content type
  • 7:06 - 7:12
    and priority, in this case. And we can actually
  • 7:12 - 7:15
    leverage the conventions that we understand
    from HTTP to
  • 7:15 - 7:19
    pull AMQP into the world. So AMQP, like I
  • 7:19 - 7:21
    mentioned, has these headers and bodies. It
    has well-known
  • 7:21 - 7:24
    fields. And HTTP essentially has headers and
    bodies and
  • 7:24 - 7:27
    also well-known fields. So we can essentially
    emulate HTTP
  • 7:27 - 7:30
    over AMQP without too much trouble. And, again,
    the
  • 7:30 - 7:32
    AMQP supports the RPC messaging pattern, which
    is what
  • 7:32 - 7:34
    HTTP is.
  • 7:34 - 7:37
    So, one of the parts of the project is
  • 7:37 - 7:42
    the AMQP HTTP RC, which, it simply does as
  • 7:42 - 7:45
    little as it has to to define the structure.
  • 7:45 - 7:46
    It's just a documentation on how we're doing
    the
  • 7:46 - 7:48
    mapping. One of the other goals is that we
  • 7:48 - 7:50
    want to make inner-operability with other
    languages and other
  • 7:50 - 7:54
    platforms really easy. So having an RC will
    allow
  • 7:54 - 7:56
    it, allow us to have just a central document
  • 7:56 - 8:00
    to refer back to in constructing other servers.
  • 8:00 - 8:02
    So let's look at HTTP a little bit more
  • 8:02 - 8:03
    in-depth. How does HTTP work? Well, you know,
    when
  • 8:03 - 8:07
    we send a request, we send a specific request
  • 8:07 - 8:09
    to a server, to a, you know, specific IP
  • 8:09 - 8:12
    address and port. And we get back a response.
  • 8:12 - 8:15
    And, of course, the request has things like
    the
  • 8:15 - 8:19
    HTTP verb, the path, headers, the bodies.
    And the
  • 8:19 - 8:21
    response comes back with a response code.
  • 8:21 - 8:24
    It's all stuff we're familiar with. So all
    we
  • 8:24 - 8:26
    had to do is map that into AMQP terms,
  • 8:26 - 8:28
    which is essentially what we've done here.
    And this
  • 8:28 - 8:30
    is just a reference for just a few of
  • 8:30 - 8:32
    the things that we're doing. Like content
    type. There's
  • 8:32 - 8:34
    already a content type header in AMQP, so
    we
  • 8:34 - 8:37
    just reuse that. Some things didn't make sense.
    Like
  • 8:37 - 8:41
    the protocol for example. In HTTP you've got
    HTP
  • 8:41 - 8:46
    or HTPS or HTTP plus dev or whatever. But
  • 8:46 - 8:49
    with AMQP, your protocol's already negotiated
    when you connect
  • 8:49 - 8:50
    to the broker. So it doesn't really make sense
  • 8:50 - 8:52
    for us to worry about that in the messages
  • 8:52 - 8:55
    we're passing around the system.
  • 8:55 - 8:57
    The host name becomes, essentially, the routing
    key. The
  • 8:57 - 9:00
    queue target that we're sending to in AMQP.
    And
  • 9:00 - 9:03
    it makes it really simple. So, this looks
    like
  • 9:03 - 9:07
    this, essentially, in code. This is an example
    of
  • 9:07 - 9:10
    how you could write a client that speaks AMQP,
  • 9:10 - 9:13
    HTTP. You create a call-back queue. We'll
    get back
  • 9:13 - 9:15
    to that in one sec. You publish a message
  • 9:15 - 9:18
    that looks like an HTTP message to the target
  • 9:18 - 9:20
    queue. And then you wait for a response.
  • 9:20 - 9:22
    Now, the callback queue is actually a really
    important
  • 9:22 - 9:26
    thing here. AMQP is a hundred percent queue
    based.
  • 9:26 - 9:29
    It's all asynchronous under the hood. But,
    you know,
  • 9:29 - 9:32
    we want to write a synchronous system. HTTP
    is
  • 9:32 - 9:34
    synchronous. I send a request. I wait for
    the
  • 9:34 - 9:37
    response, or receive the response and move
    on. So,
  • 9:37 - 9:41
    to do that in AMQP, we create a respond
  • 9:41 - 9:43
    queue that we are going to listen to in
  • 9:43 - 9:47
    the broker. It's an anonymous queue. There's
    a great
  • 9:47 - 9:49
    convention. We're doing this in AMQP. It's
    very easy.
  • 9:49 - 9:51
    So we create a response queue, we get the
  • 9:51 - 9:52
    name of that queue, and then as part of
  • 9:52 - 9:54
    the message we send to our target, we say,
  • 9:54 - 9:56
    here's the response queue to reply back at.
    And
  • 9:56 - 9:58
    then we simply wait for the response on that
  • 9:58 - 10:00
    call-back queue to come back. So that lets
    us
  • 10:00 - 10:03
    get the synchrony that we're familiar with,
    that we
  • 10:03 - 10:06
    need, with HTTP style programming, while still
    having an
  • 10:06 - 10:09
    asynchronous system under the hood.
  • 10:09 - 10:14
    RACK, of course, we're all using RACK today.
    Even
  • 10:14 - 10:16
    if you're not familiar with it. RACK, of course,
  • 10:16 - 10:18
    is what runs all Ruby web application servers.
    Turns
  • 10:18 - 10:21
    out that RACK actually doesn't care about
    HTTP. All
  • 10:21 - 10:24
    that RACK really defines is that you had defined
  • 10:24 - 10:27
    a call method that receives an environment,
    which is
  • 10:27 - 10:30
    basically a hash, and it responds back with
    a
  • 10:30 - 10:34
    three-element array. The HTTP response code,
    headers, and the
  • 10:34 - 10:35
    body.
  • 10:35 - 10:37
    That hash doesn't actually have to be anything
    but
  • 10:37 - 10:40
    a hash. It just has to look like an
  • 10:40 - 10:43
    HTTP environment. So emulation was actually
    pretty simple. So
  • 10:43 - 10:46
    this is basically how it looks. We subscribe
    to
  • 10:46 - 10:48
    a queue on the server, and then for every
  • 10:48 - 10:51
    message we receive back for that queue, we
    unpack
  • 10:51 - 10:54
    some things into variables. We create what
    looks like
  • 10:54 - 10:57
    the HTTP environment and we have the request
    method
  • 10:57 - 10:58
    and query string. If you ever wrote CGI way
  • 10:58 - 11:00
    back in the day, this might look familiar
    to
  • 11:00 - 11:02
    you.
  • 11:02 - 11:04
    And then we essentially pass that environment
    onto our
  • 11:04 - 11:07
    RACK application, receive the response from
    the RACK app
  • 11:07 - 11:10
    and then publish that back to the response
    queue.
  • 11:10 - 11:12
    So this is what Jackalope is doing for us.
  • 11:12 - 11:16
    Jackalope is emulating HTTP for our RACK applications.
    And
  • 11:16 - 11:19
    it just works. I'll show you a demo at
  • 11:19 - 11:20
    the end. You don't have to modify your code
  • 11:20 - 11:23
    at all. You can just simply deploy to it,
  • 11:23 - 11:26
    and it's speaking AMQP instead of HTTP. So
    that's
  • 11:26 - 11:29
    it. We're done. We can go on vacation, right?
  • 11:29 - 11:32
    Well. I didn't talk about how to actually
    put
  • 11:32 - 11:37
    this in production, other than just use Jackalope.
    So
  • 11:37 - 11:41
    you have to choose a broker in AMQP. So
  • 11:41 - 11:43
    what we're using is RabbitMQ. RabbitMQ is
    a well-known
  • 11:43 - 11:46
    AMQP broker. If you're doing any AMQP you're
    probably
  • 11:46 - 11:51
    using RabbitMQ, most likely. It's used by
    giants out
  • 11:51 - 11:53
    there. I mean, Google, VMWare, NASA. All these
    people
  • 11:53 - 11:55
    are using Rabbit pretty heavily.
  • 11:55 - 12:00
    It's extremely scalable. It's fault-tolerant.
    It's distributable. And it's
  • 12:00 - 12:03
    secure. It does everything you'd ever want.
    And it
  • 12:03 - 12:05
    also gives you a really great management console.
    We
  • 12:05 - 12:06
    can go in and see what's going on in
  • 12:06 - 12:08
    your system. Like I mentioned, the distributed
    logging we
  • 12:08 - 12:10
    saw in the, in the last talk, if you
  • 12:10 - 12:11
    were here for that, trying to get an idea
  • 12:11 - 12:13
    of what's going on across your system can
    be
  • 12:13 - 12:16
    challenging. Rabbit doesn't tell you everything
    you'd want to
  • 12:16 - 12:17
    know, but it at least gives you an idea
  • 12:17 - 12:20
    of what queues are being used. Their depths
    at
  • 12:20 - 12:22
    the point. The kind of information that can
    help
  • 12:22 - 12:24
    you get, at least get a handle on it.
  • 12:24 - 12:27
    Additionally, you're gonna have to think about
    how you
  • 12:27 - 12:29
    talk to the real world. I mean, AMQP is
  • 12:29 - 12:31
    all well and good behind the scenes, but how
  • 12:31 - 12:33
    do I continue to interact and serve my clients
  • 12:33 - 12:35
    that I actually care about, to the point of
  • 12:35 - 12:36
    getting paid, right.
  • 12:36 - 12:39
    So this is the architecture we typically use
    at
  • 12:39 - 12:41
    Optoro. We have our Rabbit server in the middle,
  • 12:41 - 12:44
    and all the various services sitting on Jackalope
    that
  • 12:44 - 12:46
    talk to Rabbit. And then additionally we have
    one
  • 12:46 - 12:48
    or more API services that are continuing to
    be
  • 12:48 - 12:51
    deployed on Unicorn, in our case. They talk
    to
  • 12:51 - 12:55
    the outside world and internally translate
    the, the needs
  • 12:55 - 12:58
    through AMQP and the rest of the system.
  • 12:58 - 12:59
    One of the things we actually published for
    each
  • 12:59 - 13:02
    of our services is a client gem that kind
  • 13:02 - 13:05
    of isolates the worry, the worry about exactly
    which
  • 13:05 - 13:08
    transport we're using away from the consumer,
    the API
  • 13:08 - 13:11
    here. So it actually is, is really simple.
  • 13:11 - 13:13
    And so the way that we do that is
  • 13:13 - 13:16
    we typically have been using HTTParty for
    our HTTP
  • 13:16 - 13:19
    communication needs. So we wrote, as one of
    the
  • 13:19 - 13:23
    other projects part of RACK-AMQP, is AMQParty,
    which is
  • 13:23 - 13:27
    just a API-compliant version of HTTParty.
    So we can
  • 13:27 - 13:31
    actually just drop in the AMQParty constant
    in place
  • 13:31 - 13:33
    of the HTTParty constant, and you can see
    down
  • 13:33 - 13:36
    below, that transport variable, we typically
    configure that at
  • 13:36 - 13:39
    boot time to be either HTTParty or AMQParty.
    And
  • 13:39 - 13:41
    everything, again, just works.
  • 13:41 - 13:43
    We change the, the url a little bit, too.
  • 13:43 - 13:45
    But we do that all part of the, part
  • 13:45 - 13:47
    of this setup for each server. For each client.
  • 13:47 - 13:52
    Of course, if you don't want to use HTTParty,
  • 13:52 - 13:54
    some people like the various other options
    that are
  • 13:54 - 13:57
    out there, we also are publishing RACK-AMQP
    client, which
  • 13:57 - 14:00
    is what H, AMQParty is built on. It, it's
  • 14:00 - 14:03
    a very simple API. You get a client, you
  • 14:03 - 14:07
    tell it which Rabbit to connect to. You send
  • 14:07 - 14:10
    a request to your target queue with your uri
  • 14:10 - 14:12
    as part of it, with any, you know, your
  • 14:12 - 14:14
    HTTP method and all that. You get back your
  • 14:14 - 14:16
    response. It's synchronous. It's simple. It's
    actually built on
  • 14:16 - 14:19
    Bunny, which is a really great AMQP gem out
  • 14:19 - 14:22
    there, and that also is very easy to use.
  • 14:22 - 14:28
    Additionally, we're publishing a sample SOA
    using Rails. It's
  • 14:28 - 14:33
    a work-in-progress at the moment. BUt the
    userland and
  • 14:33 - 14:34
    userland_client are mostly built as, you can
    see where
  • 14:34 - 14:37
    things are at the mo- at the current state.
  • 14:37 - 14:39
    It kind of gives you an idea about how
  • 14:39 - 14:42
    we think about SOA at Optoro, and how you
  • 14:42 - 14:45
    might be able to use Jackalope and the RACK-AMQP
  • 14:45 - 14:47
    project in your own projects.
  • 14:47 - 14:52
    So userland is a, is Rails service that essentially
  • 14:52 - 14:55
    publishes a user's concept out into the world.
    And
  • 14:55 - 14:57
    then userland_client is a gem that consumes
    the userland
  • 14:57 - 15:00
    service and interface uses the userland gem
    to talk
  • 15:00 - 15:02
    to the userland service.
  • 15:02 - 15:07
    And so then, you know, how fast is this?
  • 15:07 - 15:11
    Well, there's this bench mark I've got. I'll
    show
  • 15:11 - 15:13
    you it in just a sec. The only weird
  • 15:13 - 15:15
    thing we have to do here is tell AMQParty
  • 15:15 - 15:16
    which Rabbit to talk to, and you kind of
  • 15:16 - 15:18
    saw that in the, in the client gem a
  • 15:18 - 15:20
    little bit, so that's a little bit of setup
  • 15:20 - 15:21
    we do. Again, like I said, when we make
  • 15:21 - 15:24
    the decision about which, whether HTTParty
    or AMQParty. So
  • 15:24 - 15:26
    we tell it which Rabbit. And then, inside,
    we,
  • 15:26 - 15:31
    five hundred times, request this JSON using
    AMQParty and
  • 15:31 - 15:33
    then five hundred times request the same thing
    using
  • 15:33 - 15:33
    HTTParty.
  • 15:33 - 15:37
    So here, I'll show you that in, in use.
  • 15:37 - 15:41
    Let's see. OK.
  • 15:41 - 15:48
    Let's make this big. All right. So here I'm
  • 15:49 - 15:53
    gonna boot the app using Unicorn. So Unicorn
    is
  • 15:53 - 15:57
    listing on port 8080. Wow. That's really big.
    Trust
  • 15:57 - 16:00
    me, it's 8080 there. I'm gonna boot the same
  • 16:00 - 16:02
    map using Jackalope. The only difference I
    have to
  • 16:02 - 16:03
    do to boot the app is I have to
  • 16:03 - 16:05
    say with the right queue name, so it's going
  • 16:05 - 16:08
    to listen to the test dot simple queue.
  • 16:08 - 16:10
    So there it is running. And then down here
  • 16:10 - 16:13
    I'm gonna starty the bench mark. And like
    I
  • 16:13 - 16:16
    said, it's gonna five hundred times hit each
    service.
  • 16:16 - 16:19
    What it actually does is hit each service
    three
  • 16:19 - 16:20
    times, just to make sure that it's warm, and
  • 16:20 - 16:23
    then it can go through and hit it all
  • 16:23 - 16:25
    the way through. And there we go.
  • 16:25 - 16:27
    So you can see, it's two point nine seconds
  • 16:27 - 16:30
    total to do five hundred AMQP requests, and
    three
  • 16:30 - 16:33
    point six seconds total to do five hundred
    HTTP
  • 16:33 - 16:37
    requests. I was actually surprised when I
    got this
  • 16:37 - 16:41
    result. Jackalope is beta. I mean, it's, we're
    using
  • 16:41 - 16:44
    it at Optoro, but it's not really been battle-tested.
  • 16:44 - 16:47
    But it's faster, at the moment. So why is
  • 16:47 - 16:48
    it faster?
  • 16:48 - 16:52
    Well, maybe I haven't written all the code
    yet.
  • 16:52 - 16:56
    But more likely it, more likely it's because
    of
  • 16:56 - 17:00
    this concept in TCP called the slow-start
    phenomonon. And
  • 17:00 - 17:03
    also, your whole TCP negotiation. So each
    one of
  • 17:03 - 17:07
    these five hundred HTTP requests, close the
    connection, open
  • 17:07 - 17:11
    the connection, send the message, receive
    the response. When
  • 17:11 - 17:13
    you open the TCP connection you go through
    a
  • 17:13 - 17:15
    whole sinaq phase, which I didn't put slides
    in
  • 17:15 - 17:17
    for and maybe should have. But it's.
  • 17:17 - 17:21
    I highly recommend checking out Eliot Gregorich's
    talks, by
  • 17:21 - 17:24
    the way, about how HTTP works, how TCP works.
  • 17:24 - 17:27
    But basically, you go through protocol negotiation
    for any
  • 17:27 - 17:32
    TCP connection, and then there's a feature
    of TCP
  • 17:32 - 17:34
    called the slow-start feature, which essentially
    allows you to
  • 17:34 - 17:38
    negotiate your connection speed. And that's
    really great when
  • 17:38 - 17:40
    you're talking over the internet, and you're
    not sure
  • 17:40 - 17:42
    of the latency or the availability of routers
    to
  • 17:42 - 17:45
    be decent along the way. But when you're doing
  • 17:45 - 17:48
    internal applications, it just gets in your
    way. It
  • 17:48 - 17:49
    just slows you down.
  • 17:49 - 17:52
    So AMQP, we hold a persistent connection to
    the
  • 17:52 - 17:55
    AMQP broker. We do one sinaq cycle, and then
  • 17:55 - 17:58
    we get our maximum connection speed and we
    stay
  • 17:58 - 18:00
    there. And then we can multiplex information
    over that
  • 18:00 - 18:03
    single connection and it works really well.
    Now, you
  • 18:03 - 18:05
    could write that with HTTP if you did a
  • 18:05 - 18:09
    keep-alive connection, held over that connection
    and talk to
  • 18:09 - 18:10
    the same thing back and forth.
  • 18:10 - 18:11
    But, the bottom line is that most of us
  • 18:11 - 18:13
    don't do that when we write HTTP. We're using
  • 18:13 - 18:18
    something like HTTParty or, I always forget
    the tiforce
  • 18:18 - 18:21
    or tif- whatever it is. Sorry.
  • 18:21 - 18:22
    Most of the time, you know, we drop the
  • 18:22 - 18:24
    connection, you know, in between requests.
    We don't hold
  • 18:24 - 18:26
    it open. It's just not something we think
    about.
  • 18:26 - 18:30
    So using AMQParty or any of the libraries
    that
  • 18:30 - 18:32
    we're published, it holds that open and it
    just
  • 18:32 - 18:35
    makes it more efficient overall.
  • 18:35 - 18:36
    So I hope that's the primary explanation of
    why
  • 18:36 - 18:43
    it's so much faster. So I just wanted to
  • 18:44 - 18:46
    mention a few references, a few things that
    were
  • 18:46 - 18:48
    really inspriring when we kind of went down
    this
  • 18:48 - 18:50
    road. You know, this is really a departure
    from
  • 18:50 - 18:53
    what we're used to in Rails. And the Architecture:
  • 18:53 - 18:56
    The Lost Years talk and Matt Wynne's original
    Hexegonal
  • 18:56 - 18:58
    Rails talks were all about departing from
    what we're
  • 18:58 - 19:00
    used to, I think. So those are really interesting.
  • 19:00 - 19:03
    If you haven't checked those out, definitely
    do.
  • 19:03 - 19:05
    Additionally, Martin Fowler posted a recent
    article that was
  • 19:05 - 19:08
    awesome, called Micro Services. Definitely,
    definitely read this if
  • 19:08 - 19:12
    you are looking into service-oriented architectures.
    It lets you
  • 19:12 - 19:15
    not think about that heavy-weight bloat that
    we think
  • 19:15 - 19:17
    about with SOA.
  • 19:17 - 19:19
    It's really a revisitation of the idea of,
    just,
  • 19:19 - 19:23
    you have independent services that are collaborating
    to get
  • 19:23 - 19:25
    something done in a very simple way. And that's
  • 19:25 - 19:28
    really, again, also influenced the direction
    we're taking here.
  • 19:28 - 19:31
    We want to introduce as few specific choices
    as
  • 19:31 - 19:33
    possible to just kind of give us a simple
  • 19:33 - 19:37
    transport to, to build on top of. Additionally,
    the
  • 19:37 - 19:40
    Ruby AMQP gem has some awesome docs about
    how
  • 19:40 - 19:43
    AMQP works, how to use it with Ruby. And
  • 19:43 - 19:46
    RabbitMQ also publishes some really great
    documentation on what
  • 19:46 - 19:48
    AMQP is, how it works. How to use it
  • 19:48 - 19:50
    in the organization in your applications.
  • 19:50 - 19:52
    And there's also this really great article
    I found
  • 19:52 - 19:55
    about how HTTP works, in general. It's, I
    think
  • 19:55 - 19:58
    a piece of school material from a university
    in
  • 19:58 - 20:00
    Singapore. Definitely check it out. It's got
    really great
  • 20:00 - 20:01
    diagrams.
  • 20:01 - 20:07
    Thanks. Again, I'm Josh. I'm at jszmajda on
    the
  • 20:07 - 20:10
    Twitters. I am the CTO at Optoro. We have
  • 20:10 - 20:13
    blinq dot com. We have retailers with their
    returned
  • 20:13 - 20:15
    goods and excess goods, help them figure out
    what
  • 20:15 - 20:17
    it is, what the current value is and move
  • 20:17 - 20:18
    it quickly.
  • 20:18 - 20:20
    Additionally, I am the host of the Ruby hangout.
  • 20:20 - 20:22
    Just a quick blurb for the Ruby hangout, it's
  • 20:22 - 20:25
    a online meetup. It's really handy when you
    can
  • 20:25 - 20:28
    go face-to-face and talk to people if you
    have
  • 20:28 - 20:29
    a local meet up. If you don't have a
  • 20:29 - 20:31
    local meet up or if you're too busy or
  • 20:31 - 20:33
    if you can't make it for whatever reason,
    the
  • 20:33 - 20:36
    Ruby hangout is an online meet up to, essentially,
  • 20:36 - 20:38
    give you that local meet up feel, as much
  • 20:38 - 20:40
    as we can online. So check that out. It's
  • 20:40 - 20:42
    a lot of fun. I'm one of the co-organizers
  • 20:42 - 20:44
    of the DC Ruby Users group. And I want
  • 20:44 - 20:46
    to give a quick shoutout to Jonathan. Thanks
    Jon.
  • 20:46 - 20:50
    He's on my team, helped me get Jackalope over
  • 20:50 - 20:53
    the, over the finish line. So super helpful
    on
  • 20:53 - 20:53
    that.
  • 20:53 - 20:56
    All the code's on GitHub. Github dot com slash
  • 20:56 - 20:59
    rack dash amqp slash rack dash amqp is where
  • 20:59 - 21:02
    the RC lives and has bookmarks to the other
  • 21:02 - 21:06
    parts of the project. And I would love to
  • 21:06 - 21:10
    take your questions, because that talk was
    way short.
  • 21:10 - 21:13
    And I've got, actually, a whole bunch of stuffed
  • 21:13 - 21:16
    Jackalopes up here for good questions. So
    please feel
  • 21:16 - 21:18
    free to come grab one.
Title:
RailsConf 2014 - Rack-AMQP: Ditch HTTP Inside SOA! by Josh Szmajda
Description:

more » « less
Duration:
21:47

English subtitles

Revisions