Microservices pdf download






















How do I make my projects successful? About The Book Microservices Patterns teaches you 44 reusable patterns to reliably develop and deploy production-quality microservices-based applications. This invaluable set of design patterns builds on decades of distributed system experience, adding new patterns for composing services into systems that scale and perform under real-world conditions.

More than just a patterns catalog, this practical guide with worked examples offers industry-tested advice to help you design, implement, test, and deploy your microservices-based application. What You Will Learn How and why!

Examples are in Java. Table of Contents Escaping monolithic hell Decomposition strategies Interprocess communication in a microservice architecture Managing transactions with sagas Designing business logic in a microservice architecture Developing business logic with event sourcing Implementing queries in a microservice architecture External API patterns Testing microservices: part 1 Testing microservices: part 2 Developing production-ready services Deploying microservices Refactoring to microservices.

Many enterprises have adopted this approach to achieve agility and the continuous delivery of applications to gain a competitive advantage. This book will take you through different design patterns at different stages of the microservice application development along with their best practices.

Microservice Patterns and Best Practices starts with the learning of microservices key concepts and showing how to make the right choices while designing microservices. You will then move onto internal microservices application patterns, such as caching strategy, asynchronism, CQRS and event sourcing, circuit breaker, and bulkheads.

As you progress, you'll learn the design patterns of microservices. The book will guide you on where to use the perfect design pattern at the application development stage and how to break monolithic application into microservices. You will also be taken through the best practices and patterns involved while testing, securing, and deploying your microservice application.

At the end of the book, you will easily be able to create interoperable microservices, which are testable and prepared for optimum performance. What you will learn How to break monolithic application into microservices Implement caching strategies, CQRS and event sourcing, and circuit breaker patterns Incorporate different microservice design patterns, such as shared data, aggregator, proxy, and chained Utilize consolidate testing patterns such as integration, signature, and monkey tests Secure microservices with JWT, API gateway, and single sign on Deploy microservices with continuous integration or delivery, Blue-Green deployment Who this book is for This book is for architects and senior developers who would like implement microservice design patterns in their enterprise application development.

The book assumes some prior programming knowledge. Rather than simply advocating for the use the microservice architecture, this clearly-written guide takes a balanced, pragmatic approach, exploring both the benefits and drawbacks.

About the Technology Successfully developing microservices-based applications requires mastering a new set of architectural insights and practices. In this unique book, microservice architecture pioneer and Java Champion Chris Richardson collects, catalogues, and explains 44 patterns that solve problems such as service decomposition, transaction management, querying, and inter-service communication.

About the Book Microservices Patterns teaches you how to develop and deploy production-quality microservices-based applications. This invaluable set of design patterns builds on decades of distributed system experience, adding new patterns for writing services and composing them into systems that scale and perform reliably under real-world conditions.

More than just a patterns catalog, this practical guide offers experience-driven advice to help you design, implement, test, and deploy your microservices-based application.

To some, microservices can seem complex, confusing, and doubtful to live up to their promises. Others view microservices as picking up where service-oriented architecture SOA left off, making development faster, more scalable, and more flexible. How are businesses adopting microservices as part of their technology stack? And why? Here's a look at what's in this free PDF ebook. TechRepublic contributor Patrick Gray provides an overview on how a microservices architecture can be useful to an organization in the article, 'Microservices A guide to microservice architecture.

Microservices and service-oriented architecture are often compared, but the two frameworks are quite different and have unique uses in enterprise environments. With microservices, IT should abandon the old ways of securing applications and focus on the three guiding principles of traceability, visibility, and compartmentalization. TechRepublic contributor Matt Asay explains why in his article, 'Best practices for securing microservices. In the feature, 'Australian neobank Xinja is mastering integration through microservices,' ZDNet's Aimee Chanthadavong investigates the neobank's decision to implement an event-based microservices architecture.

Microservices may not be for everyone. There are many situations in which they may do more harm than good, cautions ZDNet contributor Joe McKendrick in the article, '8 ways to make sure you really need microservices. Containers and microservices are paving the way to DevOps.

However, as with any promising technology approach, they require management care and feeding. ZDNet Contributor's Joe McKendrick investigates in the article, '8 speed bumps that may slow down the microservices and container express. So we want to scale our system up and apply some load balancing techniques. But that could imply wasting resources, or at least not being as flexible as we could.

Connecting Microservices We will create gamification logic in a separate microservice. It should somehow connect with our existing business process of solving an attempt and getting feedback, extending it to be solving an attempt, getting feedback, and winning points.

How do we span our process across those two microservices? They could share the database so the gamification service can use the data there directly. The gamification service could poll data periodically from the multiplication service and process it as needed to assign points, badges, etc. When something happens in the multiplication service i.

Option 2 sounds better, but requires constant polling for new data and keeping track of which attempts have been already processed for instance, by asking for attempts sent since the last time gamification processed them. But there is still one thing that can be improved: multiplication service does not need to know about gamification service. We should be able to design a system in which our multiplication service can live without gamification and still behave as it is now in the current status of the application.

So we can go for an improved variation of the third option, designing a way of communication in which services are as decoupled as possible. We subscribe to the same MultiplicationSolvedEvent and perform our business logic in a different microservice. As you can see, designing our functionality following these reactive patterns give us a lot of flexibility. This way of modeling our architecture is known as event-driven architecture or reactive systems. Within our business processes we may have scenarios in which services need data from each other, not necessarily related to an event.

An example of that, based on our previous examples, would be the social network service. That one would need to access the user alias and probably some other to-be-implemented details. To illustrate how this way of communication combines with an event-driven approach, we cover a practical case using our application. Event-Driven Architecture In this type of architecture, the different microservices send events whenever an important action happens.

Those events are exchanged between microservices through a message broker also called sometimes event bus. Others can subscribe to events for which they are interested and react to them. Note an important concept: an action that already happened. What other microservices will do if they are subscribed to this event is process it according to their own business logic, which could lead to other events being published e.

Related Techniques Event-driven architecture has an affinity for some other techniques: event sourcing, domain-driven design, and CQRS. When designing your system, try not to be seduced by technology hypes, but use them as tools to solve your problems. Event sourcing is an approach to persist business entities. Instead of modeling them with a static state that you can change over time, you model them as sequences of immutable events.

We change it to name: Jhonas and we notice we made a mistake and change it back to name: John. In a traditional persistence method, if you check the data after applying these changes, you will only see the name: John state. The common examples normally used for event sourcing are based on banking applications, for which this pattern makes a lot of sense. Your account is a compilation of transactions over time. As you can imagine, event sourcing can be implemented easier in a system that is based on events.

However, it does not come for free: you can design your event-driven architecture with a few events, but going full event sourcing can increment significantly the number of events that you need to model.

The system will use event-driven architecture, but our persistence is not based on event sourcing. More than a pattern could be even defined as a philosophy for designing software, in which your business domain is the core of your system. When you follow DDD patterns, you can identify bounded contexts, which are like subdomains that can be treated separately in your system. This is very useful when designing microservices, since they can easily be mapped to bounded contexts and benefit from the DDD approach.

CQRS Command-Query Responsibility Segregation is a pattern in which the query model for reading and the command model for writing are separated, thus enabling a very fast reading approach at the expense of having a much more complex system. It can be used together with event sourcing, being the event store the write model.

The new gamification microservice will consume these types of events and assign a new score to the proper user. They keep their data and their functionality separate.

Those are characteristics of your system that, on the one hand, may give you more work to do, but on the other hand, you can benefit from. Loose Coupling With event-driven architecture, we can achieve loose coupling between our services, as described in the previous section when analyzing the options to connect them.

You can also split big processes into smaller pieces, having them completed by multiple services in an independent manner. In our system, the attempt-to-points process is divided into two microservices. This is a great advantage: we have our processes there, but they are distributed. A solution for this is using a message broker implementation that guarantees delivery of the events at least once. The big risk here is that it requires a change in the way you design and translate your functional requirements e.

Fault Tolerance As a consequence of not having or minimizing transactions, fault tolerance becomes more important in these systems. You need to prevent that from happening e. In any case, including fault tolerance is good in any kind of system, not only those using an event-driven approach. If you implement it properly, your distributed system can reach higher availability than a monolith. Events are queued for later processing so small parts of the system can die independently and restart automatically.

In an event-driven architecture, you span processes across services that are triggering and reacting to events. How do we know, by just looking at the system from a high perspective, that an e-mail might be sent when a multiplication is solved?

We can implement our own integrated mechanism to correlate events by tagging them as they cross the services , or we can use an existing tool like Zipkin. If you go for it because of the advantages, keep the drawbacks in mind and prepare the solutions. The full series is great for grasping the important concepts. Some parts are not easy to read though. We decided to move to microservices: our functionality is split into the multiplication application now the multiplication microservice and the gamification application gamification microservice.

In order to do that, we model the MultiplicationSolvedEvent, which represents that business action in the system. When a new event is received, it processes the data contained in it and assigns points and badges to the user. It is the perfect tool to send and receive messages in this application. If you want to get full details about the AMQP Model in RabbitMQ, the official tutorial is a good starting point, where you can learn more about the concepts of queue, exchange, and route, and also learn about the different types of exchanges: Direct, Fanout, Topic, and Headers.

This is to illustrate the most flexible way of sending messages. The flexibility of topic exchanges and routing keys comes from the fact that multiple subscribers can bind queues to the same exchange with different routing keys, thus potentially receiving a different subset of messages.

Think of the example of an online store: a microservice in charge of canceling orders would subscribe to order. As you may guess, designing exchanges, queues, and routing keys is not easy, especially if you want to achieve optimal performance. Our gamification microservice should contain configuration to create the topic exchange, just in case it starts before the multiplication microservice.

We want to make our existing multiplication microservice work in an event-driven ecosystem. RabbitMQ Configuration As mentioned, we need to edit the pom.

We create a new class called RabbitMQConfiguration under a new package called configuration. The Value annotation and the syntax inside are the way to inject a property value in Spring Boot.

That means we need all subscribers that are going to deserialize the message to use the same class name, in the same package.

This introduces tight coupling between services. Keep in mind the principles of the event-driven architecture: an event happens in the past and should be generic unaware of the subscribers. ToString; import java. Provides some context information about the multiplication. When modeling events, you have a wide spectrum of options regarding the information you put there.

In this case, we could have included the whole MultiplicationResultAttempt object. That would travel in the message together with the contents of the referenced User and Multiplication objects. But why would you that? Imagine that we are receiving events when user details are updated, and we decided to model the event including the changes made to the user. Think of the case in which there are multiple subscribers, one of them is failing and the broker is dispatching those rejected messages back again.

Now the order of events is not the real sequence of the changes. In this case, it might be better to notify that the user with the given identifier has been updated, and leave the consumers to ask for the latest state whenever they decide to process their logic. Another potential drawback of including too much data in events can be shown in the following example: if in future we include an extra microservice e. We would have not only a fat event but also a smart publisher who knows too much about the business logic of their consumers: an anti-pattern of event-driven architecture.

Using that in our benefit, we can include a reference to the user userId and also pass a boolean value indicating if the attempt was correct or not. This chunk of information is generic and immutable, and can save some extra REST requests from potential consumers which is the side effect of having too skinny events. As you can see, there is no black and white approach, but it should be clear at this point that modeling events is as important as modeling your domain.

On the other hand, having all the event dispatchers or listeners in a single class may end up with a huge class and a lot of redirection logic. Why would you deal with so many events within a single microservice? You should reflect on that and try to identify if it is the case that your microservice has too many responsibilities. RabbitTemplate; import org. Value; import org. Then we use the template to convertAndSend our object in this case, converted to JSON based on the provided configuration.

Besides, our MultiplicationSolvedEvent will use the routing key multiplication. The change is very straightforward: we just inject the EventDispatcher and use it to send a new MultiplicationSolvedEvent. Since we have our method annotated with Transactional, the event will not be sent in case of an exception even if we placed our eventDispatcher.

For better readability, place the event senders at the end of the logic, or at least after the action happens. Update the test to include that assertion. In any case, the Exercise blocks will guide you through the rest of the changes needed. Exercise prior to starting coding the new microservice, you need to create a project for it. Call the new application gamification and use the microservices. Besides the web dependency, you should also include Lombok, h2, and aMQp.

Cards score and badge contain the moment in time they were obtained. The result of a game iteration may contain one or more ScoreCards and one or more BadgeCards. See Listings through Contains also a timestamp with the moment in which the user got it.

Therefore, our persisted data will be composed of two tables, which are direct representations of ScoreCard and BadgeCard classes. Nothing new there, using the CrudRepository from Spring Data and a query method which, by naming conventions, will be processed as a query to get badges for a given user, most recent first.

BadgeCard; import org. For the sake of learning, the result of the query will be mapped to a new object: a LeaderBoardRow. LeaderBoardRow; import microservices. ScoreCard; import org. Query; import org. CrudRepository; import org. Param; import java. LeaderBoardRow s. JPQL provides a set of functions, operators, expressions, etc. However, take into account that this language is a specification and there are some database implementations that may not support it completely.

Our query will create new LeaderBoardRow objects for the query results, using the userId and the aggregation of the score for a given user. It also covers the sorting of results with the highest score first. LeaderBoardRow; import java.

You can find the completed tests in the v5 code repository, within the gamification project. The main game logic is inside the GameServiceImpl class. Then, we invoke the method processForBadges , which will query the database for a given user ID and assign new badges when necessary.

Finally, we combine the scores with badges in a GameStats object and return this result. The rest of the class is intended to help that method and a simple retrieveStatsForUser implementation. The link between the event bus and the business logic is the EventHandler.

This way, we can replace the interface of our microservice without needing changes in other layers e. How many points does a user have? What is the current leaderboard? Here we use a parameter userId to query for the statistics of a given user. We have six methods: five declare beans and the last one implements the interface RabbitListenerConfigurer.

To understand this configuration, the concept of binding a queue to an exchange is an important one here. Those messages are published to an exchange with a routing key in our case multiplication. You can look at the official RabbitMQ tutorial page6 to learn more about topics and to see various examples of routing. We introduced this idea before: by doing this we can process pending events even after the broker goes down, given that they are persisted.

For the queue name multiplication. All these values should be defined in the application. RabbitMQ configuration multiplication.

The goal is similar: having a centralized place from where we can process the received events and trigger the corresponding business logic. This annotation handles all the complexity of receiving a message from the broker through the queue that we defined we need to pass the queue name as a parameter to the annotation.

To avoid inter-dependencies between our microservices, we copy our MultiplicationSolvedEvent class to the gamification project. Slf4j; import microservices. GameService; import org. RabbitListener; import org. By doing that, we make sure the event is not repeatedly requeued whenever something is wrong which is the default behavior , but directly rejected.

If you want to get deeper into good practices with RabbitMQ, you can look at how to configure a dead letter exchange and put our failing messages there for further processing like retrying, logging, or raising alerts. In this section, we expand on the idea by using our architecture as a reference.

Imagine that we get a change to our gamification design. Our game designers come up with a new badge called Lucky Number. They are not coming inside the MultiplicationSolvedEvent. In this case, it might be simple and yet look like a generic event, but if you follow the approach of tailoring publishers to consumers, you may end up with fat, too smart events.

To solve this new challenge, the gamification microservice can contact the multiplication microservice and ask for the factors of the multiplication given the identifier of the attempt contained in the event. Then, if it finds the lucky number, it will assign the badge. Then, we need to create a REST client in gamification to retrieve the factors. Finally, we use them in our logic to assign the badge if one of them is the lucky number.

That means that we need to model a MultiplicationResultAttempt inside gamification somehow. A common pitfall is thinking of extracting the domain package from the multiplication microservice as a separate library that can be shared with gamification, thus having access to MultiplicationResultAttempt. You should always keep ownership of the domain entities in one microservice, so there is only one source of truth.

This has the advantage of minimizing dependencies: if you need only a couple of fields, you deserialize those and ignore everything else. That way, your microservice will be impacted only if those specific fields change. This class contains factorA and factorB as fields.

JsonDeserialize; import lombok. ToString; import microservices. For now, we will point it directly to the host and port in which we know that the microservice is deployed. We use some classes from the Jackson library, which is included inside Spring Boot. JsonParser; import com. JsonProcessingException; import com. DeserializationContext; import com. JsonDeserializer; import com. JsonNode; import microservices. MultiplicationResultAttempt; import java. We need to create a subclass of JsonDeserializer, passing the type we want to use as a result.

The next step is to write an interface to abstract the communication logic. RestTemplateBuilder; import org. Bean; import org. Configuration; import org. MultiplicationResultAttempt; import org. The getForObject method takes the class as an argument, then infers that it should use the custom deserializer.

First, we need to create the new badge by adding a value to our enumeration, as shown in Listing Once you install it, start the broker the installation guides include instructions for that as well. Keep the configuration as it is by default. If everything goes well, multiplication should start on port and gamification on port The difference now is that every time you send an attempt, a new event is published.

You can notice that by looking at the Gamification log, as shown in Listing Gamification Logging After Received Attempt gamification v5 GamificationApplication : Started GamificationApplication in 8. Do you remember that you had access to the multiplication database through the H2 console? If you query the tables after sending correct attempts, you should see the different badges and scores linked to users. You can query the gamification database using H2 To try the lucky number, we need to cheat the system a bit.

If you prefer not to wait, you can use curl to post your own multiplication to the system, as shown in Listing You can also use Postman,8 which gives you a full UI from which you can send all types of requests.

Before we delved into the microservices idea, we analyzed our plan to approach it: starting with a monolith. We used our application to compare how expensive it would have been to begin directly with a microservices approach, and covered the plan to prepare the monolith to be split later.

We received a new requirement in the form of a user story and went through it to specify a second service to design and implement, based on gamification techniques. We learned the basics of these techniques to motivate players: points, badges, and leaderboards. Following a pragmatic approach, we started with simple logic that works. About microservice interactions, we saw that there are different ways of connecting microservices together to fulfill business processes, and we chose to go for an event-driven architecture.

We reviewed its benefits and applied it directly to our application to see it in practice. We compared it to some other related techniques event sourcing, CQRS, etc. The second part of the chapter explained how to implement the asynchronous communication that supports our event-driven architecture, using Spring AMQP with RabbitMQ as implementations. Then, we went through the implementation of the new microservice, the gamification Spring Boot application.

The reason is that, in order to build a good microservices architecture, we need the UI part of the system extracted in a new service so it can interact as an independent party with our multiplication and gamification services. Many advantages, at the expense of a more complex system. The static content will be served by the multiplication microservice, as before.

The second disadvantage is that we would lose flexibility to scale: the availability of the UI server is linked to the availability of the multiplication microservice.

Maybe we need more resources in the future to serve UI pages, but we may not want to scale all the functionality offered by the microservice. Besides, we could now scale up or down our UI server following a different strategy than the multiplication microservice. There are many good ones: Tomcat, Nginx, Jetty, etc.

First, we need to download and install Jetty in our system. This is a nice approach because we normally would like to keep our custom server configuration layer under version control and separated from the server binary files, making much easier a future solution for automated deployment.

Listing shows the resulting file structure. Another problem we have when pointing at specific ports is that our system does not scale transparently. If we want to include an extra instance of the multiplication service, we should implement the logic to detect it and to do load balancing from our web client.

Luckily, there are solutions to solve this dangerous approach we just took. In this case, port numbers are not the same and You could see the issue by yourself if you skip this part, continue with the UI changes, and execute all the services as explained by the end of this section. Then, you should open the Development Tools within your browser e. To accomplish that, we need to add some Spring configuration to both of our services. Listing shows the class added to gamification; we also need to create an identical class inside multiplication to enable CORS there as well.

CorsRegistry; import org. EnableWebMvc; import org. When your system is mature and your infrastructure is set up, you may want to be stricter here by passing some property values to your applications to allow only some specific domains as origins. The Grid system, Forms, and Buttons will be the main features used in this application. We removed the styles. This is to make sure we give some time to the event to propagate and we get the updated information. We just want to keep the UI simple so this is a basic solution, but if you want to explore better options, you can read about how the server can notify the client when the data is ready using technologies like WebSockets.

That means it will look good on smaller screens like smartphones, adapting the content to the screen size. You can test it by resizing the browser or using the web developer tools to simulate different devices.

Remember that now we have to include an extra stepto see our system running: 1. Start the RabbitMQ broker. Do the same for gamification microservice. Our architecture is growing toward a real microservice architecture, step by step. The problem here is that, if we split or combine some of our microservices in the future, we will impact the UI, requiring modifications to align with the new backend structure.

The same happens with gamification and its link to multiplication. This is when a major transition in our architecture occurs. To solve these problems, we need to introduce some patterns such as service discovery, load balancing, the API gateway or routing , etc.

In the world of microservices, they usually come together with the names of the tools or frameworks that implement those patterns: Eureka, Consul, Ribbon, Zuul, etc. Should we implement all of them to have a proper microservices architecture?

This is annoying. We could think of creating a script file to start up these different parts, and that would be really good since we would create our first automated deployment strategy. We need end-to-end tests, which are covered in the next chapter.

Why should gamification know the physical location IP and port number of multiplication? It does not scale at all: what if we introduce a second instance of the multiplication microservice? Which one should we invoke from gamification?

The difference is that, in this case, the communication is between two microservices. There are different service discovery tools, among others Consul and Eureka, that are nicely supported by Spring.

Keep in mind that you could follow similar instructions to the ones in this book to make the following setup work with a different implementation for example, Consul. First, there is a new separate component: the Service Registry. We will deploy it as a new microservice. Multiplication and gamification microservices will register themselves by contacting it when they start, using their Registry Agents.

However, for those addresses to work, our microservices must use their Registry Client, which will translate the aliases to specific URLs using the mapping located at the Service Registry. Load Balancing There is still a gap in our architecture: how does Eureka work with multiple instances of the same service? The guys at Netflix solved that challenge too: they implemented Ribbon to provide client-side load balancing integrated with Eureka.

If we spin up two instances of multiplication microservice, they will both register in Eureka with the same alias since they have the same application name. You might be asking yourself: why should the caller worry about the load balancing part or the number of instances of another service? We call the service as if it were only one instance of it. The next section about routing and the API gateway pattern will provide an answer to this problem.

How are we supposed to include Eureka and Ribbon? It uses Eureka to register and update the different instances of the non-Java application via the Registry Agent and to get the available instances of other microservices via the Registry Client.

To achieve high availability, the Sidecar microservices should be scaled and monitored as well, which introduces an extra required layer of redundancy in your system. As you can imagine, maintaining this approach with a few microservices can be fine, but having it for a big part of your system might become a nightmare. In a similar way to the service registry, Zuul will work in our architecture as an extra microservice that we need to connect to the others.

This annoying side-effect becomes even worse if we offer our REST APIs to external parties, which should adapt their applications to every microservice refactoring work we make.

That will give us total flexibility to later change parts of it without impacting others. Our chosen tool, Zuul, will handle the routing of requests to the proper service once we configure some URL patterns, keeping the consumers totally unaware of the internal structure.

For the same reason, including this pattern in an existing monolith is a perfect way of splitting it and evolving it to a microservices architecture step by step. With the API gateway, we could also integrate into a central place features like Authentication since all the requests will go through that service. We could use Spring Security for example, and integrate it with Zuul with a custom Zuul filter.

As an alternative, we could also integrate within our Zuul microservice a third-party Authentication and Authorization provider, such as Auth0 or Okta Single Sign-On. However, we already learned that we need those capabilities in our system to provide high availability and be able to keep the system working even if some microservices are down. However, now that we have an API gateway microservice that lives in our backend, what if we make it responsible for the load balancing functionality for frontend requests?

Parts that are critical, like routing and filtering, may become a single point of failure. This API gateway service in particular, as the gate to our microservices, is also known as an edge service. The key to making this kind of services work in a microservices infrastructure is to apply proper load balancing to them.

Most cloud providers offer these services out of the box, and we can also implement it by ourselves with tools like Nginx. The gateway microservice, which will be implemented with Zuul and Spring Boot, contains a routing table that points to microservice aliases registered in Eureka, instead of physical addresses. This is where the integration between Zuul, Eureka, and Ribbon combines perfectly to give us a full solution based on an API gateway, service discovery, and load balancing.

When Zuul receives a request, it decomposes the URL and locates the pattern in the routing table. Every pattern is mapped to a microservice alias so Zuul uses Eureka to go to the registry and find the available instances.

Then Ribbon comes into play and picks one of the instances based on the load balancing strategy Round-Robin by default. Finally, Zuul redirects the original request to the corresponding microservice instance. It can go like before and use its own connection to the service registry, but it can also use the new API gateway service to achieve its goal. There is no right or wrong answer here: it depends on your scenario and, more specifically, on how your infrastructure is set up. We get even looser coupling between our microservices.

Configuring it properly is complicated: it may depend on geographical areas, network latency, microservice load, etc. Client-side load balancing is not a good approach for backend services in these situations since every service has a local view of the possible infrastructure issues, but a global perspective may be required instead.

If we translate that to our last figure, it means that gamification and multiplication will use Eureka and Ribbon only to locate the gateway, which could be itself replicated in several instances.

Hands-On Code Finally! Now that we understood the concepts, we can apply these patterns to our microservices architecture and include Zuul, Eureka and Ribbon in our Spring Boot applications. The first one will be Zuul, our API gateway service. Our project name will be gateway and the package name will be microservices.

Use Spring Initialzr to create the gateway microservice Then we extract it, import it into our preferred IDE, and navigate directly to our application. To make our Spring Boot application behave as a Zuul gateway, we just need to add an annotation to our main class: EnableZuulProxy. SpringApplication; import org. SpringBootApplication; import org.

In this case, we can start with this configuration, as shown in Listing All the requests coming in need to have that part in the URL, which will be removed by Zuul when redirecting the request.

The next step is to include a WebConfiguration class enabling CORS for the gateway project too as we did for the multiplication and gamification microservices. This is needed here as well for the same reason: the frontend, gateway, and microservices are located at different origins port numbers in our case. Now we need to link everything.

Make sure to use this new variable in all the API calls spread in both files. To do that, we need to update the property that we included in its application. Since the gateway is a microservice itself, now we just need to start it together with the rest of our existing services. Run the gateway microservice. Run the multiplication microservice. Run the gamification microservice. Run the Jetty web server from the ui root folder. Also note that the order of those steps is not important apart from the first one, which is required for multiplication and gamification to work properly.

This time we only need to select the Eureka Server as a dependency. Name the project service-registry and keep the package name as the default of microservices. To convert our service into a Eureka Registry server, we also use an annotation as in the Gateway in the application class: EnableEurekaServer. We could set it to any other port number but, in that case, we would need extra configuration in all our microservices to override the default port.

Our new dependency to use the service discovery, spring-cloud-starter-eureka. An extra dependency to expose the status of our microservices, spring-boot-starter-actuator. Make sure to apply the same changes to multiplication and to the API gateway, which in this case already included the Spring Cloud configuration since we created it with Zuul.

Once we add this to a Spring Boot application, it will automatically make available some endpoints that are very useful for monitoring: metrics, mappings, health, loggers, etc. That way we make sure that future changes of the project name will not impact our infrastructure. Note that we need to include it in that new file and not in application. We also add a bootstrap. The last task we need to do to finalize our service discovery setup for the entire system is change the routing configuration in our API gateway service Zuul.

The current configuration is shown in Listing



0コメント

  • 1000 / 1000