atmosphere 2014: let's build a solid base for a scale. - krzysztof debski
DESCRIPTION
Creating fast, reliable and easy to develop system is not an easiest task. If you add thousands of companies using your system as a core business platform on a daily basis, it becomes challenging. Add a flavour of a scalability and millions of users and it will be exciting. How to prepare a system that might be affected by scalability issues everywhere? Even in a simplest component. The answer is to dive deep into the world of services. We decided to prepare a strong base on top of which we can build our system. Our choice was to start with the Java stack. We've gathered all cool stuff from open source project to create bootstrap to let our developers create scalable services really fast. In a talk I would like to focus with you about all the choices we made, we will discuss about all the ecosystem we built over services. It is not only about the code we write, but all the tools that make our life easier. We will look at frameworks to provide REST services, see how to make them auto discoverable. We will also discuss tools to let us monitor and manage all the instances, etc. If you want to create or upgrade your service to scale it is the best place to start. Krzysztof Debski - Technical enthusiast, software engineer and product owner of Service Bootstrap developed in Allegro . Gained software experience in the biggest polish web companies – Onet.pl and Allegro.pl. He has a lot of experience in designing and building modern, scalable web systems. He is open to all new technologies an programming languages and he has no fear to work on legacy systems and rewrite it in modern way.TRANSCRIPT
@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 developers
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