-
-
Notifications
You must be signed in to change notification settings - Fork 26.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Finished the Microservice Architecture #2759
Closed
Closed
Changes from 7 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
2bb3e82
Test
OscarXWei cde6f27
Finish Microservice Architecture build
OscarXWei 8ea4a1c
Finish Microservice Architecture build
OscarXWei 8756199
Add readme
OscarXWei 7c13f11
Add tests for each class
OscarXWei 44679f3
Merge remote-tracking branch 'origin/master'
OscarXWei 82fcc18
Merge branch 'iluwatar:master' into master
OscarXWei e202f3b
Merge branch 'master' into master
iluwatar File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,220 @@ | ||
--- | ||
title: Microservice Architecture | ||
category: Architectural | ||
language: en | ||
tag: | ||
- Service Oriented | ||
- Scalability | ||
- Microservices | ||
--- | ||
## Intent | ||
|
||
Microservice Architecture breaks down a monolithic application into smaller, loosely coupled services that can be developed, deployed, and scaled independently.[1] | ||
|
||
## Explanation | ||
|
||
Real world example | ||
|
||
> Imagine a large e-commerce platform. Instead of a single large application managing everything - user management, product catalog, order processing, and payment - the Microservice Architecture divides these into individual services. Each service focuses on a specific domain, possesses its own database, and communicates via APIs. | ||
|
||
In plain words | ||
|
||
> Microservice Architecture dissects an application into mini services. Each embodies its domain logic, data storage, and has distinct ways to communicate. | ||
|
||
Wikipedia says | ||
|
||
> A microservice architecture is a variant of the service-oriented architecture structural style. It is an architectural pattern that arranges an application as a collection of loosely coupled, fine-grained services, communicating through lightweight protocols.[2] | ||
|
||
|
||
**Programmatic Example** | ||
It is difficult to use code to reflect microservices alone. Microservices are not only in the structure of code, but also in deployment, operation and maintenance, isolation, service discovery, load balancing, communication and data independence. | ||
|
||
Expanding on the e-commerce example, let's delve deeper into several services: | ||
|
||
1. **User Management Service** | ||
|
||
```java | ||
|
||
|
||
@RestController | ||
@RequestMapping("/users") | ||
public class UserController { | ||
|
||
@Autowired | ||
private UserRepository userRepository; | ||
|
||
@PostMapping | ||
public User createUser(@RequestBody User user) { | ||
return userRepository.save(user); | ||
} | ||
|
||
@GetMapping("/{userId}") | ||
public User getUser(@PathVariable Long userId) { | ||
return userRepository.findById(userId).orElse(null); | ||
} | ||
|
||
@PutMapping("/{userId}") | ||
public User updateUser(@PathVariable Long userId, @RequestBody User user) { | ||
User existingUser = userRepository.findById(userId).orElse(null); | ||
if (existingUser != null) { | ||
existingUser.updateFrom(user); | ||
return userRepository.save(existingUser); | ||
} | ||
return null; // or throw an exception | ||
} | ||
|
||
@DeleteMapping("/{userId}") | ||
public void deleteUser(@PathVariable Long userId) { | ||
userRepository.deleteById(userId); | ||
} | ||
} | ||
|
||
``` | ||
|
||
2. **Product Catalog Service** | ||
|
||
```java | ||
@RestController | ||
@RequestMapping("/products") | ||
public class ProductController { | ||
|
||
@Autowired | ||
private ProductRepository productRepository; | ||
|
||
@PostMapping | ||
public Product createProduct(@RequestBody Product product) { | ||
return productRepository.save(product); | ||
} | ||
|
||
@GetMapping("/{productId}") | ||
public Product getProduct(@PathVariable Long productId) { | ||
return productRepository.findById(productId).orElse(null); | ||
} | ||
|
||
@PutMapping("/{productId}") | ||
public Product updateProduct(@PathVariable Long productId, @RequestBody Product product) { | ||
Product existingProduct = productRepository.findById(productId).orElse(null); | ||
if (existingProduct != null) { | ||
existingProduct.updateFrom(product); | ||
return productRepository.save(existingProduct); | ||
} | ||
return null; | ||
} | ||
|
||
@DeleteMapping("/{productId}") | ||
public void deleteProduct(@PathVariable Long productId) { | ||
productRepository.deleteById(productId); | ||
} | ||
} | ||
``` | ||
|
||
3. **Order Processing Service** | ||
|
||
```java | ||
@RestController | ||
@RequestMapping("/orders") | ||
public class OrderController { | ||
|
||
@Autowired | ||
private OrderRepository orderRepository; | ||
|
||
@Autowired | ||
private ProductClient productClient; //Remote call of Product microservice. | ||
|
||
@PostMapping | ||
public Order createOrder(@RequestBody Order order) { | ||
//Retrieve product information from Product microservice | ||
Product product = productClient.getProduct(order.getProductId()); | ||
return orderRepository.save(order); | ||
} | ||
|
||
@GetMapping("/{orderId}") | ||
public Order getOrder(@PathVariable Long orderId) { | ||
return orderRepository.findById(orderId).orElse(null); | ||
} | ||
|
||
@PutMapping("/{orderId}") | ||
public Order updateOrder(@PathVariable Long orderId, @RequestBody Order order) { | ||
Order existingOrder = orderRepository.findById(orderId).orElse(null); | ||
if (existingOrder != null) { | ||
existingOrder.updateFrom(order); | ||
return orderRepository.save(existingOrder); | ||
} | ||
return null; | ||
} | ||
|
||
@DeleteMapping("/{orderId}") | ||
public void deleteOrder(@PathVariable Long orderId) { | ||
orderRepository.deleteById(orderId); | ||
} | ||
} | ||
|
||
``` | ||
|
||
4. **Inventory Service** | ||
|
||
```java | ||
@RestController | ||
@RequestMapping("/inventory") | ||
public class InventoryController { | ||
|
||
@Autowired | ||
private InventoryRepository inventoryRepository; | ||
|
||
@PostMapping | ||
public Inventory addInventory(@RequestBody Inventory inventory) { | ||
return inventoryRepository.save(inventory); | ||
} | ||
|
||
@GetMapping("/{productId}") | ||
public Inventory getInventory(@PathVariable Long productId) { | ||
return inventoryRepository.findByProductId(productId).orElse(null); | ||
} | ||
|
||
@PutMapping("/{productId}") | ||
public Inventory updateInventory(@PathVariable Long productId, @RequestBody Inventory inventory) { | ||
Inventory existingInventory = inventoryRepository.findByProductId(productId).orElse(null); | ||
if (existingInventory != null) { | ||
existingInventory.updateFrom(inventory); | ||
return inventoryRepository.save(existingInventory); | ||
} | ||
return null; | ||
} | ||
|
||
@DeleteMapping("/{productId}") | ||
public void deleteInventory(@PathVariable Long productId) { | ||
inventoryRepository.deleteByProductId(productId); | ||
} | ||
} | ||
``` | ||
|
||
Each of these services would have its own logic, database operations, and could even be developed using different technologies tailored for the specific service's needs. | ||
|
||
Communication between services can be established using REST APIs, message brokers, or other communication protocols. | ||
|
||
## Class diagram | ||
|
||
![alt text](./microservice-architecture/etc/microservice-architecture.png "Microservice Architecture") | ||
|
||
## Applicability | ||
|
||
Use the Microservice Architecture when: | ||
|
||
- Individual parts of your application need to be scaled separately. | ||
- You have a large development team, desiring concurrent development and deployment of distinct services. | ||
- Aiming for high availability and resilience. | ||
- Wishing to utilize diverse technologies and languages within various services. | ||
|
||
## Known issues | ||
|
||
- Service communication and coordination complexity. | ||
- Distributed system challenges: network latency, fault tolerance, and data synchronization. | ||
- The necessity for proficient monitoring and logging to troubleshoot across services. | ||
|
||
## Credits | ||
|
||
* [1][What are microservices?](https://www.ibm.com/topics/microservices) | ||
* [2][Microservices on Wikipedia](https://en.wikipedia.org/wiki/Microservices) | ||
|
||
|
||
--- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.iluwatar</groupId> | ||
<artifactId>java-design-patterns</artifactId> | ||
<version>1.26.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<artifactId>microservice-architecture</artifactId> | ||
|
||
<properties> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-web</artifactId> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.springframework.boot</groupId> | ||
<artifactId>spring-boot-starter-data-jpa</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-web</artifactId> | ||
</dependency> | ||
<!-- Spring Core --> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-core</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-beans</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-context</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.testng</groupId> | ||
<artifactId>testng</artifactId> | ||
<version>7.1.0</version> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-api</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-test</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-junit-jupiter</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
|
||
|
||
<!-- Now, you don't need to specify a version here --> | ||
</dependencies> | ||
|
||
</project> |
18 changes: 18 additions & 0 deletions
18
microservice-architecture/src/main/java/com/iluwatar/microservice/architecture/App.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.iluwatar.microservice.architecture; | ||
|
||
import org.springframework.boot.SpringApplication; | ||
import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, above the main class, we need to describe the pattern and explain how the code implement it |
||
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class }) | ||
public class App { | ||
/** | ||
* Program entry point. | ||
* | ||
* @param args command line args | ||
*/ | ||
|
||
public static void main(String[] args) { | ||
SpringApplication.run(App.class, args); | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
...ice-architecture/src/main/java/com/iluwatar/microservice/architecture/ConsumeService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.iluwatar.microservice.architecture; | ||
|
||
import org.springframework.stereotype.Service; | ||
|
||
@Service | ||
public class ConsumeService { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it be |
||
private final Consumer consumer = new Consumer(); | ||
|
||
public String createConsumer() { | ||
return consumer.create(); | ||
} | ||
|
||
public String findConsumer(Long consumerId) { | ||
return consumer.find(consumerId); | ||
} | ||
|
||
public String modifyConsumer(Long consumerId, String details) { | ||
return consumer.modify(consumerId, details); | ||
} | ||
|
||
public String deleteConsumer(Long consumerId) { | ||
return consumer.delete(consumerId); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
microservice-architecture/src/main/java/com/iluwatar/microservice/architecture/Consumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.iluwatar.microservice.architecture; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
public class Consumer { | ||
private final Map<Long, String> consumers = new HashMap<>(); | ||
private long currentId = 0; | ||
|
||
public String create() { | ||
currentId++; | ||
consumers.put(currentId, "Sample Consumer Details for ID: " + currentId); | ||
return "Consumer Created with ID: " + currentId; | ||
} | ||
|
||
public String find(Long consumerId) { | ||
return consumers.getOrDefault(consumerId, "Consumer not found"); | ||
} | ||
|
||
public String modify(Long consumerId, String details) { | ||
if (consumers.containsKey(consumerId)) { | ||
consumers.put(consumerId, details); | ||
return "Modified consumer with ID: " + consumerId; | ||
} | ||
return "Consumer not found"; | ||
} | ||
|
||
public String delete(Long consumerId) { | ||
if (consumers.containsKey(consumerId)) { | ||
consumers.remove(consumerId); | ||
return "Deleted consumer with ID: " + consumerId; | ||
} | ||
return "Consumer not found"; | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These lines not needed, they come from the parent