Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

It’s Over 9000! Neo4j on WebSockets

DZone's Guide to

It’s Over 9000! Neo4j on WebSockets

· Performance Zone ·
Free Resource

SignalFx is the only real-time cloud monitoring platform for infrastructure, microservices, and applications. The platform collects metrics and traces across every component in your cloud environment, replacing traditional point tools with a single integrated solution that works across the stack.

it__s_over_9000_

In the last blog post we managed to run Neo4j at Ludicrous Speed over http using Undertow and get to about 8000 requests per second. If we needed more speed we can scale up the server or we can scale out to multiple servers by switching out the GraphDatabaseFactory and using the HighlyAvailableGraphDatabaseFactory class instead in Neo4j Enterprise Edition.

But can we go faster on a single server without new hardware? Well… yes, if we’re willing to drop http and switch to Web Sockets.

WebSocket is a protocol providing full-duplex communications channels over a single TCP connection…allowing for messages to be passed back and forth while keeping the connection open.

Sounds complicated? It’s not, we can add it to our existing Undertow server with 18 more lines of code. No really:

.addPath("/websocket", websocket(new WebSocketConnectionCallback() {
    @Override
    public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) {
        channel.getReceiveSetter().set(new AbstractReceiveListener() {
            @Override
            protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {
                String data = message.getData();
                try {
                    List<Map<String, AtomicInteger>> results = getCrossReferences(data);
                    WebSockets.sendBinary(ByteBuffer.wrap(objectMapper.writeValueAsBytes(results)), channel, null);
                } catch (IOException e) {
                    WebSockets.sendText("Error:" + e.toString(), channel, null);
                }
            }
        });
        channel.resumeReceives();
    }
})

We are adding a “/websocket” endpoint to our existing Undertow server that: 1. sets up a channel 2. performs the CrossReference query we’ve seen before when it receives a message and 3. sends the results back. So let’s test this out. I believe Gatling 2.0 has web socket testing integrated, but I’m still using 1.5.3, so we’ll borrow the Gatling Web Sockets Library from Andrew Duffy. To use it, we’ll just compile it and add it to the lib directory of our performance testing project. Let’s create a new web socket test for this that looks very similar to our previous http test:

class TestCrossReferenceWebSocket extends Simulation {
 
  val testfile = csv("test-data.txt").circular
 
  val scn = scenario("Cross Reference via WebSocket")
    .exec(websocket("socket").open("ws://localhost:7474/websocket", "socket_open"))
    .during(30) {
      feed(testfile)
      .exec(websocket("socket")
        .sendMessage("""{"cc": "${cc}", "phone": "${phone}", "email": "${email}", "ip": "${ip}" }""",
          "socket_send"))
        .pause(0 milliseconds, 1 milliseconds)
    }
    .exec(websocket("socket").close("socket_close")
  )
 
  setUp(scn.users(16))
}

Each simulated user will open a connection to the server, spend 30 seconds reading test data from a file, sending requests to the server, and finally it will close the connection once it’s done. Let’s fire it up and oh my…

Screen Shot 2014-03-09 at 3.34.57 PM

Zoom in on that… 28 thousand requests per second… on my laptop. That’s 3.5 times as many requests as last time, and about 22 times what we started out with. Before you even ask, of course you can go faster still if you switch out JSON for a binary serialization format, but I’ll leave that as an exercise for the reader since there are so many of them. Feel free to fork this project on Github and have a go at it.

If you want to try sending Cypher over Web Sockets in MessagePack, you can also take a look at Michael Hunger‘s Cypher Websocker Endpoint project on Github. If ZeroMQ is more your thing, Nigel Small has his ZeroGraph project.


SignalFx is built on a massively scalable streaming architecture that applies advanced predictive analytics for real-time problem detection. With its NoSample™ distributed tracing capabilities, SignalFx reliably monitors all transactions across microservices, accurately identifying all anomalies. And through data-science-powered directed troubleshooting SignalFx guides the operator to find the root cause of issues in seconds.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}