Netty
from the trenches
June 2015
@jordi9
Netty…?
Netty is an
asynchronous
event-driven
network
application
framework
for rapid
development of
maintainable high
performance
protocol servers &
clients.
Netty is a NIO
client server
framework which
enables quick and
easy development
of network
applications such
as protocol servers
and clients. It
greatly simplifies
and streamlines
network
network
programming such
as TCP and UDP
socket server.
OH, MY
The Freaking
Basics
You’ve heard of:
Async apps
You’ve heard of:
Event driven
frameworks
You’ve heard of:
non-blocking
operations
You’ve heard of:
Node is
cooler
because...
I/O
I/O is
everywhere
I/O, approx:
CPU
Memory
Device
read()
read()
//wait...
read()
//wait...
keepWorkingBro()
Our program
BLOCKS
Resources
WASTED
You know what
I’m talking
about
Webserver
Request
Database
//wait...
OH,
Parallelism!
new Thread();
Webserver
Request
Database
//wait...
Webserver
Request
Database
//wait...
Request
Database
//wait...
Webserver
Request
Database
//wait...
Request
Database
//wait...
Request
Database
//wait.
A mess
We can
do better
read()
read()
keepWorkingBro()
read()
keepWorkingBro()
//I’m
//done!
You (kinda) did this:
Listeners
You (kinda) did this:
Guava’s
EventBus
You (kinda) did this:
Javascript
callbacks
Hollywood principle
“Don’t call us,
we’ll call you”
Keep working,
instead of
waiting
Hi,
Async I/O
NIO
with Java
java.nio
since 1.4, 2002
java.nio
since 1.7: NIO2
more goodies
Hi,
Complexity
Netty
to the Rescue
Built on top of:
java.nio
Built on top of:
java.net
Dependecy-haters:
Just
JDK 1.6+
ONE
big difference
All Netty APIs
are async
It’s can be one
more tool!
What the hell
is Netty for?
Think...
HTTP
everywhere
Really
BRO?
Maybe, you’re
trying to
implement a
protocol
Finally, hello
Netty!
Netty:
Tool to
implement network
applications
Netty:
Both from server
and client side
Netty:
NIO
everywhere
Why
Netty?
Netty has been
designed carefully
with the
experiences
earned from the
implementation of
a lot of protocols
such as FTP,
SMTP, HTTP, and
various binary and
text-based legacy
protocols. As a
protocols. As a
result, Netty has
succeeded to find
a way to achieve...
Ease of
development
Performance
Stability
Flexibility
Without a
compromise
IT’S TRUE
“Implementing
a protocol”
NOT THAT HARD
Most common
protocols:
out-of-the-box
Boring Protocols:
HTTP
Boring Protocols:
SSL
Boring Protocols:
UDP
Cooler Protocols:
SPDY
Cooler Protocols:
HTTP/2
Cooler Protocols:
Protobuf
Even Protocols:
Memcache
Not only I/O
Powerful
Thread model
But, where’s
the downside?
Downers:
Constant API
changes*
Downers:
Constant API
changes*
*For the best
Downers:
Learning
curve...
Downers:
Learning
curve...
Buy Netty in Action :P
Downers:
Join the
mailing list
Downers:
Join the
mailing list
You’ll see how
STUPID you are
Downers:
Join the
mailing list
But you’ll learn ALOT ;)
Netty,
The Code
Daytime
Protocol
The
Server
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
}
The Hand e
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// Handler = Business Logic
}
The Hand e
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// ChannelHandler: handles operations
// for that Channe...
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// Inbound handler: incoming traffic,
// dispatch events...
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// Outbound handler: same, but the
// other direction. Y...
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// Inbound + Outbound...
}
The Hand e
class SimpleDaytimeHandler extends
ChannelInboundHandlerAdapter {
// Inbound + Outbound..
// 5.0: DEPRECATED!
// [NOTE: In...
Hand e me hod
@Override
public void channelRead(
ChannelHandlerContext ctx, Object msg) {
// Will trigger when we receive
// some data
}...
@Override
public void channelActive(
ChannelHandlerContext ctx, Object msg) {
// Will a Channel is opened, this
// method ...
@Override
public void channelActive(ChannelHandlerContext ctx, Object msg) {
String date = DATE_TIME.print(new DateTime())...
@Override
public void channelActive(ChannelHandlerContext ctx, Object msg) {
String date = DATE_TIME.print(new DateTime())...
It’s clear,
right? :D
Network
standard way of
working?
byte[]
You said this
was fun?
Meet
ByteBuf
ByteBufUtil
@Override
public void channelActive(ChannelHandlerContext ctx, Object msg) {
String date = DATE_TIME.print(new DateTime())...
@Override
public void channelActive(ChannelHandlerContext ctx, Object msg) {
String date = DATE_TIME.print(new DateTime())...
@Override
public void channelActive(ChannelHandlerContext ctx, Object msg) {
String date = DATE_TIME.print(new DateTime())...
We have our
Handler in place
Let’s Bootstrap
the server
Ma n ass
public class DaytimeServer {
void run() throws Exception {
// fun stuff
}
public static void main(String[] args) ...
java -jar daytimeserver-fat.jar
un()
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
E en LoopG oup
Netty’s way to
handle threads
E en LoopG oup
EventLoopGroup
contains some
EventLoops
E en Loop
EventLoop
handles many
Channels
About to die
BRO?
E en LoopG oup
E en Loop
hanne
hanne
hanne
hanne
hanne hanne
hanne
hanne
hanne
hanne
hanne hanne
E en Loop
E en LoopG oup
E en Loop
hanne
hanne
hanne
hanne
hanne hanne
hanne
hanne
hanne
hanne
hanne hanne
E en Loop
This immutable
assignment is
the key
un()
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
un()
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
// Boss gro...
Se e Boo s ap
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.c...
Se e Boo s ap
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.c...
Se e Boo s ap
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.c...
Se e Boo s ap
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.c...
Se e Boo s ap
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.c...
We’re
almost there!
hanne P pe ne
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)...
hanne P pe ne
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)...
hanne P pe ne
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)...
hanne P pe ne
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)...
RUN!
b.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch)
throws E...
.I.A.
Futures
ByteBuf API
Codecs
Transports
Zero-file-copy
We can also
create
client code
Real life
Insights
We’re using Netty for
Real-Time Bidding
Boo s ap
Tons o op ons
Don’t be afraid
of “low-level”
Ta HTTP
Explore what’s
inside Netty
Integrate things
you love. In my
case: GUICE
Gu e
@Inject
DaytimeService(Provider<DaytimeServer> daytimeProvider) {}
b.childHandler(() → {
ChannelPipeline p = ch.pipel...
But… is Netty
FAST?
2ms*
* Without network latency
2ms*
Yah but… what
volume are you
talking about?
+10k QPS
1 node*
+3k QPS
*Fou 2.79GHz In e Pen um Xeon P o esso s, 7.5GB RAM
But, is this
ALOT or not?
Parse example
http://blog.parse.com/learn/how-we-moved-our-api-from-ruby-to-go-and-saved-our-sanity/
(From Ruby to Go) A y...
We have 16 nodes!
4x Netty nodes
10x Kafka, DNS, the
usual suspects…
I KNOW IT’S
NOT FAIR,
but it’s good stuff
for your ego BRO
Lovely ecosystem
like Ratpack,
or users,
with vert.x or akka
It will change the
way you program
some of your apps
Hello, Async
problems
Forget about
max onn params
One more thing...
(It’s 5:00 in the
morning and I had
to say it)
(did you notice the
“Apple
background”?)
JUST KIDDING
It doesn’ really
matter!
Have fun!
THANKS
ProTip:
We’re hiring
Q & A
#HiddenTrovitTrac@jordi9
Netty from the trenches
Netty from the trenches
Netty from the trenches
Netty from the trenches
Nächste SlideShare
Wird geladen in …5
×

Netty from the trenches

1.728 Aufrufe

Veröffentlicht am

Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. AND IT'S TRUE!

In this talk given at JBCNConf 2015 in Barcelona, we will see how we use Netty at Trovit since 2013, what brought to us and how it opened our minds. We will share tips that helped us to learn more about Netty, some performance tricks and all things that worked for us.

Veröffentlicht in: Technologie
0 Kommentare
13 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
1.728
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
68
Aktionen
Geteilt
0
Downloads
73
Kommentare
0
Gefällt mir
13
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie
  • NS: Ok, maybe with an image things are easier
  • Ok, kinda… make sense. Keep reading
  • I was looking for a fast webserver?!
    more hype words please
    I think I’m gonna pass, forget it never happened -- Almost happened to me 3 years ago
  • They’re all the same...
  • low-level, input and output (I/O) operations
  • Just to name a few: reading data from a disk drive,
    a remote procedure call (RPC),
    send a file over a network, etc. In general terms, any communication between CPU + memory and any other device is considered I/O.
  • The same goes with write() operations
  • We can say that our program blocks while the communication is in progress.
    This type of I/O is known as blocking I/O or synchronous I/O.
    NS: What’s the problem?
  • The big problem with blocking I/O is that while you’re waiting, you will leave most of your system resources idle. Meaning that your processor will mostly do nothing but to wait that the I/O operations are finished.
  • The big problem with blocking I/O is that while you’re waiting, you will leave most of your system resources idle. Meaning that your processor will mostly do nothing but to wait that the I/O operations are finished.
  • Imagine that for every request you have to handle, you need to read something from the database.
    Your code will block waiting for the database operations to finish every time.
    In that period, you’re dedicating memory and processing time to a thread that it’s only waiting
  • Because of this, typical web servers spawns a new thread for every incoming request to handle more traffic
  • But as you can see, this is not optimal.
    Under stress situations, most of your threads will be consuming more memory and CPU waiting for other operations to finish.
    We can do better...
  • But as you can see, this is not optimal.
    Under stress situations, most of your threads will be consuming more memory and CPU waiting for other operations to finish.
    We can do better...
  • Another approach is to issue an I/O call but not wait until it’s finished
  • As you can imagine, these kind of operations don’t block your program.
    In fact, the call returns immediately to the caller
    NS: and...
  • you’ll be notified once the operation has finished
  • Yup, just like with Dependency Injection
  • Even though, keep in mind that if your tasks depend on having completed an I/O operation, you’d still have to wait for its completion.
    But this time, you won’t be wasting resources just waiting, because other processing that doesn’t depend on I/O can be executed
  • With asynchronous I/O APIs and multithreading we can build more robust, scalable application.
    Async I/O also called NIO, remember first slides
  • Most Operating Systems (OS) nowadays implement many asynchronous calls with different strategies.
    For example, with Unix systems you have polling, signals or select loops, while Windows has support for callback functions.
  • Java and the JVM started to offer integration with package java.nio
    NS: since...
  • 1.4., 2002
  • Java 1.7 introduced a new API for files and more NIO goodies, usually referred as NIO2.
  • The drawback of this approach is that our software will be more complex,
    if you tried to use Selector API you know this
  • You freak dependency-haters
  • The main difference is that in Netty all API definitions are asynchronous in nature, no matter what.
    NS: What does it mean?
  • It is important to be aware of this encapsulation.
    Netty can be used as a general library as a replacement for Java NIO regarding network operations.
    Just like you would use Guava or Apache Commons.
  • These days most of the projects tend to use HTTP for everything, from sending large files to building web service
  • But HTTP is not always the answer to everything.
    Just like email works over SMTP, or non-critical data can be sent via UDP.
    For example, StatsD is a daemon that sends over UDP aggregates of different types of metrics and statistics.
  • More often than you think you can find yourself trying to implement some protocol of your own.
    Think about mobile messaging, real-time exchanges between ad-servers, or you wanting to invoke some remote method in another server, like an RPC
  • From my personal experience, I can confirm that is true in every way.
    It’s really easy to use Netty once you get used to the API.
    Soon you will notice how rapidly you are developing your applications
  • If “implementing a protocol” sounds like too much for you, it’s not.
    Don’t think of it like that.
    You’ll be implementing exactly what you need for your program
    NS: By the way...
  • By the way, most common protocols (HTTP, UDP, SSL…) are supported out-of-the-box, with many more coming.
  • 3 → 4 → 4.1 → 5.0 - Even more basic, day to day things you’ll use, change
  • This protocol defines that a daytime service simply sends the current date and time as a character string without regard to the input

    One daytime service is defined as a connection based application on TCP. A server listens for TCP connections on TCP port 13. Once a connection is established the current date and time is sent out the connection as a ascii character string (and any data received is thrown away). The service closes the connection after sending the quote
  • Handlers in Netty are where you specify your business logic and write the actual application code you’ll need
  • Handlers in Netty are where you specify your business logic and write the actual application code you’ll need
  • A ChannelHandler will handle the operations for that Channel.
    Channel is roughly, a connection
  • Inbound handlers are responsible to handle incoming traffic and dispatch events to the next Handler,
  • outbound handlers do the exact same thing but in the other direction.
  • Before, in version 3 they were known as Upstream and Downstream (like jenkins jobs)
    But it doesn’t stop there
  • Move on. We have our class in place, time to do real work.
  • We need to hook up into some method to do the actual work.
  • But RFC says: “Once a connection is established the current date and time is sent out the connection. “
    Handler has a natural lifecycle, very simplified in Netty 4
  • ByteBuf is a container to hold bytes, with most common operations implemented in ByteBufUtil helper class.
    You may know that the Java offers its own java.nio.ByteBuffer class with the same purpose, but it has too many caveats to stick to it.
    We will see much more about ByteBuf in chapter 4
  • Keep in mind that all of this is done for the sake of performance.
    Netty keeps internal pools to reuse space and prevent too many context switching, memory leaks and other typical problems you would face writing a network application on your own.
  • NS: You know how to run this?
  • Forget about classloaders, logger problems…
    If you want to call this a microservice, be my guest
    I don’t know what to think after fowler’s article about them
  • Similar to JDK’s ExecutorService but with many power-ups.
  • An EventLoopGroup is a multithreaded event loop that will handle I/O operations
  • One EventLoop instance will handle I/O operations for a Channel.

  • Put it in another way
    When we receive a connection, a Channel is registered for that connection, and then it gets assigned to an EventLoop inside the EventLoopGroup.
    Once assigned, that EventLoop is responsible to handle all I/O operations for that connection.
  • This way, we can say that with some EventLoops instances, running always in the same thread, we can handle many Channels
  • If you noticed, this is a big difference with most regular synchronous servers, where a connection is assigned to a thread
    This is the secret behind Netty’s thread model, and what vert.x and others use.
    Vert.x is actually using Netty, with Netty defaults… I believe magic happens there
    It changed for the best since version 3, with a lot of lessons learned. Like context switching is hard
    This is version 4.0, but now with version 4.1 and even 5.0, you can customize it, but following this pattern
    NS: Going back to the example
  • The “boss” group is the one that accepts incoming connections.
    The “worker” group is the one that will handle all the work once a connection is accepted.
    The “boss” group will register and pass the connection to the “worker” group.
  • For the Daytime protocol we need to accept incoming TCP/IP connections, so we need to use a ServerSocketChannel implementation.
    In this case, we are using NioServerSocketChannel, just like the previous NioEventLoopGroup uses NIO Selector to accept new connections.
  • This option will set the maximum queue length for incoming connections.
    If a connection request arrives when the queue is full, the connection is refused.
    What makes this option special is that this restriction is not handled by Netty. It’s not even under JVM’s control.
    It’s a platform-dependent option that the underlying operating system will decide how to handle.
  • If you noticed, this is a big difference with most regular synchronous servers, where a connection is assigned to a thread
    This is the secret behind Netty’s thread model, and what vert.x and others use.
    Vert.x is actually using Netty, with Netty defaults… I believe magic happens there
    It changed for the best since version 3, with a lot of lessons learned. Like context switching is hard
    This is version 4.0, but now with version 4.1 and even 5.0, you can customize it, but following this pattern
    NS: Going back to the example
  • Netty uses a ChannelPipeline to define your application workflow. You may add one or more handlers to the ChannelPipeline
    Every connection received, it will execute this workflow
  • Invoking ChannelPipeline.addLast(), you’re appending handlers at the end and defining the order of execution.
    There are more methods available, but it’s easier to keep it this way
    We’re usin
  • NS: I want to use ChannelFuture to introduce for all the K.I.A that happened here.
  • Netty is HUGE, but when you get all of its concepts, it’s always the same
  • Tons of options, we’re constantly exploring them, try to find what works best
    Here is where your devops team can help you understand them

  • “Understand your domain”, you actually need to understand what’s happening

  • There’s no need to live in the past. You still want all DI goodies
  • It this easy! Instead of using plain news
    We did some paranoid microbenchmarks, and it’s worth it every nano-second
  • We need to respond always below 100ms,
  • You have to measure everything. We use both statsd and caliper
    YourKit or any other profiler is your friend
  • It doesn’t make any sense!
    Please share your configs
  • Even if you’re not using Netty directly
  • Snowball effect
    You’re handling 500 connections per machine → 90 thousand
    You won’t get an OOM error, everything is getting slower (because you’re measuring it in real time)
  • You have to handle this, on your own
  • Something big is coming… and is not the winter
    I’ve seen 2 times the Techempower result tests… it happens to be that I’m a big fan of those results…
    I was surprised about Vert.x being first, and even more surprised being better than Netty
    NS: So, I had to do it...
  • Round 10, April 2015
    Round 9, Round 8… one per year… pretty similar results…
    Where’s vert.x?
  • Netty from the trenches

    1. 1. Netty from the trenches June 2015 @jordi9
    2. 2. Netty…?
    3. 3. Netty is an asynchronous event-driven network application framework
    4. 4. for rapid development of maintainable high performance protocol servers & clients.
    5. 5. Netty is a NIO client server framework which enables quick and easy development of network
    6. 6. applications such as protocol servers and clients. It greatly simplifies and streamlines network
    7. 7. network programming such as TCP and UDP socket server.
    8. 8. OH, MY
    9. 9. The Freaking Basics
    10. 10. You’ve heard of: Async apps
    11. 11. You’ve heard of: Event driven frameworks
    12. 12. You’ve heard of: non-blocking operations
    13. 13. You’ve heard of: Node is cooler because...
    14. 14. I/O
    15. 15. I/O is everywhere
    16. 16. I/O, approx: CPU Memory Device
    17. 17. read()
    18. 18. read() //wait...
    19. 19. read() //wait... keepWorkingBro()
    20. 20. Our program BLOCKS
    21. 21. Resources WASTED
    22. 22. You know what I’m talking about
    23. 23. Webserver Request Database //wait...
    24. 24. OH, Parallelism!
    25. 25. new Thread();
    26. 26. Webserver Request Database //wait...
    27. 27. Webserver Request Database //wait... Request Database //wait...
    28. 28. Webserver Request Database //wait... Request Database //wait... Request Database //wait.
    29. 29. A mess
    30. 30. We can do better
    31. 31. read()
    32. 32. read() keepWorkingBro()
    33. 33. read() keepWorkingBro() //I’m //done!
    34. 34. You (kinda) did this: Listeners
    35. 35. You (kinda) did this: Guava’s EventBus
    36. 36. You (kinda) did this: Javascript callbacks
    37. 37. Hollywood principle “Don’t call us, we’ll call you”
    38. 38. Keep working, instead of waiting
    39. 39. Hi, Async I/O
    40. 40. NIO with Java
    41. 41. java.nio
    42. 42. since 1.4, 2002 java.nio
    43. 43. since 1.7: NIO2 more goodies
    44. 44. Hi, Complexity
    45. 45. Netty to the Rescue
    46. 46. Built on top of: java.nio
    47. 47. Built on top of: java.net
    48. 48. Dependecy-haters: Just JDK 1.6+
    49. 49. ONE big difference
    50. 50. All Netty APIs are async
    51. 51. It’s can be one more tool!
    52. 52. What the hell is Netty for?
    53. 53. Think...
    54. 54. HTTP everywhere
    55. 55. Really BRO?
    56. 56. Maybe, you’re trying to implement a protocol
    57. 57. Finally, hello Netty!
    58. 58. Netty: Tool to implement network applications
    59. 59. Netty: Both from server and client side
    60. 60. Netty: NIO everywhere
    61. 61. Why Netty?
    62. 62. Netty has been designed carefully with the experiences earned from the implementation of
    63. 63. a lot of protocols such as FTP, SMTP, HTTP, and various binary and text-based legacy protocols. As a
    64. 64. protocols. As a result, Netty has succeeded to find a way to achieve...
    65. 65. Ease of development
    66. 66. Performance
    67. 67. Stability
    68. 68. Flexibility
    69. 69. Without a compromise
    70. 70. IT’S TRUE
    71. 71. “Implementing a protocol” NOT THAT HARD
    72. 72. Most common protocols: out-of-the-box
    73. 73. Boring Protocols: HTTP
    74. 74. Boring Protocols: SSL
    75. 75. Boring Protocols: UDP
    76. 76. Cooler Protocols: SPDY
    77. 77. Cooler Protocols: HTTP/2
    78. 78. Cooler Protocols: Protobuf
    79. 79. Even Protocols: Memcache
    80. 80. Not only I/O
    81. 81. Powerful Thread model
    82. 82. But, where’s the downside?
    83. 83. Downers: Constant API changes*
    84. 84. Downers: Constant API changes* *For the best
    85. 85. Downers: Learning curve...
    86. 86. Downers: Learning curve... Buy Netty in Action :P
    87. 87. Downers: Join the mailing list
    88. 88. Downers: Join the mailing list You’ll see how STUPID you are
    89. 89. Downers: Join the mailing list But you’ll learn ALOT ;)
    90. 90. Netty, The Code
    91. 91. Daytime Protocol
    92. 92. The Server
    93. 93. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { } The Hand e
    94. 94. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // Handler = Business Logic } The Hand e
    95. 95. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // ChannelHandler: handles operations // for that Channel, duh } The Hand e
    96. 96. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // Inbound handler: incoming traffic, // dispatch events to next handler // If we have inbound... } The Hand e
    97. 97. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // Outbound handler: same, but the // other direction. Yeah, there’s some // flow between Handlers (eg: Pipeline) } The Hand e
    98. 98. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // Inbound + Outbound... } The Hand e
    99. 99. class SimpleDaytimeHandler extends ChannelInboundHandlerAdapter { // Inbound + Outbound.. // 5.0: DEPRECATED! // [NOTE: Insert a grumpy cat here] } The Hand e
    100. 100. Hand e me hod
    101. 101. @Override public void channelRead( ChannelHandlerContext ctx, Object msg) { // Will trigger when we receive // some data } Hand e me hod
    102. 102. @Override public void channelActive( ChannelHandlerContext ctx, Object msg) { // Will a Channel is opened, this // method will be called } Hand e me hod
    103. 103. @Override public void channelActive(ChannelHandlerContext ctx, Object msg) { String date = DATE_TIME.print(new DateTime()); // Get the date } Hand e wo
    104. 104. @Override public void channelActive(ChannelHandlerContext ctx, Object msg) { String date = DATE_TIME.print(new DateTime()); ctx.writeAndFlush(ByteBufUtil.encodeString( ctx.alloc(), CharBuffer.wrap(date), CharsetUtil.US_ASCII)); } Hand e wo
    105. 105. It’s clear, right? :D
    106. 106. Network standard way of working? byte[]
    107. 107. You said this was fun?
    108. 108. Meet ByteBuf ByteBufUtil
    109. 109. @Override public void channelActive(ChannelHandlerContext ctx, Object msg) { String date = DATE_TIME.print(new DateTime()); ctx.writeAndFlush(ByteBufUtil.encodeString( ctx.alloc(), CharBuffer.wrap(date), CharsetUtil.US_ASCII)); // We need to encode the String } Hand e wo
    110. 110. @Override public void channelActive(ChannelHandlerContext ctx, Object msg) { String date = DATE_TIME.print(new DateTime()); ctx.writeAndFlush(ByteBufUtil.encodeString( ctx.alloc(), CharBuffer.wrap(date), CharsetUtil.US_ASCII)); // We allocate some space // +Netty: Keeps internal pools } Hand e wo
    111. 111. @Override public void channelActive(ChannelHandlerContext ctx, Object msg) { String date = DATE_TIME.print(new DateTime()); ctx.writeAndFlush(ByteBufUtil.encodeString( ctx.alloc(), CharBuffer.wrap(date), CharsetUtil.US_ASCII)); // Write the message // Request to actually flush the data // back to the Channel } Hand e wo
    112. 112. We have our Handler in place
    113. 113. Let’s Bootstrap the server
    114. 114. Ma n ass public class DaytimeServer { void run() throws Exception { // fun stuff } public static void main(String[] args) throws Exception { DaytimeServer daytimeServer = new DaytimeServer(); daytimeServer.run(); } }
    115. 115. java -jar daytimeserver-fat.jar
    116. 116. un() EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup();
    117. 117. E en LoopG oup Netty’s way to handle threads
    118. 118. E en LoopG oup EventLoopGroup contains some EventLoops
    119. 119. E en Loop EventLoop handles many Channels
    120. 120. About to die BRO?
    121. 121. E en LoopG oup E en Loop hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne E en Loop
    122. 122. E en LoopG oup E en Loop hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne hanne E en Loop
    123. 123. This immutable assignment is the key
    124. 124. un() EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup();
    125. 125. un() EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); // Boss group accepts connections // Work group handles the work
    126. 126. Se e Boo s ap ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(8080) .option(ChannelOption.SO_BACKLOG, 100)
    127. 127. Se e Boo s ap ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(8080) .option(ChannelOption.SO_BACKLOG, 100) // We assign both event loops
    128. 128. Se e Boo s ap ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(8080) .option(ChannelOption.SO_BACKLOG, 100) // We use a ServerSocketChannel // to accept TCP/IP connections // as the RFC says
    129. 129. Se e Boo s ap ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(8080) .option(ChannelOption.SO_BACKLOG, 100) // Simply bind the local address
    130. 130. Se e Boo s ap ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .localAddress(8080) .option(ChannelOption.SO_BACKLOG, 100) // Set some Socket options... why not? // Just remember: This is not handled // by Netty or the JVM, it’s the OS
    131. 131. We’re almost there!
    132. 132. hanne P pe ne b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new SimpleDaytimeHandler()); } });
    133. 133. hanne P pe ne b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new SimpleDaytimeHandler()); } }); // ChannelPipeline to define your // application workflow
    134. 134. hanne P pe ne b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new SimpleDaytimeHandler()); } }); // Append our handlers // ProTip: use LoggingHandler to // understand Netty
    135. 135. hanne P pe ne b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new SimpleDaytimeHandler()); } }); // Finally, we add our handler
    136. 136. RUN! b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(new SimpleDaytimeHandler()); } }); ChannelFuture f = b.bind().sync(); f.channel().closeFuture().sync(); // It works!
    137. 137. .I.A. Futures ByteBuf API Codecs Transports Zero-file-copy
    138. 138. We can also create client code
    139. 139. Real life Insights
    140. 140. We’re using Netty for Real-Time Bidding
    141. 141. Boo s ap
    142. 142. Tons o op ons
    143. 143. Don’t be afraid of “low-level”
    144. 144. Ta HTTP
    145. 145. Explore what’s inside Netty
    146. 146. Integrate things you love. In my case: GUICE
    147. 147. Gu e @Inject DaytimeService(Provider<DaytimeServer> daytimeProvider) {} b.childHandler(() → { ChannelPipeline p = ch.pipeline(); p.addLast(new LoggingHandler(LogLevel.INFO)); p.addLast(daytimeProvider.get()); }); // Inject a Provider<T> and get // instances
    148. 148. But… is Netty FAST?
    149. 149. 2ms*
    150. 150. * Without network latency 2ms*
    151. 151. Yah but… what volume are you talking about?
    152. 152. +10k QPS
    153. 153. 1 node* +3k QPS *Fou 2.79GHz In e Pen um Xeon P o esso s, 7.5GB RAM
    154. 154. But, is this ALOT or not?
    155. 155. Parse example http://blog.parse.com/learn/how-we-moved-our-api-from-ruby-to-go-and-saved-our-sanity/ (From Ruby to Go) A year and a half in, at the end of 2012, we had 200 API servers running on m1. xlarge instance types with 24 unicorn workers per instance. This was to serve 3000 requests per second for 60,000 mobile apps
    156. 156. We have 16 nodes! 4x Netty nodes 10x Kafka, DNS, the usual suspects…
    157. 157. I KNOW IT’S NOT FAIR, but it’s good stuff for your ego BRO
    158. 158. Lovely ecosystem like Ratpack, or users, with vert.x or akka
    159. 159. It will change the way you program some of your apps
    160. 160. Hello, Async problems
    161. 161. Forget about max onn params
    162. 162. One more thing...
    163. 163. (It’s 5:00 in the morning and I had to say it)
    164. 164. (did you notice the “Apple background”?)
    165. 165. JUST KIDDING It doesn’ really matter!
    166. 166. Have fun!
    167. 167. THANKS
    168. 168. ProTip: We’re hiring
    169. 169. Q & A #HiddenTrovitTrac@jordi9

    ×