AtmosphereConf - Let's build a solid base for a scale

Preview:

Citation preview

@DebskiChris

#AtmosphereConf

Krzysztof Dębski Allegro Group

Let’s build a solid base for a scale

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Agenda

The Allegro Situation How to build a new World? The way to improve What’s in it for you?

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

The Allegro Situation

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Allegro

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Allegro

6 million LOC

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

400 people in IT

Allegro

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

A New Hope

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

A New Hope

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

A New Hope

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

A New Hope?

Service

Oriented

Ambiguity

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Domain Driven Design

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

(Micro)Services

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

(Micro)Services

Business needs Offer

User

Transaction

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

(Micro)Services

Offer

User

Transaction

Independent

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

(Micro)Services

API Offer

User

Transaction

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

(Micro)Services

Polyglot

Cassandra

MongoDB

Oracle

Offer

User

Transaction

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

(Micro)Services

Smart Endpoints

Cassandra

MongoDB

Oracle

Offer

User

Transaction

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

The first approach

Service

Auto deployable Monitored Auto scalable Auto healable Auto discoverable

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

How to build a new World?

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

The first project

Gradle Spring External Jetty server

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Let’s REST

JAX-RS / JSR Compliant @Path("/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {

// [...] @GET public UserCollectionResponse findAllUsers() { //[...] }

}

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Let’s expose our methods

Swagger @Path("/users") @Api(value = "/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {

// [...] @ApiOperation(value=“Get all users”, response=UserCollectionResponse.class) @GET public UserCollectionResponse findAllUsers() { //[...] }

}

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Let’s expose our methods

Swagger

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

And make them discoverable

Offer

User

Discovery ZooKeeper  

Register  

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

And make them discoverable

Offer

User

Discovery ZooKeeper  

Get  User  

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

And make them discoverable

Offer

User

Discovery ZooKeeper  

Get  User  

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

And make them discoverable

Offer

User

Discovery ZooKeeper  

Get  User  Get  off

er  for  user  

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Multiple API versions

Header support public class UserMediaType {

public static final String V1_JSON = "application/vnd.allegro.user.v1+json” public static final String V2_JSON = "application/vnd.allegro.user.v2+json”

}

curl --dump-header - -H ”Accept: application/vnd.allegro.user.v2+json" -X GET http://localhost:8080/users

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Multiple API versions

Content negotiation @Path("/users") @Consumes(AllegroUserMediaType.V1_JSON) @Produces(AllegroUserMediaType.V1_JSON) public class UsersEndpoint {

// [...] @GET @Produces(AllegroUserMediaType.V2_JSON) public UserCollectionResponse findAllUsers() { //[...] }

}

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

How to configure it?

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

How to configure it?

Zookeper Environment properties Command-line options

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

And it became slow

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Lower startup time

External Jetty Embedded Jetty Embedded UnderTow

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Easier deployment

Cargo deployment Built to zip package On immutable images

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

Tests

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Do you test your tests?

Pitest

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Integration tests

Test without mocks Run from IDE

public class UsersIntegrationTest {

private static Map<String, String> overrideConfiguration = Maps.newHashMap();

static { overrideConfiguration.put("property.name", "This was overwritten value"); }

@ClassRule public static final RestServiceStarted DEPLOYED_SERVICE = new RestServiceStarted(overrideConfiguration);

private WebTarget getUsersResourceWebTarget() { return DEPLOYED_SERVICE.getWebTarget().path("users"); }

}

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

Monitoring

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Let’s see what happens

LogStash Kibana NxLog

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Let’s see what happens

Graphite # Metrics metrics.reporters.graphite.enabled=true metrics.reporters.graphite.host=graphite.service metrics.reporters.graphite.port=2003 metrics.reporters.graphite.prefix=stats.Prod.service metrics.reporters.interval=30

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

Monolith Alert

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Monolith Alert

Multi module project support

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

The way to improve

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Authentication

OAuth2

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Patch Support

Standardized by IETF https://tools.ietf.org/html/rfc6902

PATCH /user/1 HTTP/1.1 Host: user.service.local Content-Length: 312

Content-Type: application/json-patch+json [

{”op”: ”test”, ”path”: ”/firstname”, ”value”: ”Jane”}, {”op”: ”add”, ”path”: ”/maidenname”, ”value”: ”Smith”}, {”op”: ”replace”, ”path”: ”/lastname”, ”value”: ”Doe”},

{”op”: ”remove", ”path”: ”/meetings”}, {”op”: ”move”, ”from”: ”/balance”, ”path”: ”sharedbalance”}, {”op”: ”copy”, ”from”: ”/a”, ”path”: ”/b”}

]

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Simplify annotations

Swagger? @Path("/users") @Api(value = "/users") @Consumes(CONTENT_TYPE_JSON) @Produces(CONTENT_TYPE_JSON) public class UsersEndpoint {

// [...] @ApiOperation(value=“Get all users”, response=UserCollectionResponse.class) @GET public UserCollectionResponse findAllUsers() { //[...] }

}

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Deployment

Docker support

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

What’s in it for you?

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Use the latest tools

GradleW issue in Continuous Integration Environment and parent POM issues. Don’t do DDOS yourself and your partners’ sites.

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Change is the only constant

HTTP Server Service API provider Dependency injection engine Deployment tools

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Focus on right metrics

import org.junit.Test;

import static net.trajano...

public class MediaTypesTest {

@Test public void mediaTypesShouldBeValidUtilityClasses()

throws Throwable { assertUtilityClassWellDefined(UserMediaType.class); } }

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Tools also lie

Metrics tend to lie – Default PHP metrics in SonarQube – Tested file

•  4535 CLOC •  Whole code written using imperative programming

How many violations are there?

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Tools also lie

How many violations are there?

4 At least according to Sonar

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Learn to REST

REST is not so obvious

/api/bi/XYZ123/1

/recommendations/1/items

/offer/100?output=ESI/JSON

#AtmosphereConf @DebskiChris Allegro The New World Improvement WIIFY

Community

Involve all developers in building the Bootstrap. Or they will build their own tools.

Łukasz Drumiński Mateusz Gajewski @wendigo

Allegro The New World Improvement WIIFY #AtmosphereConf @DebskiChris

Q & A