Upgrade to Pro — share decks privately, control downloads, hide ads and more …

From Monolith to Microservices

From Monolith to Microservices

In this talk, We will focus on how to split up an old enterprise application which has become a monolith into microservices. We will examine the pros and cons of doing so and also the best design practices and architecture decisions that will ensure this process is a success.

We will mainly explore how to identify services in your monolithic application, identify seams in your monolith. We will also investigate how to decouple microservices from monoliths and the best practices when doing so. We will also focus on microservices development and DevOps tips.

We will be examining how to extract a monolith application using example PHP microservices that were pulled out of a larger legacy PHP application. I will also investigate some war stories on how Superbalist achieved this and the lessons learned along the way.

At the end of the talk, you will know better how to refactor your monolith and improve your own architecture.

Liam Norman

March 28, 2019
Tweet

More Decks by Liam Norman

Other Decks in Technology

Transcript

  1. About You • Don't know what microservices are? • Have

    a monolith that you want to migrate?
  2. About You • Don't know what microservices are? • Have

    a monolith that you want to migrate? • In the process of migrating a monolith?
  3. About You • Don't know what microservices are? • Have

    a monolith that you want to migrate? • In the process of migrating a monolith? • Building a new architecture with microservices
  4. About You • Don't know what microservices are? • Have

    a monolith that you want to migrate? • In the process of migrating a monolith? • Building a new architecture with microservices • This talk has a little bit for all of you
  5. What are Microservices? Microservices at their core are small, independent,

    autonomous services that work together. • Microservices should be small.
  6. What are Microservices? Microservices at their core are small, independent,

    autonomous services that work together. • Microservices should be small. • Microservices should be independent.
  7. Autonomous • Microservices should be separate entities. • Tight Coupling

    is when you have services which rely on one another.
  8. Autonomous • Microservices should be separate entities. • Tight Coupling

    is when you have services which rely on one another. • Avoid Tight Coupling
  9. Autonomous • Microservices should be separate entities. • Tight Coupling

    is when you have services which rely on one another. • Avoid Tight Coupling • Microservices should communicate with one another via network calls.
  10. "Can you make a change to a microservice and deploy

    it by itself without changing anything else?"
  11. Benefits of Microservices Technology Freedom • Can select the right

    tool for the job • No need to use a one-size-fits all approach as we often use for a monolith.
  12. Benefits of Microservices Technology Freedom • Can select the right

    tool for the job • No need to use a one-size-fits all approach as we often use for a monolith. • Improved performance with correct tool!
  13. Benefits of Microservices Resilience • Avoids cascading failures • Isolated

    services • Separates our application and can degrade gracefully if handled correctly.
  14. Benefits of Microservices Scaling • Easier to scale as we

    can scale smaller independent services.
  15. Benefits of Microservices Scaling • Easier to scale as we

    can scale smaller independent services. • Superbalist moved to microservices as we found it was important to ensure we could handle the load when a large sale occurred or Black Friday occurred.
  16. Benefits of Microservices Ease of Deployment • Deploying monoliths is

    dangerous as they are large-impact, high risk deployments.
  17. Benefits of Microservices Ease of Deployment • Deploying monoliths is

    dangerous as they are large-impact, high risk deployments. • Deploying microservices is safer as we deploy it independently and if we encounter a bug, we know exactly which service is causing it and can rollback.
  18. Benefits of Microservices Composability A system design principle that deals

    with the inter-relationships of components. A highly composable system provides components that can be selected and assembled in various combinations to satisfy specific user requirements. — Wikipedia
  19. Benefits of Microservices Composability A system design principle that deals

    with the inter-relationships of components. A highly composable system provides components that can be selected and assembled in various combinations to satisfy specific user requirements. — Wikipedia • Composable
  20. Benefits of Microservices Composability A system design principle that deals

    with the inter-relationships of components. A highly composable system provides components that can be selected and assembled in various combinations to satisfy specific user requirements. — Wikipedia • Composable • We no longer develop for one application.
  21. No Silver Bullet • Microservices are no silver bullet and

    don't make a good choice for everything.
  22. No Silver Bullet • Microservices are no silver bullet and

    don't make a good choice for everything. • Microservices are great for many scenarios but they come with added complexity.
  23. No Silver Bullet • Microservices are no silver bullet and

    don't make a good choice for everything. • Microservices are great for many scenarios but they come with added complexity. • It depends...
  24. Cons of Microservices • Added complexity in deployments • Added

    complexity in managing logging and monitoring.
  25. Cons of Microservices • Added complexity in deployments • Added

    complexity in managing logging and monitoring. • How to properly prevent cascading failure and degrade gracefully.
  26. Setting the Scene • Creating a simple order management system

    with a product microservices. • We will be using Laravel, Docker and Loggly.
  27. Bounded Contexts Bounded contexts, What does that mean? • Any

    given domain consists of multiple bounded contexts
  28. Bounded Contexts Bounded contexts, What does that mean? • Any

    given domain consists of multiple bounded contexts • A bounded context is defined as “a specific responsibility enforced by explicit boundaries.”
  29. Bounded Contexts • Not sharing internal representations reduces tight coupling

    • Bounded contexts lend themselves well to identifying boundaries, especially in code.
  30. Bounded Contexts • Not sharing internal representations reduces tight coupling

    • Bounded contexts lend themselves well to identifying boundaries, especially in code. • Bounded contexts become excellent candidates for microservices.
  31. Seams • A seam is a portion of code that

    can be treated in isolation and worked on without impacting the rest of the codebase.
  32. Seams • A seam is a portion of code that

    can be treated in isolation and worked on without impacting the rest of the codebase. • To break up a monolith, we must find seams.
  33. Seams • A seam is a portion of code that

    can be treated in isolation and worked on without impacting the rest of the codebase. • To break up a monolith, we must find seams. • Bounded contexts make great seams because they are cohesive and loosely coupled.
  34. Splitting into Packages • Orders - for managing orders, order

    items, orders placed • Products - for managing products, product stock
  35. Splitting into Packages • Orders - for managing orders, order

    items, orders placed • Products - for managing products, product stock
  36. Splitting into Packages • Orders - for managing orders, order

    items, orders placed • Products - for managing products, product stock • Users - for managing users and user information
  37. Slow Down • This process could be quick or several

    weeks, months etc... • Rather look at splitting the codebase accurately into viable packages.
  38. Evolutionary Architecture and Microservices • It is difficult to change

    architecture once implemented. • Evolutionary architecture is a terminology created by Rebeca Parsons, Patrick Kua and Neal Ford. It refers to architecture which has the ability to change over time.
  39. Evolutionary Architecture and Microservices • It is difficult to change

    architecture once implemented. • Evolutionary architecture is a terminology created by Rebeca Parsons, Patrick Kua and Neal Ford. It refers to architecture which has the ability to change over time. • Microservices enables this in an incremental way.
  40. Methodology to Split Out the Microservice 1. Establish the bounded

    contexts and the seams 2. Identify code to split out and group into Packages
  41. Methodology to Split Out the Microservice 1. Establish the bounded

    contexts and the seams 2. Identify code to split out and group into Packages 3. Create the Microservice to accomplish same functionality
  42. Methodology to Split Out the Microservice 1. Establish the bounded

    contexts and the seams 2. Identify code to split out and group into Packages 3. Create the Microservice to accomplish same functionality 4. Direct traffic to microservices
  43. Methodology to Split Out the Microservice 1. Establish the bounded

    contexts and the seams 2. Identify code to split out and group into Packages 3. Create the Microservice to accomplish same functionality 4. Direct traffic to microservices 5. Retire old code in Monolith
  44. Problems with the Monolithic Database Design • A monolith DB

    is a single point of failure • Bad for data retrieval and performance over time
  45. Problems with the Monolithic Database Design • A monolith DB

    is a single point of failure • Bad for data retrieval and performance over time • Constraints to one type of database
  46. Finding seams in your Database • Equally important as seams

    in application layer • Ensure each microservice has the data they need and doesn't need to make unnecessary API calls
  47. Installing SchemaSpy apt-get install graphviz java -jar schemaspy.jar -t mysql

    -dp /users/liamnorman/sqljdbc4-3.0.jar -db products -host 127.0.0.1 -port 3306 -u testuser -p mygreatpassword -o /users/liamnorman/schemaspyoutput
  48. The Database Split • Break parts of your database into

    smaller databases • Easy to revert, only retire old tables after split and microservice is running
  49. The Database Split • Break parts of your database into

    smaller databases • Easy to revert, only retire old tables after split and microservice is running • Split database first
  50. Data Integrity and Event Sourcing • There are multiple approaches

    to this problem such as event bus, distributed transactions, syncs etc...
  51. Data Integrity and Event Sourcing • There are multiple approaches

    to this problem such as event bus, distributed transactions, syncs etc... • I recommend an Event Bus (event sourcing) approach - each service sends events for its changes and the interested parties listen and save the info as needed. This is often implemented with PubSub and events-based architecture.
  52. Data Integrity and Event Sourcing • There are multiple approaches

    to this problem such as event bus, distributed transactions, syncs etc... • I recommend an Event Bus (event sourcing) approach - each service sends events for its changes and the interested parties listen and save the info as needed. This is often implemented with PubSub and events-based architecture. • Multiple PubSub providers such as Google PubSub, AWS SNS, Socket Cluster etc...
  53. Data Integrity and Event Sourcing • There are multiple approaches

    to this problem such as event bus, distributed transactions, syncs etc... • I recommend an Event Bus (event sourcing) approach - each service sends events for its changes and the interested parties listen and save the info as needed. This is often implemented with PubSub and events-based architecture. • Multiple PubSub providers such as Google PubSub, AWS SNS, Socket Cluster etc...
  54. Crafting our Microservices Application • We are going to build

    a simple order management system with a product Microservice in PHP 7 using Laravel 5.
  55. Crafting our Microservices Application • We are going to build

    a simple order management system with a product Microservice in PHP 7 using Laravel 5. • We are going to focus on the product Microservice in the system.
  56. App Toolbox • PHP 7 • Composer • Laravel 5

    • Docker • Monolog • Loggly
  57. Setting up Docker version: "3" services: app: image: laravel-www container_name:

    product-api build: context: . dockerfile: docker/Dockerfile depends_on: - mysql env_file: - .docker.env volumes: - .:/var/www/html networks: - frontend_oms ports: - 8081:80 environment: APP_ENV: local CONTAINER_ROLE: app
  58. Setting up Docker mysql: container_name: product-mysql image: mysql:5.7 ports: -

    13307:3306 volumes: - mysql:/var/lib/mysql environment: MYSQL_DATABASE: homestead MYSQL_ROOT_PASSWORD: root MYSQL_USER: homestead MYSQL_PASSWORD: secret volumes: mysql: driver: "local" networks: frontend_oms: external: true
  59. Docker Up and Running docker-compose build && docker- compose up

    -d e1576be47250 laravel-www "docker-php-entrypoi…" 4 seconds ago Up 2 seconds 9000/tcp, 0.0.0.0:8081->80/tcp product-api 474a6cb3928f mysql:5.7 "docker-entrypoint.s…" 7 minutes ago Up 4 seconds 0.0.0.0:13307->3306/tcp product-mysql 097314bbe4f9 80c639ead8df "docker-php-entrypoi…" 8 minutes ago Up 8 minutes 80/tcp, 9000/tcp frontend-scheduler a8fb0eac2298 80c639ead8df "docker-php-entrypoi…" 8 minutes ago Up 8 minutes 80/tcp, 9000/tcp frontend-queue 2d62d7fa1b7c 80c639ead8df "docker-php-entrypoi…" 8 minutes ago Up 8 minutes 9000/tcp, 0.0.0.0:8080->80/tcp frontend-www 349b26ec6e4a mysql:5.7 "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:13306->3306/tcp frontend-mysql b2a42fd78a1d redis:4-alpine "docker-entrypoint.s…" 8 minutes ago Up 8 minutes 0.0.0.0:16379->6379/tcp frontend-redis
  60. Product Migrations <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class

    CreateProductsTable extends Migration { public function up() { Schema::create('products', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('slug'); $table->bigInteger('price'); $table->integer('quantity'); $table->string('image'); $table->timestamps(); }); } public function down() { Schema::dropIfExists('products'); } }
  61. Routes // Routes for Product CRUD Route::get('/products', 'ProductController@index')->name('products.index'); Route::post('/products', 'ProductController@store')->name('products.store');

    Route::get('/products/{slug}', 'ProductController@show')->name('products.show'); Route::get('/products/{slug}/delete', 'ProductController@delete')->name('products.delete');
  62. Product Controller <?php namespace App\Http\Controllers; use App\Product; use Illuminate\Http\Request; class

    ProductController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $products = Product::all(); return response()->json($products); } }
  63. Product Controller /** * Display the specified resource. * *

    @param string $slug * @return \Illuminate\Http\Response */ public function show($slug) { $product = Product::where('slug', '=', $slug)->get()->first(); if (empty($product)) { return response()->json([ 'message' => 'Product not found', ], 404); } // check product is in stock if ($product->quantity <= 0) { return response()->json([ 'message' => 'Product not in stock', ], 200); } return response()->json($product); }
  64. Product Controller /** * Delete a product * @param $slug

    * @return \Illuminate\Http\JsonResponse */ public function delete($slug) { $product = Product::where('slug', '=', $slug)->get()->first(); if (empty($product)) { return response()->json([ 'message' => 'Product not found', ], 404); } $product->delete(); return response()->json([], 200); }
  65. Setting Up Distributed Logging // in config/services.php 'loggly' => [

    'key' => 'MY LOGGLY TOKEN', 'tag' => 'microshop' .strtolower(env('APP_ENV')), ], // in bootstrap/app.php $app->configureMonologUsing(function($monolog) { $handler = new \Monolog\Handler\LogglyHandler(config('services.loggly.key'),\Monolog\Logger::DEBUG); $handler->setTag(config('services.loggly.tag')); $monolog->pushHandler($handler); }); Log::info('received products', $products)
  66. Superbalist War Stories • Monitoring microservices is difficult. It creates

    overhead/ management. For each project you need to have insight, logging and metrics. If you have multiple teams working on different services with different standards then this can be a pain point. It is important to have standardisation.
  67. Superbalist War Stories • Monitoring microservices is difficult. It creates

    overhead/ management. For each project you need to have insight, logging and metrics. If you have multiple teams working on different services with different standards then this can be a pain point. It is important to have standardisation. • The greatest benefit from an application standpoint is separation of concerns, single purpose systems and isolation.
  68. Superbalist War Stories • Microservices ultimately take longer to develop

    and start. A monolith isn't a bad thing when trying to meet a deadline. It is much easier to start with a monolith and migrate to a microservices based architecture.
  69. Superbalist War Stories • Microservices ultimately take longer to develop

    and start. A monolith isn't a bad thing when trying to meet a deadline. It is much easier to start with a monolith and migrate to a microservices based architecture. • Moving to microservices greatly boosted developer productivity as each team had more responsibility over their projects and were less bogged down by obscure code in the monolith.