preface

Only a bald head can be strong

The knowledge about SpringCloud summarizes an atlas to share with you:

SpringCloud GitHub Demo(after reading the article, students can practice their own) :

Github.com/ZhongFuChen…

Project structure Drawing:

What is clustering/distributed/microservices /SOA?

When I look at these words (cluster/distributed/microservices /SOA) and I’m a tech nerd, it feels like I’m out of reach (big tech!!). . Just like when I was learning Java object-oriented, I was browsing the materials on the forums and came across “aspect programming” and thought it was out of reach (cool technology!!). .

But when it comes to “faceted programming,” it’s not a big deal to realize that’s what it is. I was just intimidated by the name…

I wonder if you were intimidated when you first came into contact with the names cluster/distributed/microservices /SOA?

Here’s a brief description of what these nouns mean

2.1 What is a cluster

The following is from Wikipedia:

Computer cluster for short a cluster is a computer system that performs computing work in close collaboration through a loosely integrated set of computer software and/or hardware linked together. In a sense, they can be regarded as a computer. Individual computers in a clustered system, usually called nodes, are usually connected over a local area network, but other connections are possible. Cluster computers are often used to improve the computing speed and/or reliability of a single computer. In general, cluster computers cost much more than individual computers, such as workstations or supercomputers

Cluster technology features:

1. Achieve higher efficiency by using multiple computers to complete the same work.

2. The contents and working process of two or more machines are exactly the same. If one crashes, the other can kick in.

It’s pretty clear on Wikipedia, but let me give you an example.

Xiao Zhou is writing Java programs in the company, but the business of the company is developing, a Java developer may be too busy, xiao Zhou has to ask for leave sometimes. So I invited 3Y to do Java development together. Usually Xiao Zhou and 3Y write Java programs, but 3Y May have to go back to school. It’s ok, the company still has Xiao Zhou working on Java development, the company development can continue to operate.

1.3 Y and Xiao Zhou both do Java development.

2.3 Y is coming, and Xiao Zhou’s work can be shared.

Y is on leave, and Xiao Zhou is still here.

I wrote a 910 convenient network released to the server, now more and more people visit, access a little slow, how to do?? Very simple, (only charge money can be stronger), add configuration (add CPU, add memory). After the upgrade configuration, the number of visitors more and more, so found that can not help but use, in this machine to add configuration has been solved, how to do?? Very simple, (only charge money can become strong), I buy another server, 910 convenience network also released to the newly bought server.

Features:

1. The two servers are running the same system –>910 Convenience network

Benefits:

1. There was only one machine to handle the access, but now there are two machines to handle the access, sharing the pressure.

2. If one of them forgets to pay, it cannot be used for the time being. That’s okay. There’s another one you can use.

Clustering: The same business, deployed on multiple servers (different servers running the same code, doing the same thing)

2.2 What is Distributed

The following is from Wikipedia:

A distributed system is a group of computers connected through a network to transmit messages and communication and coordinate their behavior. Components interact with each other to achieve a common goal.

Let me give you an example:

Now the company has Xiao Zhou and 3y doing Java development together. Generally, we can write some jQuery and AJAX for Java development, so we are responsible for all these tasks.

However, 3Y is not very familiar with the front end, and some debugging can not be adjusted for a long time. The boss thinks 3Y is real! So let xiao Zhou specialized to deal with the front end of the matter. So 3Y will be happy, can concentrate on writing their own Java, the front end will be exclusively in charge of Xiao Zhou. So, Xiao Zhou and 3Y became collaborative development.

1.3Y is not familiar with the front end (it can be written), but it can take a lot of time to debug

2. Zhou specializes in front-end work, so 3y can concentrate on writing his own Java programs.

3. All for the normal operation and iteration of the project.

My 910 convenience network has been deployed to two servers, but more and more people are accessing it. And now it’s getting too much. So what now? So keep piling on the money and getting stronger?? As a rational person, I have to figure out what’s wrong. Now there are several 910 convenience network modules, all lost in the same Tomcat.

In fact, the access of some modules is very low (such as background management), so can I do this: extract each module independently, and use good server to install the module with large traffic, and use bad server to install the module with few people. Such advantages are: first, the reasonable use of resources (no one access to the module with poor performance of the server, the volume of the module alone to improve the performance is good). Two, the coupling degree is reduced: each module comes out independently, each doing its own thing (professional people do professional things), easy to expand.

Features:

The 910 convenience network function split, independent between modules, in the use of the time to combine these independent modules is a system.

Benefits:

1. Modules are independent, each doing its own thing, easy to expand, high reuse

2. High throughput. A task that requires one machine to run for 10 hours may be completed in 2 hours by using a distributed run of 10 machines (breaking the task into 10 smaller tasks)

Distributed: A business is split into several sub-services, deployed on different servers (different servers, running different code, for the same purpose)

2.3 Cluster/Distributed

Clustering and distribution are not in conflict, you can have distributed clusters

Now 3y is a much bigger company, with 5 guys writing Java, 4 guys writing front-end, 2 guys testing, and 1 guy as DBA.

1. The Relationship between Java, front end, test, and DBA is considered distributed

2.5 Java as a cluster (front-end, same with testing)…

2.4 Distributed/microservices /SOA

In fact, I think the concepts of distributed/microservices /SOA are pretty much the same. It’s just a matter of understanding one or the other and putting your own understanding on top of it. There is no need to break down the specific concept of each ~~(of course, I would love to see someone comment in the comments section)

References:

What is the difference between distributed and clustered? www.zhihu.com/question/20… Distributed, cluster, the difference between micro service, SOA blog.csdn.net/heatdeath/a…

Second, CAP theory

From the concept of distribution mentioned above, we already know that distribution is simply understood as: a service is divided into multiple sub-services and deployed on different servers

In general, a sub-business is called a node.

If you are familiar with the basic concepts of distribution, you will have heard of CAP. For example, if you have learned about MySQL’s InnoDB storage engine, you must have heard ACID!

First, let’s take a look at what CAP stands for:

1.C: Data consistency

All nodes have the latest version of the data

2.A: Availability

Data is highly available

3.P: Partition fault tolerance

Network partitions are tolerated, and the network between partitions is unreachable.

Here are three nodes (clustered), all of which can communicate with each other:

Since our system is distributed, communication between nodes is carried out through the network. In distributed systems, it is possible to have a situation where some nodes are disconnected due to some failure, and the entire network is divided into several regions.

The data is scattered in these disconnected areas, called partitions

Now after the network partition appears, a request comes in to register an account.

At this point we have node 1 and node 3 are not able to communicate, so we have a choice:

1. If the current user is allowed to register an account, the registered record data will be synchronized between node 1 and node 2 or between node 2 and node 3, because the records of node 1 and node 3 cannot be synchronized.

This is essentially a choice of availability over consistency if the current user is not allowed to register for an account (i.e., until node 1 and node 3 resume communication). Once node 1 and node 3 are communicating again, we can ensure that the nodes have the latest version of the data.

This is essentially a case of abandoning availability in favor of consistency

3.1 Let’s sort out CAP theory again

Generally we say distributed system, P: partition tolerance this is necessary, it is objective existence.

CAP cannot be taken into account completely. As can be seen from the above examples, we can choose EITHER AP or CP. However, it should be noted that C is not completely abandoned when AP is chosen. It does not mean that if CP is selected, A is completely abandoned!

In CAP theory, the consistency represented by C is strong consistency (the data of each node is the latest version), but there are other levels of consistency:

1. Weak consistency: Compared with strong consistency, weak consistency does not guarantee that the latest value can always be obtained;

Eventual consistency: Relaxes requirements on time. Data on multiple nodes will be agreed at a certain point after an operation is completed

The range of availability can be defined as a continuous range from 0 to 100%.

Therefore, CAP theory defines that “strong consistency” and “extreme availability” cannot be achieved at the same time while network partitioning is tolerated.

SpringCloud is that simple

I believe you have read here, have a certain understanding of distributed/micro services, in fact, from the concept alone, is very easy to understand. It’s just probably spooked by the name.

Let me talk about the basics of SpringCloud

4.1 Why is SpringCloud needed?

As mentioned earlier, from a distributed/microservices perspective, it means breaking up our large project into smaller modules. These small modules combine to complete the function.

Here’s an example that might not be appropriate (the reality might not be split this way, but the point is good) :

There are all sorts of problems that arise when you break down multiple modules, and SpringCloud provides a complete solution!

Note: These modules are separate subsystems (different hosts).

Basic features of SpringCloud:

1. Service governance: Spring Cloud Eureka

2. Client load balancing: Spring Cloud Ribbon

3. Service fault tolerance protection: Spring Cloud Hystrix

4. Declarative service invocation: Spring Cloud Feign

5.API Gateway service: Spring Cloud Zuul

6. Distributed configuration center: Spring Cloud Config

Advanced features of SpringCloud (not covered in this article) :

1. Message Bus: Spring Cloud Bus

2. Message-driven microservices: Spring Cloud Stream

3. Distributed service tracking: Spring Cloud Sleuth

4. Introduce Eureka

What could go wrong? The first is the communication between subsystems. Subsystems are not in the same environment as each other, so remote calls are required. Remote calls can be implemented using httpClient, WebService, etc.

Since it is a remote call, we must know the IP address, and we may have the following scenario.

Function implementation 1: Service A needs to invoke service B

In service, A service code inside call B explicit calls by IP address: http://123.123.123.123:8888/java3y/3

Function realization two: A service calls B service, B service calls C service, C service calls D service

In service, A service code inside call B explicit calls by IP address: http://123.123.123.123:8888/java3y/3, (the same) – > B, C, C – > D

Function realization three: D service calls B service, B service calls C service

Invoke service B in D service code, explicit calls by IP address: http://123.123.123.123:8888/java3y/3, B – > C (again)

In the event that the IP address of our service B changes, imagine what would happen: Service A, service D (and so on) would need to manually update service B’s address

Maintaining these static configurations manually is a nightmare in the case of multiple services!

To solve the problem of service instance maintenance (IP address) in microservices architecture, a large number of service governance frameworks and products have emerged. The implementation of these frameworks and products all revolve around the mechanism of service registration and service discovery to automate the management of microservice application instances.

Eureka is commonly used in our service governance framework in SpringCloud.

Our question:

There are now four services, A, B, C, and D, which call each other (and whose IP addresses are likely to change). When A service’s IP address changes, the code in the service changes with it. Manually maintaining these static configurations (IP) is very troublesome!

Here’s how Eureka solved the above situation:

Create an E service and register the information of services A, B, C, and D with the E service. The E service maintains the registered information

Services A, B, C and D can all get the registration list of Eureka(Service E). Services A, B, C, and D invoke each other using service names instead of specific IP addresses.

Get the registration list -> the registration list has the service name -> naturally can get the specific location of the service (IP). The IP address will change, but the service name will not change.

4.1 details had been

Eureka is specifically used to register other services called Eureka Server(Service registry), and the remaining services registered with Eureka Server are called Eureka Clients.

In Eureka Server, we usually configure the following:

Register-with-eureka: false #false indicates that you do not register yourself with the registry. False #false indicates that my end is the registry and my responsibility is to maintain the service instance, not to retrieve the serviceCopy the code

Eureka Client is divided into service providers and service consumers.

It is possible, however, that a service is both a service provider and a service consumer. Don’t be too surprised to see on the web that a SpringCloud service configuration is not “registered” with Eureka-Server (but it can get a list of Eureka services)

It is possible that the author simply considers the service as a pure service consumer, who does not need to provide services externally and thus does not need to register with Eureka

Eureka: client: register-with-eureka: false http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/Copy the code

The following is the governance mechanism of Eureka:

1. Service providers

Service registration: When started, it registers itself with Eureka Server by sending REST requests, along with some metadata information about its own service.

Service renewal: After registering the service, the service provider maintains a heartbeat that continuously tells the Eureka Server: “I’m still alive”, Service offline: When a service instance performs a normal shutdown operation, it triggers a REST request to Eureka Server for the service offline, telling the service registry “I’m going offline”.

2. Serve consumers

Get the Service: When we start the service consumer, it sends a REST request to the service registry to get the list of services registered above

Service invocation: After obtaining the list of services, the service consumer can obtain the name of the instance that provides the service and the metadata information of that instance. Service providers in the same Zone are preferentially accessed during service invocation.

3.Eureka Server(Service Registry)

Invalid Culling: By default, services that have not been renewed due to timeout (default: 90 seconds) in the current list are excluded from the list at regular intervals (default: 60 seconds).

Self protection:. When EurekaServer is running, it calculates whether the rate of heartbeat failure within 15 minutes is less than 85%(usually due to network instability). The Eureka Server protects the current instance registration information so that it does not expire and protects the registration information as much as possible. Finally, we have this picture:

Here’s an example:

1.3 Y went shopping with his girlfriend in Dongfang Baotai of east Railway Station, but he didn’t know what was interesting in Dongfang Baotai. So I went to the property management office to search the list of Oriental Baotai merchants. I found uniqlo on the first floor, Starbucks on the second floor and McDonald’s on the third floor.

2. Next to Uniqlo, there is the newly opened KFC, with a big sign “Welcome KFC to Oriental Baotai” on the wall.

The merchants need to pay the property management fee regularly.

4. Property management maintains the stability of Oriental Baotai. If a business does not want to operate in Oriental Treasure Tai, tell the property. Property will naturally remove its list of Oriental Baotai merchants.

Introduce the RestTemplate and Ribbon

With the Eureka service governance framework, we can obtain the location (IP) of a specific service instance by the service name. You generally do not need to manually create HttpClient to make remote calls when using SpringCloud.

The RestTemplate utility class wrapped in Spring is simple to use:

// The traditional way, directly show write dead IP is not good! //private static final String REST_URL_PREFIX = "http://localhost:8001"; // Service instance name private static final String REST_URL_PREFIX = "http://MICROSERVICECLOUD-DEPT"; /** * Using restTemplate to access restful interfaces is very simple and crude. (URL, requestMap, * responseBean.class) represent the REST request address, request parameters, and the object type to which the HTTP response transformation is converted. */ @Autowired private RestTemplate restTemplate; @RequestMapping(value = "/consumer/dept/add") public boolean add(Dept dept) { return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class); }Copy the code

To achieve high availability of services, we can cluster service providers. For example, now a seckill system is designed and ready to go live. On November 11th, in order to support high concurrency, we ran multiple machines to support concurrency.

Now, if you want these three split-kill systems to properly distribute user requests (load balancing in the technical sense), you might think of NGINx.

In fact, SpringCloud also supports load balancing, but it is the client side load balancing, which is implemented by the Ribbon!

There are two types of load balancing:

Client Load Balancing (Ribbon)

The list of service instances is on the client, and the client implements load balancing algorithm allocation.

(From the above we already know that the client can get a list of services from Eureka Server and use load balancing algorithm to select one of multiple servers to access when sending a request.)

Server Side Load Balancing (Nginx)

List of service instances On the server side, the server performs load balancing algorithm allocation

So, our graph could look something like this:

5.1 Ribbon details

The Ribbon supports load balancing. The default load balancing policy is polling. You can customize the load balancing policy based on your requirements.

@Configuration public class MySelfRule { @Bean public IRule myRule() { //return new RandomRule(); // The Ribbon defaults to RoundRobinRule(); Return new RandomRule_ZY(); // Ribbon defaults to polling. // I customize 5 times per machine}}Copy the code

AbstractLoadBalancerRule class and override public Server Choose (ILoadBalancer LB, Object key).

SpringCloud uses AP in CAP theory, and there is a retry mechanism in the Ribbon

Here’s an example:

1.3 Y spent a few months with his girlfriend and went to Oriental Baotai again. Because memory is not good, and went to the property that made a list of Oriental Treasure Tai merchants.

2. This time, Oriental Baotai opened another McDonald’s, one on the second floor and one on the third floor. Business was so good that in order to improve user experience, we opened an extra McDonald’s on the second floor.

3. At this point, 3Y asks his girlfriend: “Which McDonald’s is better? Shall we flip a coin?” 3Y girlfriend: “Are you stupid? You must go to the nearest one.”

Introduce Hystrix

So far, our service looks pretty good: the ability to call other services remotely based on their names, and load balancing on the client side.

But t what happens if we call multiple remote services and one service is delayed?

In the case of high concurrency, due to the delay of a single service, all requests may be delayed, and even in a few seconds, the service will be overloaded, the resources will be exhausted, and the distributed system will become unusable. This is an “avalanche”.

Spring Cloud Hystrix implements a series of service protection features such as circuit breakers and thread isolation to address these problems.

1.Fallback: When a service unit fails (similar to a short circuit in an appliance), an error response is returned to the caller through the fault monitoring of the circuit breaker (similar to blowing a fuse) instead of waiting for a long time. In this way, threads will not be held for a long time due to invocation of faulty services, and the spread of faults in distributed systems is avoided.

2. Resource/dependency isolation (thread pool isolation) : It creates a separate thread pool for each dependent service, so that if there is too much latency for one dependent service, it only affects the invocation of that dependent service and does not slow down other dependent services.

Hystrix provides several key fuse parameters: sliding window size (20), fuse switch interval (5s), error rate (50%)

1. When 50% of the 20 requests fail, the fuse is turned on. If the service is invoked again, a failure message is returned and the remote service is not invoked.

2. Check the trigger condition again after 5 seconds to determine whether to turn off the fuse or continue to turn on the fuse.

Hystrix also has powerful functions such as request merge and request cache. I won’t go into details here, but you can continue to learn more about Hystrix

6.1 Hystrix dashboard

Hystrix Dashboard: It is used to monitor Hystrix indicators in real time. The real-time information provided by the Hystrix Dashboard helps us quickly identify problems in the system and take timely action.

Page at startup:

Monitoring single service page:

Our current service looks like this:

In addition to monitoring pages that can be opened for individual instances, there is also a monitoring endpoint /turbine. Stream for clusters. From the name of the endpoint, Turbine could be introduced to aggregate monitoring information and provide the aggregated information to the HystrixDashboard for centralized display and monitoring.

Here’s an example:

1.3 Y and his girlfriend decided to go to Wanda for fun. When they went to the parking lot of Wanda, they found that “The negative floor is full, please go down to the negative floor, there are 100 free parking Spaces on the negative floor!”

2. At this moment, 3Y said to his girlfriend, “Wanda parking lot is doing a good job. If wanda didn’t directly tell me that negative floor 1 was full, I might go to negative floor 1 to find a place. 3Y went on to say: “It’s also good to look at the state of the parking space. There is a sensor above the parking space, if it’s red it means it’s stopped, if it’s green it means it’s empty.”

3.3 Y’s girlfriend disdained: “You really talk a lot”

Introduce Feign

The Ribbon and Hystrix have been introduced above, but they are widely used as basic toolclass frameworks for microservices. We will find that the use of both frameworks occurs almost simultaneously.

To simplify our development, Spring Cloud Feign came along! It is based on the Netflix Feign implementation and integrates Spring Cloud Ribbon with Spring Cloud Hystrix. In addition to combining the power of the two, it also provides for declarations of service invocation (no longer through RestTemplate).

Feign is a declarative, templated HTTP client. Using Feign in Spring Cloud, we can make remote service requests using HTTP have the same coding experience as local methods, without the developer perceiving that it is a remote method, much less an HTTP request.

Here’s a quick look at how Feign gracefully implements remote calls:

Service binding:

@feignClient (value = "microServicecloud-dept ", fallbackFactory = DeptClientServiceFallbackFactory.class) public interface DeptClientService { // With Feign we can use SpringMVC annotations to bind the service! @RequestMapping(value = "/dept/get/{id}", method = RequestMethod.GET) public Dept get(@PathVariable("id") long id); @RequestMapping(value = "/dept/list", method = RequestMethod.GET) public List<Dept> list(); @RequestMapping(value = "/dept/add", method = RequestMethod.POST) public boolean add(Dept dept); }Copy the code

Fuses used in Feign:

/** * Feign uses circuit breakers * this is mainly used to handle exception error cases (demote/fuse service is not available, fallback will find this) */ @component // Don't forget to add, Don't forget to add the public class DeptClientServiceFallbackFactory implements FallbackFactory < DeptClientService > {@ Override public DeptClientService create(Throwable throwable) { return new DeptClientService() { @Override public Dept get(long id) { Return new Dept().setdeptno (id).setdName (" SetDb_source ("no this database in MySQL"); setDb_source("no this database in MySQL"); } @Override public List<Dept> list() { return null; } @Override public boolean add(Dept dept) { return false; }}; }}Copy the code

Call:

Eight, introduce Zuul

Based on what we learned above, our current architecture is likely to look like this:

There are two troubling problems with such an architecture:

1. Routing rules and service instance maintenance: The external load balancer (NGINx) needs to maintain the list of all service instances (OpenService).

2. The signature validation, login check redundancy problem: in order to guarantee the safety of the foreign service, we in a service interface, implementation of a service often has certain permissions checking mechanism, but our service is independent, we have to in these applications are implementing such a set of validation logic, this will cause validation logic redundancy.

Let’s draw a picture to understand this:

Each service has its own IP address, and Nginx must maintain the address of each service instance in order to properly request forwarding to the service!

To make matters worse, the IP addresses of these service instances may change, as will the division between services.

http://123.123.123.123

http://123.123.123.124

http://123.123.123.125

http://123.123.123.126

http://123.123.123.127

Shopping cart and order module can be accessed normally only after user login. Based on the current architecture, the verification logic can only be written in both shopping cart and order module, which is undoubtedly redundant code.

To address these common architectural problems, the concept of an API gateway was born. An API gateway component, SpringCloud Zuul, based on an implementation of Netfl IX Zuul, is provided in SpringCloud.

Spring Cloud Zuul solves these two problems:

1.SpringCloud Zuul registers itself as an application under Eureka service governance by integrating with SpringCloud Eureka, and obtains instance information of all other microservices from Eureka. The outer calls must go through the API gateway, leaving the job of maintaining service instances to the service governance framework to automate.

2. Make a unified call on the API gateway service to pre-filter the microservice interface, so as to realize the interception and verification of the microservice interface.

Zuul naturally has thread isolation and circuit breakers for self-protection, as well as client-side load balancing for service calls. That said: Zuul also supports Hystrix and Ribbon.

There’s a lot more to know about Zuul (which I won’t go into here for space reasons) :

1. Route matching (dynamic route)

2. Filter implementation (dynamic filter)

3. Cookies and sensitive HTTP headers are filtered out by default (extra configuration)

8.1 Possible questions about Zuul

Zuul supports the Ribbon and Hystrix, as well as client load balancing. Isn’t our Feign also client-side load balancing and Hystrix? Now that Zuul has been implemented, is our Feign still necessary?

Or it can be interpreted as:

1. Zuul is the only exposed interface. The request of Controller is routed, while the request of Service is routed by Ribbonhe and Fegin

2. Zuul performs load balancing for the outermost requests, while Ribbon and Fegin perform load balancing for service calls of microservices within the system

With Zuul, do you need Nginx? Can they use it together?

Zuul and Nginx can be used together (after all, Zuul can also be clustered for high availability), it depends on the complexity of the architecture (business)

References:

Microservices and API Gateways (PART 1) : Why do YOU Need AN API Gateway? : blog.didispace.com/hzf-ms-apig… Talk about the API gateway: www.jianshu.com/p/b52a2773e… Talk about API Gateway in micro service Gateway (API) : www.cnblogs.com/savorboard/… API Gateway performance comparison: NGINX vs. ZUUL vs. Spring Cloud Gateway: www.360doc.com/content/18/… About API gateway background, architecture, as well as the floor plan: www.infoq.com/cn/news/201… Zuul and nginx:zhuanlan.zhihu.com/p/37385481

SpringCloud Config

As our business expands, we will have more and more services. Each service has its own configuration file.

Since it is a configuration file, it will inevitably change something for us to configure.

For example, in our Demo, each service writes the same configuration file. If one day, we need to change the password in the configuration file, we will have to change all three.

In distributed systems, a change in basic service information is likely to result in a series of updates and restarts

The Spring Cloud Config project is a configuration management solution for distributed systems. It consists of a Client and a Server. The Server stores the configuration file and provides the content of the configuration file in the form of an interface. The Client obtains data through the interface and initializes its application based on the data.

To put it simply, using Spring Cloud Config means putting configuration files in a centralized location (such as GitHub) that the client can retrieve via an interface. When you modify a configuration file on GitHub, the application loads the modified configuration file.

SpringCloud Config Additional knowledge:

1. On the server side of SpringCloud Config, Git is used as the default implementation of the configuration repository, and SVN can also be configured.

2. Encrypt and decrypt the information in the file

3. Modified the configuration file, hoping to dynamically refresh the configuration without restarting, and use ~ with Spring Cloud Bus

Possible problems with Using SpringCloud Config: application. Yml is different from bootstrap.yml

The last

I here organized a SpringCloud related information documents, Spring series of family barrel, Java systematic information (including Java core knowledge, interview topics and 21 years of the latest Internet real questions, e-books, etc.) friends who need to pay attention to the public number [procedures yuan Small wan] can be obtained.