>> Go Developers often build applications and
microservices that communicate with
each other using messages and cues.
Well, David Justice is here to show us some of
the messaging service options available
inside Azure for Go Developers,
today on Azure Friday.
Welcome to Azure Friday everybody.
I'm Eric St. Martin and with me
today is David Justice who's going to talk
about some of the messaging options that we
have available as Go Developers inside Azure.
>> Awesome. I am very
grateful to be here. Thank you, Eric.
So yeah, we have some really cool stuff that came up
most recently with Go and messaging.
So, I'm going to lead us
with a little bit of background on messaging in
general, and just kind
of look at the landscape for a second.
So, generally, with microservices,
we try to communicate through dumb pipes.
We don't want any real intelligence in
it and there's really two kind of schools of thought.
The first one being HTTP direct communication.
So, I have some serious discovery in place,
I have some services behind Load Balancer,
I'm going to go figure out what
a DNS entry is for and just give them a call.
That's cool, that's cool, we can do that.
We can also communicate through cues, and we have
really cool strong enterprise messaging options in Azure,
and I think we're going to dig into that
today and compare and contrast those.
So the old adage,
do not communicate by sharing
memory communicate share memory by,
what is it, communicating, excuse me.
So, in HTTP messaging,
we get direct and it's simple,
we don't really get
any guarantees about whether the message gets there,
we could try to infer that based on error codes.
We are temporarily coupled
meaning that this service
needs to be up for me to reach it within HTTP call.
>> Do you ever try to hit a service that is there?
>> Calling restarts things like this.
You just happen to hit and then
that sweet spot where it's down.
>> Yes, yes.
Oops. So, then we build in libraries to do
retries and we have side cars to do it.
We have all sorts of stuff built around this idea.
It would be nice if there
was just services that did this
for us and this is what we're going to get into.
So, you have that classic problem.
You see the Load Balancer,
you see the service calling in the Load Balancer.
You see all these services behind it,
trying to register themselves,
so that you know in this moving environment
where this thing A and B are going to be,
they're always moving around.
They could get moved to node-to-node,
they need to keep telling the service registry,
we can do better.
So, we introduced this Message Broker and the Message
Broker is a lightweight messaging protocol.
It's pretty dumb.
It's binary, it's AMQP, it's a standard.
You get a reliable delivery,
it's load balanced by default.
The Message Broker takes care of it.
You get more of this typology where
your services on the outside
only need to know about where the broker is.
They don't even know about each other,
they just coordinate on cues,
they coordinate on the contents of the message.
So, making sure my data cues are the same and it's quick,
it's cool, and we have great services for it.
So, one of the problems with running
these in the past is
actually running a Message Broker yourself.
Have you ever run Rabbit?
>> Almost all of them over the years
I've ran and yeah nobody likes.
>> I dig interlink. I don't
want to look at an interlinks stack trace.
>> No.
>> So, we do that for you
and the benefit of this is I throw a message in my cue.
>> Interlink stack processing as a service?
>> No thank you.
Yes. So, imagine you have a cue out there.
I toss a message in the cue. It's asynchronous.
I'm waiting for a response back
possibly from that service, hopefully.
But they're decoupled so that service has made
that connection to that cue and may
pop that message and then respond when it's ready.
It doesn't matter where it's at at
that moment that's the temporal disconnect.
This is a really cool semantic.
So, Event Hubs gives us this,
the Event Hub service gives us this massive ingress
and egress of messages.
We can use it for log collection,
we can use it for IoT solutions,
we can take in tons of
messages and then also read
those messages and process them in the streams.
Service Bus gives us the ability to route messages,
filter messages, do pub/sub,
do queues, you get retry semantics.
It's all built in and it's all load balanced.
Then you get Event Grid which is all HTTP-based.
Those first two are AMQP,
a binary protocol standard,
and Event Hubs or
Event Grid gives us this HTTP end points that we
can use to relay
events and guarantees delivery that kind of good stuff.
>> So, when would you want to use one over another?
>> That's a great question. So Event Hubs,
you would want to use for like I say large log, ingress,
egress, stream processing where
you need at least one time that the event gets processed.
So in the Event Hubs,
you can go and throw
tons and tons of messages and we're talking about
like gigabytes per minute, that kind of ingress.
Then you have a partitioned consumer.
So, a single consumer consumes
a single partition and you can
have hundreds of partitions.
I think we crossed 1000
but I don't want to say that for sure.
But we test up to 256 partitions.
So, you had a receiver for each one of those.
Service Bus is more like I want to make
sure this financial record gets processed.
So, I want to know
if this financial transaction got processed.
If it didn't get processed,
I want it to go in a dead letter
cue some I guarantee that I'm going to look at it later.
>> Okay.
>> Event Grid is more like,
it's not huge throughput.
It's more I want to
get notified when this webhook gets it.
I want to know when a blob is created in stores.
>> Events are triggering some action or something
more so than actually like sending a ton of data to it.
>> Yep. Precisely. So without further ado,
let's look at some code.
>> Let's do this.
>> Okay. So, we built these new libraries in Go
and we have an Event Hub library
and we also have a Service Bus library.
Those are located at- so we have GitHub and Event Hub Go.
You can go out there and grab a library and in here,
we have this little command line.
This is kind of what we used to test some ingress.
So, this is a Cobra Command.
It's called Max test and this
is a test hub project and here,
I'm going to go create a new TokenProvider here with
sasKey and sasName for Event Hub.
Then, I'm going to make sure that
the Event Hub is
partitioned and then I'm going
to spin off based on the number of senders,
how many senders I want to go start sending into the cue.
So, a sender itself actually just goes through,
creates a new Event Hub
given the namespace, the hub name,
the TokenProvider and variadic set
of options so like who do I want to send
to and then it goes through and starts sending messages.
So, we try to maximize batch size here
so you can batch up a bunch of events,
pack them together and send it.
>> When you said new hub that's not actually
provisioning an instance of Event Hub that's just-.
>> It would if you asked it to.
>> Okay.
>> Yeah. So, we kind of mixed
the management plane and the data plane here.
So, that and meaning,
you can provision and do Event Hubs,
and you can also start using them.
So it's really nice.
You want to have that experience together.
So, here we're going to go see how this runs.
Here, so I set up a connection string already so we
just pass this in and yay.
So, those are how many messages
were sent in so far and I have
a really bad connection here because we're on
Wi-Fi and I can't really maximize there.
So, before here, I
sent a bunch of stuff and I did a deployment at the Kub.
So, I'm going to get some pods,
see my pods out there. All right cool.
So, I have seven senders in
Kubernetes right now running that are
actually pretty near to the service
and let's go look and see how many of these have sent.
I started them up this morning.
Let's see. All right.
So, I think that's a pretty healthy number.
Is that 93 million or nine million, 9.3?
>> Ninety-three million.
>> Yeah, that's pretty good.
>> Wait, yes.
>> So, multiply that by seven or so.
>> [inaudible] scale.
>> Yeah. Let's see what this thing actually looks like.
So, here is the last six hours
and we're averaging close to
eight million messages per minute or so.
Throughput is about eight gigs or so.
So, you want to throw some messages at it.
This is just managed,
like you don't have to go and
deal with spinning up and provisioning stuff.
All you do is turn it on.
Tell it how many throughput units you want to use?
Like how many compute units I'm going to use,
and it'll spin up and expand as needed. It's really cool.
>> Yes.
>> Yeah, it's fun.
So, any questions about Event Hub?
>> No, I just want to flood it, I want to take it down.
To Sanader I like to break stuff.
>> Well.
>> How many messages will it take?
>> Yes, let's see.
So, we actually have some great tests there.
if you go out to the Repo,
I placed out our test,
and what we've done to ensure
the library runs for a long period of time, it's robust.
To see how much it'll take,
up to 100 throughput units?
So, we have provisioned like
private infrastructure internally.
We run it for days on end,
just to make sure this thing is bulletproof, right?
Because you don't want that stuff breaking down.
>> Once I get a hold of it.
>> Bring it, file bug please.
We will fix it quickly. All right.
So, the next one is service bus.
So, service bus is a little bit different piece.
You aren't going to be using it for huge ingress.
You're going to be using it more for queue, routing,
filtering, and ensuring that
the message gets processed, right?
That went before is at least once.
This is I want it process only one time.
You don't want to debit your account two,
three times,right? You want it once.
>> I want your account debited more than once.
>> Then transferred it.
>> Exactly
>> All right. So, from here,
we actually have a Buffalo app.
So, Buffalo is a very popular web framework these days,
and it is already running.
So cool. Thanks Buffalo.
>> You kill the other thing in
that address and started a new one.
>> You are awesome. I love you.
All right. So, let's see here.
Let's see if this will run.
Here we go. All right.
So here, we have a little Buffalo app that's running,
and it's going to ask us to login.
When it goes to login, it's going to go head off 8080,
and it's going to login, and it's going to grab my Email,
and it's going to say,
"Hey, I'm going to send you an email."
So, let's see this thing working.
So, it's head off, it's authenticated.
Now, it sent an email to me. All right, that's great.
Now, what happened there?
>> Inside an e-mail.
>> I know, right. Super-great. Thanks a lot.
So, what we did is,
we have, that Buffalo comes with this simple worker,
and the simple worker just spins off
a Goprog and it's goroutine,
and it's going to just run stuff with in-process right?
That's pretty useful.
But, if your process gets killed,
anything happens, that work is lost, right?
There's no backing to it.
There's also a Rattus backing to it as well.
But what we did is we put together
a lovely implementation using the worker interface.
So, you just provided your connection string,
create a new service bus,
and tell it what cues are you going to be listening to.
Then, you set it in the worker for the app.
Then, you can register to jobs.
So, for example, I registered my logging e-mail.
So, that's neat. It's successfully sent an email,
and it just emailed notification.
So, we have a really rich e-mail service here.
So, it works, and that's really neat.
But, what happens if it fails?
So, I want to see what happens when I fail this thing.
Let's get rid of ARGs, and, so rebuilt.
Let's go login one more time, and we're going to see-.
Oh, no! I failed again,
I failed again, and it continues this way.
It will continue that way for 10 times.
That's configurable on the queue.
We can configure that as we want.
Then, we're looking at putting
in smarter worker constraint.
So, based on delivery count,
you have an exponential back off or something like that.
Then, you can also see that in service bus,
if we hop over there,
we'll see our queue for email. Soon as it comes up.
>> We're sharing about the exponential back off.
That would be for something like you kept tripping up
against the API limits for whatever the-
>> Yeah, totally.
>> - [inaudible] using as or something.
>> Yeah, I'm using
x-provider and it's a transition error.
I want to retry it, okay?
But, even if I didn't,
I still now can start seeing dead letters.
So, these dead letters after that thing is
processed x number of times,
like you said, it'll
then get dropped in the dead letter queue.
So, you know this thing didn't get processed,
and you can go look at it at the end of the day.
Go see what went wrong.
Maybe I should attach my error case to it,
so that I can see what that error was?
It's really nice for job processing,
and that's something we do all the time in
the web jobs or web apps.
You want to be able to process those.
So, what does it look like to actually queue-up that job?
That's where it gets fun too.
So, it's just as simple as this.
You just call worker job queue, email,
and tell the handler,
and our handler is login email.
So, that's about as easy as it gets.
>> So here, inside this application,
it is both serving the purpose
as the publisher and the subscriber.
It has a worker running as well as doing that.
>> Yeah. We can build in richer semantics as well around,
as I said, queues, topics, and subscriptions.
Queues are as you would think, simple queues.
Topics are really cool.
Topics are like queues that you can't receive from,
but you can create subscriptions too.
So, you could subscribe to
the queue and pop the messages
off into each subscription.
So, this is kind of a broadcast,
and those broadcasters can
start filtering on those subscriptions.
So, you could put your logic for just like, "Hey,
I don't want to hear about this stuff",
up into the managed service,
never deal with it.
>> So, you're only getting the messages
that you're actually-
>> Yes.
>> -interested in. That's perfect.
>> Yeah. It's really easy.
I like easy. I'm really lazy. This helps do easy.
>> I think that's why we're programmers, right?
It's for lazy. We don't want
to have to do the same task twice.
>> I totally agree.
>> Thanks so much for joining us.
>> Thanks for having me. It's awesome.
>> So today, we learned all about the options available
for events and messaging inside Azure for Go Developers,
here on Azure Friday.