The words written in the front
Exam coming soon!!
As a helpless and painful reading college students, and to face half a year once the final exam, because the class did not listen to, I do not know what, what communication principle, single-chip microcomputer… Give me a break!!
I’ll show you what I’m doing in class and you’ll see why I can’t do anything.
Lecture notes.
Emmm, the word is ugly 😑. I still remember it was an English class, the teacher did not allow electronic devices, I had to hand write my ideas for this article…
So, at the risk of failing my final exam 👊, I have to finish this article and share my knowledge with you so that I can review and learn more about Spring Cloud.
My girlfriend said she would buy me a SSD 🙏🙏🙏 if this article got 50 likes
First of all, LET me show you a picture. If you don’t understand something about this picture, I hope this article will enlighten you.
The overall architecture
What is Spring Cloud
Building distributed systems does not need to be complex and error-prone. Spring Cloud provides a simple and easy-to-accept programming model for the most common distributed system patterns, helping developers build resilient, reliable, and coordinated applications. Spring Cloud is built on top of Spring Boot, making it easy for developers to get started and quickly put into production.
Official as expected official, the introduction is so regular.
Spring Cloud, as I understand it, is a one-stop solution for microservice system architecture. In normal times, we need to do operations such as service discovery registration, configuration center, message bus, load balancing, circuit breaker and data monitoring in the process of building microservices. Spring Cloud provides us with a simple programming model that enables us to easily build microservice projects based on Spring Boot.
The Spring Cloud version
Of course this is just a digression.
The version number of Spring Cloud is not the usual digital version number, but some very strange words. These are the names of underground stations in London, England. At the same time according to the order of the alphabet corresponding to the version of the time order, for example: The first Release was Angel, the second was Brixton, then Camden, Dalston, Edgware, Finchley, Greenwich, Hoxton.
Eureka, Spring Cloud’s service discovery framework
Eureka is a REST-based (representative state transition) service primarily used in the AWS cloud to locate services for load balancing and mid-tier server failover. We call this service the Eureka server. Eureka also comes with a Java-based Client component, Eureka Client, which makes it easier to interact with services. The client also has a built-in load balancer that performs basic cyclic load balancing. At Netflix, more sophisticated load balancers package Eureka to provide weighted load balancing based on traffic, resource usage, error conditions, and other factors to provide excellent resilience.
In summary, Eureka is a service discovery framework. What is to serve and why to discover?
Take an example in life, for example, we usually rent a house to find an intermediary.
When there is no agency, we need to look for landlords one by one to find out whether there are houses to rent, which is obviously very laborious. You can’t find many houses for you to choose by one person’s ability, and you are too lazy to keep looking (after looking for so long, there is no suitable one to settle for). We are the consumers in microservices, and the landlords are the providers in microservices. The Consumer needs to invoke some of the services provided by the Provider, just as we now need to rent their house.
However, if the search is only conducted between the tenant and the landlord, their efficiency is very low. The landlord cannot find the tenant to earn money, and the tenant cannot find the landlord to live in the house. Therefore, the landlord must have thought of broadcasting his housing information (such as putting up a small advertisement on the street), so that the landlord has fulfilled his mission (to make the housing available to the public), but two problems appear. First, other people who are not renters can receive this rental message, which is fine in the real world, but in the computer world, there will be a resource consumption problem. Second, the tenant is still difficult to find you, just think I need to rent a house, I also need to find a small street advertising east and west, hemp is not trouble?
So what to do? Of course, we will not be so silly, the first time is to find an intermediary ah, it provides us with a unified house source place, we consumers only need to run to it to find there on the line. As for the landlord, they only need to list the listing with the agent.
So now, our model looks like this.
However, some problems may arise at this time.
-
What if the landlord does not want to sell the house after registration? Do we need to ask the landlord to renew the lease on a regular basis? If the landlord does not renew the lease, is it necessary to remove them from the agent’s registration list?
-
Do tenants also need to register? Otherwise, how can party B get the contract?
-
Can an intermediary be a chain store? If this store cannot be used due to some force majeure, can we change to another chain store?
Let’s reconstruct the above pattern diagram for the above problem
Ok, so with 🌰 we can look at some of the basic concepts of Eureka, and you’ll see how easy it is to understand. 👎 👎 👎
Service discovery: in fact, it is an “intermediary”, and there are three roles in the whole process: service provider (rental house), service consumer (tenant), service intermediary (housing intermediary).
Service provider: it is to provide some services that can be performed by itself to the outside world.
Service consumer: A “user” who needs to use some service.
Service mediation: In fact, it is the “bridge” between service providers and service consumers. Service providers can register themselves with service intermediaries, and service consumers can look for service providers registered in service intermediaries if they need to consume some services (use some functions).
Service Register:
When the Eureka client registers with the Eureka Server, it provides its own metadata, such as IP address, port, health indicator URL, home page, etc.
The landlord (Provider Eureka Client Provider) registers the housing information, such as area, price, lot and so on (metaData) with the broker (Eureka Server).
Renew:
Official explanation: Eureka customers renew their contracts by sending a heartbeat every 30 seconds (by default). Renew the contract to inform the Eureka Server that the Eureka customer still exists and there is no problem. Normally, if Eureka Server does not receive a renewal from an Eureka customer within 90 seconds, it removes the instance from its registry.
The landlord (Provider Eureka Client Provider) regularly tells the intermediary (Server Eureka Server) that my house is still rented (renewed), and the intermediary (Server Eureka Server) continues to retain the information of the house after receiving it.
Fetch Registries:
The Eureka client retrieves the registry information from the server and caches it locally. The client uses this information to find other services to make remote calls. This registration list information is updated regularly (every 30 seconds). The information returned from the registration list may be different from the information cached by the Eureka client. The Eureka client processes the information automatically. If for any reason the registry information does not match in time, the Eureka client retrieves the entire registry information. The Eureka server caches the registry information, and the entire registry as well as the information for each application is compressed so that the compressed content is identical to the uncompressed content. The Eureka client and Eureka server can communicate using JSON/XML format. By default, the Eureka client uses compressed JSON format to retrieve the registry information.
Combined with intermediary understanding: The tenant (Eureka Client Consumer) goes to the broker (Eureka Server) to get all the housing information lists (Eureka Client List), In addition, tenants regularly obtain and update local listings from the intermediary (Eureka Server) to get the latest information.
Service offline Cancel:
The Eureka client sends a cancellation request to the Eureka server when the program is shut down. After the request is sent, the client instance information is removed from the server’s instance registry. The offline request will not automatically completed, it needs to call the following content: DiscoveryManager. GetInstance () shutdownComponent ();
The landlord (Eureka Client Provider) tells the agent (Eureka Server) that my house is no longer rented, and the agent then removes the registered house information from the list.
Service exclude Eviction:
By default, if the Eureka client does not send a service renewal (i.e. heartbeat) to the Eureka server for 90 consecutive seconds (3 renewal cycles), the Eureka server will remove the service instance from the service registry.
Combined with intermediary understanding: The landlord (Provider Eureka Client Provider) will regularly contact the intermediary (Server Eureka Server) to tell him that my house is still rented (renewed). If the intermediary (Server Eureka Server) has not received the information from the Provider for a long time, Then the agent will take his housing information off the shelf (service removal).
Here’s Netflix’s official Eureka architecture diagram, and you’ll find it’s no different from the intermediary diagram we drew earlier.
Eureka architecture diagram
Of course, there are many components that can act as service discovery: Zookeeper, Consul, Eureka, etc.
For more information on Eureka (self-protection, initial registration strategy, etc.) check out the official website for yourself, or check out another of my articles to learn more about Eureka.
Load Balancing Ribbon
What is the RestTemplate?
What about the Ribbon? What about the RestTemplate? Don’t worry. Just listen to me.
I don’t listen I don’t listen I don’t listen 🙉🙉🙉
I’m just saying! RestTemplate is a client class that Spring provides to access Http services. The RestTemplate is used for calls between microservices. So let’s say that we need to call the service provided by provider A when we have consumer B. As I see in the pseudocode below.
@Autowiredprivate RestTemplate restTemplate; Private static final String SERVICE_PROVIDER_A = "http://localhost:8081"; private static final String SERVICE_PROVIDER_A = "http://localhost:8081"; @PostMapping("/judge")public boolean judge(@RequestBody Request request) { String url = SERVICE_PROVIDER_A + "/service1"; return restTemplate.postForObject(url, request, Boolean.class); }Copy the code
If you’re interested in the source code, you’ll notice that the underlying registration, renewal, and so on in the Eureka framework we talked about above are all restTemplates.
Why is the Ribbon needed?
Ribbon is an open source load balancing project from Netflix. It is a client/in-process load balancer that runs on the consumer side.
Let’s take 🌰 again. For example, we designed a seckill system, but for the high availability of the whole system, we need to make the system a cluster, and at this time we consumers can have multiple seckill system invocation channels, as shown in the following figure.
If we’re not doing some balancing at this point, if we’re making a lot of calls to system 1, and the other two are basically uncalled, it crashes system 1, and the other two become puppets, then why are we clustering, and what’s the point of our high availability?
So the Ribbon appears, notice our bold words above — runs on the consumer side. The Ribbon is a load balancer that runs on the consumer side, as shown below.
The way it works is that the Consumer gets all the service lists and uses load balancing algorithms internally to make calls to multiple systems.
Nginx vs. Ribbon
Unlike the Ribbon, Nignx is a centralized load balancer.
What is centralized? The simple idea is to centralize all requests and load balance them. The diagram below.
We can see that Nginx receives all requests for load balancing, whereas the Ribbon does load balancing on the consumer side. The diagram below.
Note the location of the Request. In Nginx the Request goes into the load balancer first, whereas in the Ribbon the Request is load balanced on the client first.
Ribbon load balancing algorithms
Load balancing, both Nginx and the Ribbon need the support of their algorithms, and if I remember correctly Nginx uses polling and weighted polling algorithms. In the Ribbon, there are more load balancing scheduling algorithms that use RoundRobinRule by default.
-
RoundRobinRule: indicates a polling policy. The default policy used by the Ribbon. If no available provider is found after one round of polling, the system rounds at most 10 rounds of polling. If not found, null is returned.
-
RandomRule: A strategy to randomly select one of all available providers.
-
RetryRule: Retry policy. Obtain the provider based on RoundRobinRule. If obtaining the provider fails, retry within the specified time limit. The default is 500 milliseconds.
🐦🐦🐦 there are many more, which are not 🌰. The most important thing you need to know is the default polling algorithm, and you can change the default load balancing algorithm by making changes in the configuration file.
providerName: ribbon: NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Copy the code
Of course, in the Ribbon you can also customize load balancing algorithms by implementing the IRule interface and modifying configuration files or customizing Java Config classes.
What is Open Feign
With Eureka, RestTemplate, Ribbon we can happily make calls between services 😃, but using RestTemplate is still inconvenient, and we have to make these calls every time.
@Autowiredprivate RestTemplate restTemplate; Private static final String SERVICE_PROVIDER_A = "http://localhost:8081"; private static final String SERVICE_PROVIDER_A = "http://localhost:8081"; @PostMapping("/judge")public boolean judge(@RequestBody Request request) { String url = SERVICE_PROVIDER_A + "/service1"; // Is it too much trouble?? Every time the url, request, the return type of the return restTemplate. PostForObject (url, request, Boolean. Class); }Copy the code
Is it too much trouble to call the API of RestRemplate every time? Can I call each service just like calling the original code?
💡💡💡 smart kids must have thought of it, that use mapping ah, like domain name and IP address mapping. We can map the called service code to the consumer side so that we can “develop seamlessly”.
OpenFeign also runs on the consumer side and uses the Ribbon for load balancing, so OpenFeign comes directly with the Ribbon.
With Open Feign imported, we can have fun coding the Consumer side.
@feignClient (value = "eureka-client-provider")public interface TestClient {// Use @feignClient to specify the name of the provider It's important to note that you need to use the provider side of the request relative path, @requestMapping (value = "/provider/ XXX ") method = RequestMethod.POST) CommonResponse<List<Plan>> getPlans(@RequestBody planGetRequest request); }Copy the code
Then we can call it in Controller just like we used to call the Service layer code.
RestControllerpublic class TestController {// Autowired private TestClient TestClient; @requestMapping (value = "/test", method = RequestMethod.POST) public CommonResponse<List<Plan>> get(@RequestBody planGetRequest request) { return testClient.getPlans(request); }}Copy the code
Essential Hystrix
What are Hystrix’s circuit breakers and downgrades
In a distributed environment, it is inevitable that some of the many service dependencies will fail. Hystrix is a library that helps you control the interaction between these distributed services by adding wait time tolerance and fault tolerance logic. Hystrix does this by isolating access points between services, stopping cascading failures between services, and providing fallback options, all of which improve the overall resilience of the system.
In general, Hystrix is a library for fuses and downgrades to improve overall system resiliency.
So what are circuit breakers and downgrades? Another example is 🌰, where our entire microservices system looks like this. Service A calls service B, and service B calls service C, but for some reason, service C can’t hold up, and A lot of requests are blocked at service C.
Service C is blocked. After all, it’s just a system crash. Note that service B’s request to call service C will be blocked because service C cannot return A response, and service A will also crash if service B is blocked.
Notice why the blocking crashes. Because these requests will consume threads, IO, and other resources that occupy the system, the system server will not crash after consuming your system.
This is called service avalanche. Damn, you didn’t give me a clear explanation of the fuse and downgrade, and now you’re talking about a service avalanche? 😵 😵 😵
Don’t worry. Just listen to me.
I have to go on if I don’t listen!
The so-called circuit breaker is an effective solution to the service avalanche. When the request failure rate reaches the threshold in a specified time window, the system disconnects the request link through a circuit breaker.
In other words, if the failure rate of service B calling service C reaches a certain value in a specified time window, Hystrix will automatically cut off all requests between service B and service C to avoid service avalanche.
The circuit breaker in question is Hystrix’s circuit breaker mode. You can mark a method with a simple @HystrixCommand annotation so that Hystrix “wraps” the method with a circuit breaker. Whenever the call takes longer than the specified time (the default is 1000ms), the breaker interrupts the call to this method.
Of course you can set many of the attributes of this annotation, such as setting the timeout, like this.
@HystrixCommand( commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "1200")})public List<Xxx> getXxxx() { // ... Omit code logic}Copy the code
However, I looked at some blogs and found that they were confusing the concept of a circuit breaker with a downgrade, which in my understanding is for a better user experience by executing another code logic to give a user friendly reply when a method calls an exception. This corresponds to Hystrix’s backup processing mode. You can set alternate code logic for a method by setting fallbackMethod. Such as a hot news appeared, this time we will recommend to the user to check the details, and then the user will by id to check details of the news, but because the news is too fire (for example, recently what * easy, right?), a large number of users access may lead to system crash at the same time, then we will service degradation, Some requests will be downgraded such as too many people now please check later and so on.
@hystrixCommand (fallbackMethod = "getHystrixNews") @getMapping ("/get/news")public news Public News getHystrixNews(@pathVariable ("id") int id) {public News getHystrixNews(@pathvariable ("id") int id) {// Do service downgrade // return the current number of too many, please check later}Copy the code
What is Hystrix and others
I also came across the concept of the bulkhead pattern while reading the book Spring Microservices in Action. Without the bulkhead pattern, service A calls service B, which is executed by default using the same set of threads, and when A service has A performance problem, all threads are maxed out, waiting for work to be processed, blocking new requests and eventually crashing. The bulkhead pattern isolates remote resource calls in their own thread pool so that they can control a single poorly performing service without crashing the program.
I recommend you to find out how it works. There is no explanation of bulkhead mode in this article. Of course, there is also the Hystrix dashboard, which is used to monitor Hystrix’s various indicators in real time. I will throw this out here as well, and hope that those who don’t know can search for it themselves.
Microservices Gateway — Zuul
ZUUL is the front door for all requests from devices and Web sites to the back end of Netflix streaming applications. As a boundary service application, ZUUL is built for dynamic routing, monitoring, resiliency, and security. It also has the ability to route requests to multiple Amazon Auto Scaling Groups (Amazon’s approach to cloud computing) depending on the situation
After learning Eureka above, we know that service providers are accessed by consumers through Eureka Server, that is, Eureka Server is the unified entrance of service providers. How do users access consumer projects when there are so many consumers in the entire application that they need to call? You can of course access these projects directly as before. However, this approach does not have a unified entry point for consumer project invocation, making it difficult to access and manage. Zuul is such a unified entry point for consumers.
If you’ve learned about the front-end, you probably know about the Router, such as the route to Flutter, the route to Vue, the route to React, and the Zuul route. You’ll find that the routing function is basically the same as configuring the front-end route. 😁 I occasionally lift up Flutter.
You should be very familiar with the gateway, simply speaking, the gateway is the only external entrance of the system, between the client and server, used for request authentication, traffic limiting, routing, monitoring and other functions.
Yes, Zuul has almost all the functions of the gateway. The key to Zuul is routing and filters, which is the title of Zuul in the official documentation
Router and Filter : Zuul
Zuul’s routing function
Simple configuration
I was going to copy some of the code for you, but on reflection, because the configuration of the code is a little bit fragmented, and it looks a little bit fragmented, I decided to draw a diagram to illustrate it.
Please don’t give me a thumbs-up 👍 just because I’m so good. Crazy hints.
For example, at this point we have registered two consumers and three provicers with Eureka Server, and at this point we should add Zuul gateway.
Emmm, that’s a lot of information. Let me explain. I will not explain the previous knowledge 😐.
First, Zuul needs to register with Eureka. What are the benefits of registration?
You are silly. All consumers have registered with Eureka Server. Do you think the gateway can get all Consumer information just by registering with Eureka Server?
What’s the advantage of getting the information?
Can I get metadata (name, IP, port) for all consumers?
What are the benefits of having this metadata? Can we just do route mapping if we get it? Such as the original user interface Consumer1 localhost: 8001 / studentInfo/update this request, we can call? Localhost: 9000 / consumer1 / studentInfo/update? Does that make sense to you?
The url here is not restful for more people to understand.
If you understand the above, then you can understand the basic configuration of Zuul, see below.
Server: port: 9000 Eureka: client: service - url: # here just registered Eureka defaultZone: http://localhost:9997/eurekaCopy the code
Then add the @enableZuulProxy annotation to the startup class. Yes, it’s that simple 😃.
Unified prefix
This is very simple, we can add in front of a unified prefix, such as we just call the localhost: 9000 / consumer1 / studentInfo/update, this time we add the following in the yaml configuration file.
zuul: prefix: /zuul
Copy the code
So we need through the localhost: 9000 / zuul/consumer1 / studentInfo/update to visit.
Routing Policy Configuration
You will find that the previous access method (using the service name directly), which requires exposing the microservice name to the user, has security issues. Therefore, a customized path can be used to replace the microservice name, that is, a customized routing policy.
zuul: routes: consumer1: /FrancisQ1/** consumer2: /FrancisQ2/**
Copy the code
This time you can use localhost: 9000 / zuul/FrancisQ1 / studentInfo/update for a visit.
Service name masking
At this time you don’t think you are good, you can try, after you configure the routing policy after using the micro service name can still access, this time you need to shield the service name.
zuul: ignore-services: "*"
Copy the code
Path to the shield
Zuul can also specify masked path URIs, meaning that as long as a user request contains the specified URI path, the request will not be able to access the specified service. In this way, users can be restricted.
zuul: ignore-patterns: **/auto/**
Copy the code
So we can filter out the auto request.
** indicates to match any multi-level paths
* indicates to match any path at one level
Sensitive request header masking
Sensitive headers such as cookies and set-cookies are blocked by Zuul by default. You can remove these filters by default, or you can add headers.
Zuul’s filtering function
If routing is Zuul’s base, then filters are Zuul’s weapon. After all, all requests go through the gateway (Zuul), so we can do all kinds of filtering, so we can do limiting, grayscale publishing, permission control, etc.
Simple implementation of a request time log printing
To implement our own Filter, we simply inherit ZuulFilter and add the Filter class to the Spring container with the @Component annotation.
Let me explain a few things about filters before I show you the code.
Filter type: Pre, Routing, and Post. Pre is to filter before the request, Routing filter is the Routing policy mentioned above, and Post filter is to filter before Response. You can look at the picture above in conjunction with the understanding, and I’ll give the corresponding notes below.
@componentPublic class PreRequestFilter extends ZuulFilter {// Returns the filter type filterType() { return FilterConstants.PRE_TYPE; } // Specify the filter order as small as possible, There are other filters in Zuul that are executed first. For example, SERVLET_DETECTION_FILTER_ORDER = -3@override public int filterOrder() { return 0; } @override public Boolean shouldFilter() {return true; @override public Object Run () throws throws ZuulException {} @override public Object Run () throws ZuulException RequestContext ctx = RequestContext.getCurrentContext(); ctx.set("startTime", System.currentTimeMillis()); return null; }}Copy the code
@componentPublic Class AccessLogFilter extends ZuulFilter {// Specifies the filter type for this filter @Override public String filterType() { return FilterConstants.POST_TYPE; } // SEND_RESPONSE_FILTER_ORDER is the last filter @override public int filterOrder() {return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; @override public Object run() throws ZuulException {RequestContext Context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); // get the original startTime from RequestContext and use it to calculate the entire interval Long startTime = (Long) context.get("startTime"); // Here I can get HttpServletRequest to get the URI and print out String URI = request.getrequestUri (); long duration = System.currentTimeMillis() - startTime; log.info("uri: " + uri + ", duration: " + duration / 100 + "ms"); return null; }}Copy the code
The above simply implements the request time log printing function. Do you feel the powerful filtering function of Zuul?
No? Ok, let’s try again.
Token bucket flow limiting
Of course, it is not only token bucket flow limiting method, Zuul as long as it is flow limiting work, here I just give a simple 🌰.
Let me first explain what token bucket limiting is.
First we have a bucket, and if it’s not full then tokens are put in at a constant rate, and a request comes in and gets the token from the bucket first, if it doesn’t get it then the request is rejected, if it gets it then it’s allowed. That’s easy, huh?
Here we use Zuul’s pre-filter to achieve a command plate bucket current limiting.
@Component@Slf4jpublic class RouteFilter extends ZuulFilter {// Defines a token bucket that generates 2 tokens per second, That is, a maximum of two requests are processed per second. Private static final RateLimiter RATE_LIMITER = RateLimiter. Create (2); @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return -5; } @override public Object run() throws ZuulException {log.info(" pass "); return null; } @Override public boolean shouldFilter() { RequestContext context = RequestContext.getCurrentContext(); if(! Rate_limiter.tryacquire ()) {log.warn(" Traffic overload "); / / specify the current request not by filtering context. SetSendZuulResponse (false); / / response code 429, returned to the client request too many context. SetResponseStatusCode (429); return false; } return true; }}Copy the code
So we can limit the number of requests to two per second. Is that cool?
Other things about Zuul
Zuul’s filter does more than just the two I’ve implemented above, it can also implement permissions verification, including grayscale publishing I mentioned above and so on.
Of course, Zuul as a gateway certainly has a single point of view. If we want to ensure high availability of Zuul, we need to configure Zuul clustering, which can be done with additional load balancers such as Nginx.
Spring Cloud Configuration Management — Config
Why use configuration management?
As our microservice system gradually expands, so many Consumer, Provider, Eureka Server and Zuul systems will have their own configurations. At this time, we may need to change the configurations of some applications when the project is running. If we do not carry out unified configuration management, We can only go to each application and find the configuration file one by one and then modify the configuration file and restart the application.
First of all, for distributed systems, we should not modify the configuration file individually for each application. Second, for restarted applications, the service is not accessible and therefore the availability is discarded, which is much less desirable.
Is there a way to manage configuration files uniformly and dynamically modify them while the project is running?
That’s the Spring Cloud Config that I’m going to introduce today.
Spring Cloud Config is not the only framework for configuration management. You can choose your own (Disconf, Apollo, etc.). And there are some areas where the implementation of Config is not satisfactory.
What is the Config
Spring Cloud Config provides server and client support for externalized configuration in distributed systems. Using the Config server, you can manage the external properties of applications in all environments from a central location.
To put it simply, Spring Cloud Config is the ability to store the configuration files of each application/system/module in a unified place and manage them (Git or SVN).
If you think about it, our application does not load configuration files only when it is launched, then our Spring Cloud Config exposes an interface for the startup application to get the configuration files it wants. The application gets the configuration files and then initializes it. See the picture below.
If I change the configuration file in the Remote Repository (Git) while the application is running, will any started application that depends on this configuration file change its configuration?
The answer is no.
What? So how do you dynamically modify the configuration file? Isn’t this configuration drift? You cheat and play with women’s feelings of the man 🤬, you cheat me again!
Don’t worry, you can use Webhooks, github provides this function to ensure that the configuration information in the client is updated after the configuration file in the remote library is updated.
Oh, oh, that’s more like it. I’ll find out how it works.
Webhooks will fix this, but if you read about them you will find that they are not suitable for production, so they are not likely to be used.
Generally, we will use the Bus message Bus + Spring Cloud Config to dynamically refresh the configuration.
Spring Cloud Bus is introduced
An event bus for linking services and service instances to distributed messaging systems. It is useful to propagate state changes (such as configuration change events) across the cluster.
You can think of Spring Cloud Bus simply as managing and broadcasting messages in a distributed system, which is the broadcast mode in a messaging engine system. Of course, Spring Cloud Bus as a message Bus can do a lot more than just client-side configuration refresh.
With Spring Cloud Bus, you can create a simple request and add the @ResFreshScope annotation to dynamically modify the configuration. Here’s a diagram for you to understand.
conclusion
In this article I’ve taken you through the various components of Spring Cloud that they have
-
Eureka service discovery framework
-
Ribbon load balancer
-
Open Feign service invocation mapping
-
Hystrix service degradation fuse
-
Zuul Microservices Gateway
-
Config Unified micro service configuration center
-
Bus Message Bus
If you can understand the following figure at this point, you already have some architectural understanding of Spring Cloud microservices.