“This is the 17th day of my participation in the First Wen Challenge 2022.First challenge in 2022”

SpringCloud microservices distributed

This article is based on the previous code to modify learning click 👍

The basic architecture of Eureka

I learned the basics of Eureka in my last post

  • Eureka consists of two components:Eureka ServerandEureka Client
  • Eureka Server registryThe Client ClientProvide:Service registration and service discovery capabilitiesAfter each node Client is started, it is registered in EurekaServer so that the service registry in EurekaServer stores information about all available service nodes.(The information of the service node can be seen intuitively in the interface)
  • EurekaClient is a Java clientTo simplify the interaction with Eureka Server, the client also has a built-in load balancer that uses round-robin load algorithms.After the application starts, it willOn a regular basisSends heartbeat to Eureka Server (default interval: 30 seconds).If no heartbeat is received from a node,EurekaServer will remove the service node from the service registry (default: 90 seconds)

Eureka Server ha cluster

Microservers always use data from the local cache when consuming remote apis. Therefore, in general, even if Eureka Server goes down, the calls between services will not be affected.

  • But if EurekaServer goes down, some microservices become unavailable

  • If the cache in Eureka Server is not refreshed, it may affect the invocation of microservices and even the high availability of the entire application system.

  • Therefore, a cluster of highly available Eureka Servers is typically deployed in a build environment.

  • Benefits: Build Eureka clusters and if one of the Eureka registries goes down during application development. Even if, at this point, a Eureka Client changes/stops… Records are also managed by other registries… Make your application highly available

  • Eureka Server can run multiple instances andEach registeredTo implement cluster ha deployment

  • Eureka Server instances incrementally synchronize information with each other to ensure consistent data on all nodes.Registering nodes with each other is the default behavior of Eureka Server. (Above: Cluster operations between three registries… Synchronize data between registries and manage provider and ComSumer togetherIf one hangs, the operation will not be affected.)

Set up a Eureka Server HA cluster

Copy the eureka-Server registry you wrote earlier

For eureka-server2 to facilitate operation between copy

  • Change the name…
  • Modify the project name in pom.xmleureka-server2
  • The main Maven projectpom.xmlAdd a dependency ~ to

This is not clear enough for anyone who has learned Maven…Maven pom Lord. XML

     <! The Maven parent project contains the management child project... -->
     <modules>
         <module>common_api</module>
         <module>common_orderService</module>
         <module>common_userService</module>
         <module>eureka-server</module>
         <module>eureka-server2</module>     <! Update Maven to add copy projects to projects... -->
         <module>import-demo</module>
     </modules>
Copy the code

Ok, so that’s about itRegistration center

Modify port/configuration of registry:

The next step is to configure the registry…. Eureka – server2. Yml

 server:
   port: 7002                # modified... Port of the registry; (Know that ports are unique...)
 spring:
   application:
     name: eureka-server     The registry application name does not need to be changed...
 
 # Configure the registry....
 eureka:
   client:
     service-url:            # Registered address leaked from registry... Comma separated, no Spaces!!
       defaultZone: http://localhost:7002/eureka/,http://localhost:7001/eureka/
     fetch-registry: false
     register-with-eureka: false      
Copy the code

Eureka – server.yml

 server:
   port: 7001                # registry port;
 spring:
   application:
     name: eureka-server     The registry application name does not need to be changed...
 # Configure the registry....
 eureka:
   client:
     service-url:    # Registered address leaked from registry...
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
     fetch-registry: false
     register-with-eureka: false
Copy the code

test

Start the Eureka-Server registry Start common_orderService orders module | common_userService user module Start the Eureka-Server2 registry

Closing the 7001 registry and testing will not affect the use of… Note:

  • Because the registry is closed, Eureka’s client will detect itA registry is downOut of the ordinary!
  • But will not affect the use!

Ok, Eureka is in effect!

Eureka cluster summary:

  • Create two exception portsportF, basically the sameThe registry

  • To its. Two registry interdependence in the configuration of yml: = = defaultZone: http://localhost:7002/eureka/, http://localhost:7001/eureka/==

    Eureka source code analysis

Automatic loading in SpringBoot

The ImportSelector interface is the core interface Spring uses to import external configuration

In the automated configuration of SpringBoot and @enablexxx (functional annotations)Decisive role.

First ImportSelector is an interface:

  • When in the Class annotated at @Configuration
  • After introducing an ImportSelector implementation class using @import
  • All Class names returned by methods in the implementation Class are defined as beans.
 public interface ImportSelector { 
     // Implement interface need to override method, return value is an array... Store class name data;
     // Use @import in an @Configuration class to introduce the implementation class of the interface;
     // All class names are defined as beans...
    String[] selectImports(AnnotationMetadata var1); 
 }
Copy the code

DeferredImportSelector interface and ImportSelector

DeferredImportSelector is a subinterface to ImportSelector… DeferredImportSelector. Java interface

 public interface DeferredImportSelector extends ImportSelector {... }Copy the code

To view:

  • Go to @SpringBootApplication — go to — @enableAutoConfiguration
 @Target({ElementType.TYPE})
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
 @Inherited
 @AutoConfigurationPackage
 @Import({AutoConfigurationImportSelector.class})    / / enter AutoConfigurationImportSelector. Class
 public @interface EnableAutoConfiguration {
     String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<? >[] exclude()default {};
 ​
     String[] excludeName() default {};
 }
Copy the code

Enter — AutoConfigurationImportSelector. Class DeferredImportSelector role:

  • The DeferredImportSelector interface inherits ImportSelector
  • The difference between this and the ImportSelector is when the bean is loadedDeferredImportSelector does not load until all @Configuration is executed…Must be slower than ImportSelector...

Customize one using ImportSelector@EablexxStartup notes:

Implementation: @eabelexxx starts class annotations. Only with annotations can you use this class in your program.@Eable cannot use class as method () if not started...

This time add a module import_Eable

Create entity under com.wsm.entity package:

Define the Bean object user.java

 public class User {
     String name;
     String age;
     / / omit get/set/toString...
 }
Copy the code

Com.wsm. config config package to start the implementation code:

Define the Configuration class. Configuration Class Userconfig.java

 // The @configuration class does not declare a Configuration class, but it already uses @bean for load injection;
 public class UserConfig {
     @Bean
     public User createUser(a) {
         User u = new User();
         u.setName("Zhang");
         u.setAge("12");
         returnu; }}// It is not immediately loaded into the Spring container, but the following classes are uniformly loaded by ImportSelector...
Copy the code

Define ImportSelectorUserImportSelector. Java

 //UserImportSelector implements the ImportSelector interface, overriding the method...
 public class UserImportSelector implements ImportSelector {
 ​
     @Override
     public String[] selectImports(AnnotationMetadata annotationMetadata) {
         return new String[]{UserConfig.class.getName()};       // Return an array of strings containing the names of the classes to be loaded..
     }
     // The method return value character array [] contains the class to be loaded via @import...
 }
Copy the code

Custom create open annotations:EnableUser.Java

 @Retention(RetentionPolicy.RUNTIME)     // Class execution completes when the class is loaded
 @Documented
 @Target(ElementType.TYPE)
 //------- These are Java annotations
 @Import(UserImportSelector.class)   // Import the implementation Class with import(UserImportSelector.Class)..
 public @interface EnableUser {
     // Use @interface to define a custom annotation: @enableuser;
     // It is a binding annotation that contains one inside: @import (UserImportSelector. Class)
     // using @enableUser is equivalent to using @import (UserImportSelector. Class)!!
 }
Copy the code

ok ! . Project Maven release:install: internal contains clean package deploy test compile… Operation;

Testing:

The Jar package has been prepared and published to Maven’s local repository… So now direct: project references can use annotations… I am using a registry that is not often used otherwise and there is already a User class in the order and User module to avoid conflicts and facilitate testing…


Operation start:

  • The pom.xml of the eureka-server2 module is introduced into the import_Eable module
  • Refresh Maven to the main program class using the @eableUser annotation MyEurekaServer2 .Java
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 import org.springframework.context.ConfigurableApplicationContext;
 import wsm.config.EnableUser;  // This is just a custom annotation!! This will enable the loading of the User class...
 import wsm.entity.User;
 ​
 @SpringBootApplication         // Also know that there is an @SpringBootConfiguration under the @SpringBootApplication annotation
 @EnableEurekaServer            // Comments main program to start Eureka service
 @EnableUser                    // Import custom annotations to complete the following User
 public class MyEurekaServer2 {
     public static void main(String[] args) {
         ConfigurableApplicationContext run = SpringApplication.run(MyEurekaServer2.class, args);
 ​
         User u = (User) run.getBean("uu");     // load into the Spring container according to @bean ("uu"); Via @eableUser!System.out.println(u); }}Copy the code

Eable comment out; error when running!! What a strong note! This is like a class switch that you turn on when you need it and off when you don’t! then@EnableEurekaServerThe autowiring of….(behind separate out a detailed explanation… Chinese New Year more!

Eureka replacement plan Consul

Eureka closed source effect

Eureka 2.x closed source announced on Euraka’s GitHub. This means that developers continue to use code bases and artifacts released as part of an existing working REPO on the 2.x branch at their own risk. Alas, it is a pity that we need to find a new registry

Consul overview

Consul is a popular service discovery tool in recent years. Consul has three main application scenarios: service discovery, service isolation, and service configuration.

  • Consul is an open source tool from HashiCorp for service discovery and configuration in distributed systems.
  • Consul’s solution is more “one-stop” than other distributed service registration and discovery solutions
  • Built-in service registration and discovery frame, distributed consistency protocol implementation, health check, Key/Value storage, multi-data center solution
  • No longer need to rely on other tools (such as ZooKeeper, etc.). It is also simpler to use.
  • Consul is written in the Go language, making it naturally portable (Linux, Windows, and Mac OS X support);
  • The installation package contains only one executable file for easy deployment and works seamlessly with lightweight containers such as Docker.

Consul’s advantages:

  • Raft algorithm is used to ensure consistency, which is more straightforward than the complex Paxos algorithm. Zookeeper uses Paxos while ETCD uses Raft.
  • Supports multiple DCS, and uses different ports for listening on Intranet and extranet services.Multi-dc cluster can avoid single point of failure of a single DC, and its deployment needs to consider network latency and fragmentation.Zookeeper and ETCD do not support the MDC function.
  • Supports health check. Etcd does not provide this functionality.
  • Supports HTTP and DNS interfaces. Zookeeper integration is complex, and ETCD supports only HTTP.
  • The official web management interface etCD does not provide this function.
  • Consul is a rising star in service registration and configuration management

Consul versus Eureka

  • consistencyCAPConsul Strong Consistency (CP) Eureka guaranteedHigh availabilityAnd final consistency (AP)
  • Develop language and usageEureka is a servlet application that runs in a servlet containerSpringBoot internally integrates Tomcat..Consul is written from go and can be installed and startedStart one before useStart the programconsul.exe

CAP principle is also called CAP theorem

  • It refers to consistency in a distributed systemConsistency, availability,Availability, partition fault tolerancePartition tolerance
  • The CAP principle is that, at best, these three elements can achieve two, not all at once.
  • Consistency of CWhether all data backups in a distributed system have the same value at the same time. The registry is represented by:In a clustered registry environment, a client service sends changes, registers with the registry,  All registries must be synchronized before requests can continue…
  • Availability of AEnsure that every request has a response regardless of success or failure.Final consistencyThe registry is represented by:In a clustered registry environment, a client service sends changes, registers with the registry,  No, all registries are synchronized to continue operations… It will continue the current operation, silently doing synchronization in the background
  • Partition tolerance pThe loss or failure of any information in the system does not affect the system operation.P represents the network communication protocol in the synchronization process...

What is high availability?

  • High availability, or HA for short
  • A feature or indicator of a system that provides a higher performance than the average normal service time.

Consul download and installation

It says that a client is required to execute the program to start:consul.exe

Under CMD, specify the client execution program directory:Consul. Exe agent - dev - client = 0.0.0.0 Local boot access:localhost:8500 Request to via GEThttp://127.0.0.1:8500/v1/catalog/servicesView the list of all servicesRequest to via GEThttp://127.0.0.1:8500/v1/catalog/service/Service Name View service details


Basic use of Consul

  • Consul supports health checks and provides apis for HTTP and DNS calls to complete service registrations
  • Service discovery, and K/V storage of these functions. Get a feel for Consul by sending an HTTP requestFollow-up to learn..

Service registration and discovery Go to Baidu to find out what it's worth...Send a PUT request to postmanhttp://127.0.0.1:8500/v1/catalog/register{“Datacenter”: “dC1 “, “Node”: “node01”, “Address”: “192.168.74.102”, “Service”: {“Datacenter”:” dC1 “, “node01” : “192.168.74.102”, “Service”: {” ID “:” mysql – 01 “, “Service” : “mysql”, “tags” : / “master”, “v1”, “Address” : “192.168.74.102”, “Port” : 3306}


Consul based service registration

Find a microservice module to modify, first of all, this module before the Eureka configuration comment out!! Because we’re using Consul as our registry…


Consul Registry through the applicationBoot directly!!

Modify the poM file associated with the microservice common_orderService order module:

Will eureka depend onpom.xmlAnd the configuration.ymlRemove, useConsul Registry

Add the Consul based dependencies provided by SpringCloudPom.xml

 
      
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>SpringCloudBJ</artifactId>
         <groupId>org.example</groupId>
         <version>1.0 the SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 ​
     <artifactId>common_orderService</artifactId>
 ​
     <! -- Key!! -->
     <dependencies>
         <! -- common_orderService project introduced common_API -->
         <dependency>
             <groupId>org.example</groupId>
             <version>1.0 the SNAPSHOT</version>
             <artifactId>common_api</artifactId>
         </dependency>
         <! Eureka-server service dependency -->
 <! -- <dependency>-->
 <! -- <groupId>org.springframework.cloud</groupId>-->
 <! -- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>-->
 <! -- </dependency>-->
 ​
         <! -- Consul based service Registration
         <! -- Service discovery based on Consul provided by SpringCloud -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-consul-discovery</artifactId>
         </dependency>
         <! -- Use it to check heartbeats -->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>
     </dependencies>
 </project>
Copy the code

Configuring service Registration.yml

 server:
   port: 6001            # set port 6001 to 6001
 spring:
   application:
     name: order-server  # set the name of the micro service, the following registration/call service is based on this;
 Configuration of consul;
   cloud:
     consul:                 Cloud add: Consul configuration;
       host: 127.0. 01.       Consul's Server request address
       port: 8500            # indicates the port of Consul's Server
       discovery:            Configure service registration and discovery
         register: true
         instance-id: ${spring.application.name}-${server.port}  ${spring.application. Name}-${server.port} ${spring.application. Name}-${server.
         service-name: ${spring.application.name}
         port: ${server.port}
         ip-address: ${spring.cloud.client.ip-address}           Request IP for the current micro service
         prefer-ip-address: true                                 To enable IP address registration is to display IP
 # Original Eureka registration service configuration...
 #eureka:
 # client:
 # service-url:
 # # defaultZone: http://localhost:7001/eureka/, http://localhost:7002/eureka/ specified service registry registry;
 # instance:
 # prefer-address: true # prefer-address: true # prefer-address: true # prefer-address: true
 # instance-id: ${spring.cloud.client. Ip-address}:${server.port} # instance-id: ${spring.cloud.client.
 # lease-renewal-interval-in-seconds: 5
 # lease-expiration-duration-in-seconds: 10 # If there is no delay in renewing the heartbeat...
Copy the code

Modify theService/ClientConsul Registry

Modify the common_orderService order module main program annotation to myOrderServer.java

 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 //import org.springframework.cloud.netflix.eureka.EnableEurekaClient; // Comment the Eureka reference
 ​
 @SpringBootApplication
 // @enableEurekaclient //Eureka special annotations start client registration ~
 @EnableDiscoveryClient      // General registry notes ~
 public class MyOrderServer {
     public static void main(String[] args) { SpringApplication.run(MyOrderServer.class, args); }}Copy the code
  • Will @ EnableEurekaServerEureka special registration annotationsReplacement for @ EnableDiscoveryClientCommon registry annotations
  • Start main program: Don’t forget to start Consul client or you’ll get an error! Failed to start ~
  • @enableDiscoveryClient This is a universal annotation that can be used by clients and servers, even if your registry is Eureka!

Summary using Consul Registry:

  • If it was a microservice from another registry;Clean up other registry code
  • Local boot up well in advanceConsulThe registry
  • Importing Consul Dependenciespom.xml
  • configured.ymlfile
  • Use the common Startup Registration Service annotation:@EnableDiscoveryClient Refresh the page to see the microservicesRegistered to the Consul

Ribbon The clientLoad balancing

Change the above cousul registry to the Eureka registry to illustrate:Eureka integrates Reibbon internally

What is theLoad balancing

  • Load balancingIt's a computer technology
  • Used to distribute load among multiple computers (clusters of computers), network connections, CPUS, disk drives, or other resources
  • To optimize resource usage, maximize throughput, minimize response time, while avoiding overload.

Why do you need load balancing

  • In our daily life, we often have to go to some crowded places, such as subway stations, railway stations, cinemas, banks and so on.
  • Whether buying tickets or queuing for admission, these places will generally set up multiple service points or entrances. In most cases, the nearest entrance will be crowded if there is no one to guide it. The service points or entrances that are far away are much looser. In this case, there is a huge waste of resources
  • Because if these queuing people can be well dispersed to each entrance, it will greatly shorten the queuing time.
  • In fact, the construction of the website is the same. In order to improve the service capacity of the website, many websites adopt cluster deployment, like a theater with multiple entrances. At this point, a coordinator is needed to evenly distribute these user requests, so that users can be evenly distributed to different servers.

What is Ribbon?

  • The Ribbon is a Netflix load balancer that helps control HTTP and TCP client behavior.
  • In SpringCloud, Eureka is used in conjunction with the Ribbon, which provides client load balancing functions. The Ribbon uses the service information it reads from Eureka.
  • When a service node is called to provide a service, the load is reasonable.
  • Load balancer on the client side, not the server side.

The main functions of the Ribbon

  • Service invocation gives the Ribbon a service name-request path mapping of all the services that pull through the channel when a service invocation is implemented. The final call is made with the RestTemplate
  • Load balancing When there are multiple service providers, the Ribbon automatically selects the service address to invoke based on the load-balancing algorithm

build

Because Eureka is integrated with the Ribbon, there is no additional dependency loading.

  • When creating the RestTemplate, declare @loadBalanced
  • Invoke remote microservices with restTemplate:There is no need to concatenate the URL of the microservice, waiting for the requested service name to replace IP address!!

Copy an order module directly to common_orderService2

The provider provides two identical order modules to doLoad balancing ~

  • Modify the pom.xml project name
  • The parent pom.xml is introduced to connect Maven ~ Same as the above two registries
  • Changing the port NumberAlthough the service functions are the same, the port is unique common_orderService1 6001 common_orderService2 6003 6002 is used by user module...

Distinguish between two order modules ~

Ok, after two almost identical order modules are finished (module name and port are different)… Common_orderService OrderService.java = common_orderService orderService.java = common_orderService orderService.java

 @Service
 public class OrderService {
     // Simulate fake order set...
     private static List<Order> orders = new ArrayList<>();
     // Class load gets some data by default.. Simulated fake orders..
     static {
         orders.add(new Order(1."The order 11".10.0.1));
         orders.add(new Order(2."Order 21".10.0.2));
         orders.add(new Order(3."Order 31".10.0.1));
         orders.add(new Order(4.41 "order".10.0.2));
     }
 ​
     / / get the host IP post -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - load balance ~
     // @value (" ${} can be used to obtain the Value in the properties file.. And assign to the object ~")
     @Value("${spring.cloud.client.ip-address}")
     private String ip;
     @Value("${server.port}")
     private String post;
 ​
     // Get the order set according to the input user ID..
     public List<Order> findOrderByUser(Integer uid) {
         / / in order to distinguish between load balancing IP call to print and post -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - load balance ~
         System.out.println(ip+":"+post);
 ​
         List<Order> myorders = new ArrayList<>();
         // Go through the collection to get uid consistent data stored in the collection returns...
         for (Order order : orders) {
             if(order.getUid() == uid) { myorders.add(order); }}returnmyorders; }}Copy the code

Launch the registry and two order microservice modules respectively

Change how the caller calls the Consumer…

Modify the caller user moduleRestTemplateLoad balancing is configured on the caller

Add @loadBalanced MyUserServer.java to an instance of the RestTemplate class

 @SpringBootApplication
 @EnableEurekaClient
 public class MyUserServer {
     public static void main(String[] args) {
          SpringApplication.run(MyUserServer.class, args);
     }
 ​
     @LoadBalanced           // Add the @loadBalanced annotation to the RestTemplate class and call services from the RestTemplate using ------ load balancing by default!
     @Bean
     // Instantiate RestTemplate to facilitate Service
     // Don't forget the @SpringBootApplication composite annotation can have @SpringBootConfiguration, which is also a Spring configuration class!
     public RestTemplate createRestTemplate(a) {
         return newRestTemplate(); }}Copy the code

To change theRestTemplateCall method of

Userservice.java ** Lines 17 to 18 load balancing calls ~**

 @Service
 @Slf4j                  // Load lo4g using...
 public class UserService {
 ​
     @Autowired
     private RestTemplate restTemplate;
     // Network communication via restTemplate returns.. Data from other remote modules (although now all local but emulated)
 ​
     @Autowired              // Implement dynamic call...
     private DiscoveryClient discoveryClient;
 ​
     public List<Order> currentUserOrder(Integer uid) {
         // Get the microserver module instance on the registry according to the service name;
         // Return a collection: it is possible that the service exists on multiple registries, 'load balancing ~' is therefore a collection;
         List<ServiceInstance> instances = discoveryClient.getInstances("order-server");
         ServiceInstance serviceInstance = instances.get(0); // This time there is only one...
         log.info("User service invokes order service");
 ​
 ​
         / / ribbon load balancing call -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
         // Because you now have two identical order-server microservices, but also use IP + port is fixed, through load balancing to complete the dynamic call ~ so directly use the module service name to express microservices!
         String myurl = "http://order-server/findOrderByUser/" + uid;
 ​
 ​
         // The service controller requests its parameter uid
         //String myurl = "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/findOrderByUser/" + uid;
         log.info(myurl);
         List<Order> list = restTemplate.getForObject(myurl, List.class);
         returnlist; }}Copy the code

test

Continuously refresh the user module to see the result of the order module being called…Distribution is called three times The default load balancing mode is:Round robin load balancer.. And take turns running one by one...

Conclusion:

  • Load balancing is configured in the Consumer caller to implement load balancing calls to modules with the same service name
  • Add the @loadBalanced annotation to the RestTemplate object of the caller to make the load-balancing call ~
  • Modify the Service layer, the call method is adoptedhttp://service name/request name /{parameters}/{parameters.. }formLoad balancing call;

Modify load balancing configurations

Of load balance of related configuration, the default prefix used polling: com.net flix. Loadbalancer.

  • BestAvailableRule Selects a server with the smallest concurrent request
  • AvailabilityFilteringRule filter out those because connection is marked as circuit tripped backend server, and filter out the high concurrency backend server (active connections over configuration threshold value)
  • WeightedResponseTimeRule assigns a weight based on response time, and the longer the response time, the smaller the weight and the less likely it is to be selected.
  • RetryRule Retry mechanism for the selected load balancing policy.
  • RoundRobinRule roundRobin select server (default)
  • RandomRule Selects a server at random
  • ZoneAvoidanceRule compound determines the performance of the zone where the Server is located and selects the Server for availability of the Server

.yml

How to configure load balancing calls under the caller module:Then configure the load balancing configuration of the order module under the user module

 order-server:   # order-server is the name of my service... Current my order module ~
   ribbon:
     NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # Modify load balancing policy random method service
Copy the code

Because it is the name of the service, there is no code warning:Copy between suggestions

Support retry microserver

When one of the load balancing modules goes down, the Ribbon detects it and tries to restart the service. Will not retry ~

Again, this is serving,The callerThe User User module declared by the module

Introduction of depend onpom.xml

 <dependency>
        <groupId>org.springframework.retry</groupId>
        <artifactId>spring-retry</artifactId>
 </dependency>
Copy the code

The configuration of yml

.yml

 order-server:
   ribbon:
     ConnectTimeout: 250                 Connection timeout
     ReadTimeout: 1000                   Data read timeout
     OkToRetryOnAllOperations: true      Whether to retry all operations
     MaxAutoRetries: 1                   Number of retries for the current instance
     MaxAutoRetriesNextServer: 1         Number of retries for switching instances
Copy the code

Feign service invocation

So far we have seen three microservice invocation methods for SpringBoot: Consumer — call — Provide:

  • RestTemplate hardcoded formal service invocation
  • DiscoveryClient implements dynamic calls…List the instances = discoveryClient. GetInstances (” module service name “);Returns a collection of modules based on the module service name ServiceInstance serviceInstance = instances.get(0); Get a module;String myURL = “http://serviceinstance.gethost () + “:” + serviceinstance.getPort () + “/ request name /” + parameter ~; serviceInstance.getHost()The service of the host serviceInstance.getPort() Service port number.
  • The RestTemplate declared by the @loadBalanced annotation makes service calls in the form of load balancing String myURL = "http://multiple providers provide module/request name /"

According to different work requirements, use different service invocation modes…. Here’s how Fegin does it

Introduction of Feign

Interface oriented development ~

Feign is a statement developed by NetflflixTemplated HTTP client

  • Inspired by Retrofifit,JAXRS-2.0, and Websocket.feign, it helps us make easy and elegant calls to HTTP apis
  • Feign supports a variety of annotations, such as Feign’s own annotations or JAX-RS annotations.
  • Feign has been enhanced by SpringCloudMade Feign support for SpringMVC annotations and integrationRibbonandEurekaTo make Feign easier to use.
  • In SpringCloud, using Feign is as simple as creating an interfaceAdd some annotations to the interface, and the code is done;In Eureka, a Consumer can also invoke the Provider's interface as a method invocation Very easy and very fast. Can effectively reduce the amount of code.

Build start

Create a user fegin module: common_userService_fegin

Implementation of fegin call method, callOrder module (provide)

addfeginDependent component: POM.xml

pom.xml

 
      
 <project xmlns="http://maven.apache.org/POM/4.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <parent>
         <artifactId>SpringCloudBJ</artifactId>
         <groupId>org.example</groupId>
         <version>1.0 the SNAPSHOT</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 ​
     <artifactId>common_userService_fegin</artifactId>
 ​
     <dependencies>
         <! Maven subproject API entity -->
         <dependency>
             <artifactId>common-api</artifactId>
             <groupId>com.zb</groupId>
             <version>1.0 the SNAPSHOT</version>
         </dependency>
         <! -- Eureka dependent ~ -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
         </dependency>
 ​
         <! -- Fegin depends!! -->
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-openfeign</artifactId>
         </dependency>
     </dependencies>
 </project>
Copy the code

addfeginThe mot configuration

Port service name Eureka Configuration center Management… In order to prevent errors on the copy, there are already a lot of duplicate things…. application.yml

 server:
   port: 6004                  Change port 6004
 spring:
   application:
     name: User - server - fegin   # set the name of the micro service, the following registration/call service is based on this;
 eureka:
   client:
     service-url:
       defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/
   instance:
     prefer-ip-address: true
     instance-id: ${spring.cloud.client.ip-address}:${server.port}   # display IP number on Eureka..
Copy the code
  • The default Tomcat port for SpringBoot is 8080
  • Because ports are unique, SpringCloud is also a microservice architecture, one per service, which requires frequent port changes
  • If a service doesn't work. Check the port problem first ~

Create the main program class:

Enable Spring Cloud Feign support with the @enableFeignClients annotation myUserFeginServer.java


 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 import org.springframework.cloud.openfeign.EnableFeignClients;
 ​
 @SpringBootApplication
 @EnableEurekaClient
 @EnableFeignClients                 // Start classes to add Feign support
 public class MyUserFeginServer {
     public static void main(String[] args) { SpringApplication.run(MyUserFeginServer.class, args); }}Copy the code

Com.wsm. client interface package:

Based on interface oriented programming…

Create an interface that is the core interface for invoking microservices in Feign

  • Declaration on interface@feignClient (" Specify the microservice provider service name to invoke ")
  • The class then declares the same method to be invoked in the provider service, including parameters.Fegin automatically makes the underlying matching mapping call ~

OrderFeginClient.Java

 import com.zb.entity.Order;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import java.util.List;
 ​
 // @feignClient specifies the name of the microservice to call
 @FeignClient("order-server")
 public interface OrderFeginClient {
 ​
     // Call the request path, note that this should be as close as possible to the implementation method of the provider, including parameters, parameter types!!
     @GetMapping("/findOrderByUser/{uid}")
     public List<Order> findOrderByUser(@PathVariable("uid") Integer uid);
 }
Copy the code

After that, the normal implementation of service and Controller…

UserService.Java

 import com.wsm.client.OrderFeginClient;
 import com.zb.entity.Order;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import java.util.List;
 ​
 @Service
 public class UserService {
 ​
     @Autowired
     private OrderFeginClient ofc;           // Get the interface object. @feginclient will automatically inject the class into Spring
 ​
     public List<Order> currentUserOrder(Integer uid){
         return ofc.findOrderByUser(uid);    // Call the interface's methods,fegin's bottom layer will call by default, for the service's methods...}}Copy the code

Usercontroller.java will not be explained in detail…

 @RestController
 public class UserController {
 ​
     @Autowired
     private UserService us;
 ​
     @GetMapping("/showUserOrder")
     public List<Order> showUserOrder(Integer uid){
         returnus.currentUserOrder(uid); }}Copy the code

Testing:

Ok, implement the call!

Fegin Service Invocation summary:

  • Import depends on POM.xml
  • Fegin’s.YML doesn’t have any required configuration…
  • When creating the main program class, add@EnableFeignClientsStart classes to add Feign support
  • Fegin is interface oriented programming:Create an interface class:Class declaration @feignClient (" specify provider module name ")And:Interface methods, note ⚠️ : be consistent with the Provider's controller!! annotations parameter Parameter type!

Feign Load balancing

Feign already has Ribbon dependencies and auto-configuration integrated into Feign itself

  • So we don’t need to import additional dependencies or register the RestTemplate object. Automatic load balancing ~
  • This is really cool. It’s automaticLoad balancing ~Default theory follows ~
  • In addition, we can configure the Ribbon directly by using Ribbon. Xx to enable global configuration. You can also configure the specified service using the service name.ribbon. Xx

Feign’s.yml setting

For slow computers, Fegin calls 2 seconds by default. If time out, the request will not be executed… To solve this problem prolong the request response time:

Yml The default timeout period is 10 seconds

 feign:
   httpclient:
     connection-timeout: 10000
   client:
     config:
       default: # feignClients specifies a global timeout for all clients
         connectTimeout: 10000
         readTimeout: 10000
         loggerLevel: basic
Copy the code

For Fegin interfaces, @FeignClient(” specify the provider module name “) is required to specify the calling module if the same @Feginclient (” multiple interfaces declare the same module name “) module is used on multiple interfaces. An error:

.yml requires that the spring.main. allow-bean-meant-overriding property be set to true

 spring:
   main:
     allow-bean-definition-overriding: true
Copy the code

Can avoid this problem!!