SpringCloud learning notes (crazy God video notes)

SpringCloud (V)

6. Ribbon: load balancing (client based)

6.1 load balancing and Ribbon

  1. What is Ribbon?

    • Spring Cloud Ribbon is a set of client-side load balancing tools based on Netflix Ribbon.
    • In short, Ribbon is an open source project released by Netflix. Its main function is to provide software load balancing algorithms for clients and connect Netflix's middle tier services together. The Ribbon client component provides a series of complete configuration items, such as connection timeout, Retry, etc. To put it simply, list all the machines behind the LoadBalancer (LB: load balancer for short) in the configuration file. The Ribbon will automatically help you connect these machines based on certain rules (such as simple polling, random connection, etc.). We can also easily use the Ribbon to implement a custom load balancing algorithm!
  2. What can Ribbon do?

    • LB, load balancer, is an application often used in microservices or distributed clusters.

    • Load balancing simply means spreading the user's requests to multiple servers, so as to achieve the HA (high use) of the system.

    • Common load balancing software include Nginx, Lvs and so on.

    • Dubbo and spring cloud Zhongjun provide us with load balancing, and the load balancing algorithm of spring cloud can be customized.

    • Simple classification of load balancing:

      • Centralized LB

        That is, an independent LB device is used between the service provider and the consumer, such as Nginx: reverse proxy server, which is responsible for forwarding the access request to the service provider through some policy!

      • Program LB

        • Integrate LB logic into the consumer. The consumer knows which addresses are available from the service registry, and then selects a suitable server from these addresses.
        • Ribbon belongs to in-process LB, which is just a class library integrated into the consumer process, through which the consumer obtains the address of the service provider.

6.2 integrated Ribbon

  • springcloud-consumer-dept-80 to POM Add Ribbon and Eureka dependencies to XML

        <!-- Ribbon -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    
        <!--eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    
  • In application Configure Eureka in yaml file

    # Eureka configuration
    eureka:
      client:
        register-with-eureka: false # Do not register yourself with Eureka
        service-url: # Visit one of the three registries at random
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
  • Add the @ EnableEurekaClient annotation to the main startup class to open Eureka

    @SpringBootApplication
    @EnableEurekaClient //Open Eureka client
    public class DeptConsumer_80 {
        public static void main(String[] args) {
            SpringApplication.run(DeptConsumer_80.class,args);
        }
    }
    
  • Custom Spring configuration class: configbean Java configuration load balancing to implement RestTemplate

    @Configuration
    public class ConfigBean {   //Cofiguration -- spring applicationContext.xml
    
        @LoadBalanced //Configure load balancing to implement RestTemplate
        @Bean
        public RestTemplate getRestTemplate() {
            return new RestTemplate();
        }   
    }
    
  • Modify controller: deptconsumercontroller java

    //Ribbon: the address here should be a variable, accessed through the service name
    //private static final String REST_URL_PREFIX = "http://localhost:8001";
    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    

6.3 load balancing using Ribbon

flow chart:

  1. Create a new cloud for two service providers: springcloud-provider-dept-8003 and springcloud-provider-dept-8002

  2. Refer to springcloud-provider-dept-8001 to add POM for the other two clouds in turn XML dependency, mybatis and application. XML under resources Yaml configures Java code.

  3. Start all servers for testing (determine the number of services to be started according to their own computer configuration), and access http://eureka7001.com:7002/ View results

    Test access http://localhost/consumer/dept/list At this time, the service provider 8003 is accessed randomly

    Visit again http://localhost/consumer/dept/list At this time, the random service provider 8001

    Each visit above http://localhost/consumer/dept/list Random access to a service provider in the cluster is called polling. The polling algorithm can be customized in spring cloud.

  4. How to switch or customize rules?

    Configure in the ConfigBean under the springcloud-provider-dept-80 module and switch to different rules

    @Configuration
    public class ConfigBean {//@Configuration -- spring  applicationContext.xml
    
        /**
         * IRule:
         * RoundRobinRule round-robin policy 
         * RandomRule Random strategy
         * AvailabilityFilteringRule :  It will filter out, trip, access the failed service ~, and poll the rest~
         * RetryRule :  The service ~ will be obtained according to the polling first. If the service acquisition fails, it will be performed within the specified time and try again
         */
        @Bean
        public IRule myRule() {
            return new RandomRule();//Use random strategy
            //return new RoundRobinRule();// Use polling policy
            //return new AvailabilityFilteringRule();// Use polling policy
            //return new RetryRule();// Use polling policy
        }
    }
    

    You can also customize rules and customize a configuration class myRule under myRule package Java, note: this package should not be at the same level as the package where the main startup class is located, but at the same level as the package where the startup class is located:

    MyRule.java

    @Configuration
    public class MyRule {
        @Bean
        public IRule myRule(){
            return new MyRandomRule();//The default is to poll RandomRule, which is now customized as its own
        }
    }
    

    The main startup class enables load balancing and specifies a custom MyRule configuration class

    //After the integration of Ribbon and Eureka, the client can call directly without caring about the IP address and port number
    @SpringBootApplication
    @EnableEurekaClient
    //The customized Ribbon class can be loaded when the micro service is started (the customized rules will override the original default rules)
    @RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)//Turn on load balancing and specify custom rules
    public class DeptConsumer_80 {
        public static void main(String[] args) {
            SpringApplication.run(DeptConsumer_80.class, args);
        }
    }
    

    Custom rules (here we refer to the default rule code in the Ribbon and change it slightly): myrandomrule java

    public class MyRandomRule extends AbstractLoadBalancerRule {
    
        /**
         * If each service is accessed 5 times, the next service will be replaced (a total of 3 services)
         * <p>
         * total=0,Default = 0. If = 5, it points to the next service node
         * index=0,Default = 0, if total=5,index+1
         */
        private int total = 0;//Number of calls
        private int currentIndex = 0;//Who is currently providing services
    
        //@edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE")
        public Server choose(ILoadBalancer lb, Object key) {
            if (lb == null) {
                return null;
            }
            Server server = null;
    
            while (server == null) {
                if (Thread.interrupted()) {
                    return null;
                }
                List<Server> upList = lb.getReachableServers();//Access to currently alive services
                List<Server> allList = lb.getAllServers();//Get all services
    
                int serverCount = allList.size();
                if (serverCount == 0) {
                    /*
                     * No servers. End regardless of pass, because subsequent passes
                     * only get more restrictive.
                     */
                    return null;
                }
    
                //int index = chooseRandomInt(serverCount);// Generating interval random number
                //server = upList.get(index);// Randomly get one from a or living service
    
                //=====================Custom code=========================
    
                if (total < 5) {
                    server = upList.get(currentIndex);
                    total++;
                } else {
                    total = 0;
                    currentIndex++;
                    if (currentIndex > upList.size()) {
                        currentIndex = 0;
                    }
                    server = upList.get(currentIndex);//Obtain the specified service from the living service for operation
                }
                
                //======================================================
                
                if (server == null) {
                    /*
                     * The only time this should happen is if the server list were
                     * somehow trimmed. This is a transient condition. Retry after
                     * yielding.
                     */
                    Thread.yield();
                    continue;
                }
                if (server.isAlive()) {
                    return (server);
                }
                // Shouldn't actually happen.. but must be transient or a bug.
                server = null;
                Thread.yield();
            }
            return server;
        }
    
        protected int chooseRandomInt(int serverCount) {
            return ThreadLocalRandom.current().nextInt(serverCount);
        }
    
        @Override
        public Server choose(Object key) {
            return choose(getLoadBalancer(), key);
        }
    
        @Override
        public void initWithNiwsConfig(IClientConfig clientConfig) {
            // TODO Auto-generated method stub
        }
    }
    

7. Feign: load balancing (based on the server)

7.1 Feign introduction

Feign is a declarative Web Service client, which makes it easy to call between services, similar to the controller calling service. Spring cloud integrates Ribbon and Eureka, and can use feign to provide a load balanced http client.

Just create an interface and add annotations~

Feign, mainly the community version, is used to interface oriented programming. This is the norm for many developers. There are two methods to call microservice access:

  1. Microservice name [ribbon]
  2. Interface and notes [feign]
  • What can Feign do?
    • Feign aims to make it easier to write Java Http clients.
    • Previously, when using Ribbon + RestTemplate, RestTemplate is used to encapsulate Http requests, forming a set of templated calling methods. However, in the actual development, because there may be more than one invocation of service dependencies, and often one interface will be invoked in multiple places, a client class is usually encapsulated for each micro service to wrap the invocation of these dependent services. Therefore, Feign has made further encapsulation on this basis to help us define and implement the definition of dependent service interface. Under the implementation of Feign, we only need to create an interface and configure it in the way of annotation (similar to the Mapper annotation on Dao interface in the past, now it is a micro service interface with a Feign annotation on = = above), The interface binding to the service provider can be completed, which simplifies the development of automatically encapsulating the service call client when using the Spring Cloud Ribbon.
  • Feign integrates Ribbon by default
    • The Ribbon is used to maintain the service list information of microservicecloud dept, and the load balancing of the client is realized through polling. Different from the Ribbon, Feign only needs to define the service binding interface and realize the service invocation in a declarative way.

7.2 use steps of feign

  1. Create the springcloud consumer fdept feign module

    Copy the POM under the springcloud-consumer-dept-80 module XML, resource, and java code to the springcloud consumer feign module, and add feign dependencies.

    <!--Feign Dependence of-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    

    Realized through the Ribbon: the original controller: deptconsumercontroller java

    @RestController
    public class DeptConsumerController {
    
        /**
         * Understanding: consumers should not have a service layer~
         * RestTemplate .... For us to call directly! Register in Spring
         * (Address: url, entity: map, class < T > responsetype)
         * <p>
         * Provide a variety of convenient methods to access remote http services and a simple Restful service template~
         */
        @Autowired
        private RestTemplate restTemplate;
    
        /**
         * Service provider address prefix
         * <p>
         * Ribbon:The address here should be a variable accessed by the service name
         */
    //    private static final String REST_URL_PREFIX = "http://localhost:8001";
        private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    
        /**
         * Add department information to the consumer
         * @param dept
         * @return
         */
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept) {
            // Postforobject (service provider address (Interface), parameter entity, return type class)
            return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
        }
    
        /**
         * The consumer queries the Department information according to the id
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id) {
            // Getforobject (service provider address (Interface), return type class)
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
        }
    
        /**
         * Consumer query department information list
         * @return
         */
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list() {
            return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
        }
    }
    

    Realized through Feign: controller after transformation: deptconsumercontroller java

    @RestController
    public class DeptConsumerController {
    
        @Autowired
        private DeptClientService deptClientService;
    
        /**
         * Add department information to the consumer
         * @param dept
         * @return
         */
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept) {
            return deptClientService.addDept(dept);
        }
    
        /**
         * The consumer queries the Department information according to the id
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id) {
           return deptClientService.queryById(id);
        }
    
        /**
         * Consumer query department information list
         * @return
         */
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list() {
            return deptClientService.queryAll();
        }
    }
    

    Comparing Feign with Ribbon, the former shows the characteristics of interface oriented programming, and the code looks more refreshing. Moreover, Feign's calling method is more in line with our previous programming habit of calling the Service layer by the Controller layer when we were working on SSM or SpringBoot projects!

    Main configuration class:

    @SpringBootApplication
    @EnableEurekaClient
    // feign client annotation, and specify the package to be scanned and the configuration interface DeptClientService
    @EnableFeignClients(basePackages = {"com.kuang.springcloud"})
    // Don't add this comment, otherwise it will not appear
    //@ComponentScan("com.kuang.springcloud")
    public class FeignDeptConsumer_80 {
        public static void main(String[] args) {
            SpringApplication.run(FeignDeptConsumer_80.class, args);
        }
    }
    
  2. Transforming the spring cloud API module

    pom. Adding feign dependency to XML

    <!--Feign Dependence of-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    

    Create a new service package and a new deptclientservice Java interface,

    // @FeignClient: Micro service client annotation, value: specify the name of the micro service, so that the Feign client can directly find the corresponding micro service
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
    public interface DeptClientService {
    
        @GetMapping("/dept/get/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public Dept queryAll();
    
        @GetMapping("/dept/add")
        public Dept addDept(Dept dept);
    }
    

7.3 how to choose feign and Ribbon?

It depends on personal habits. If you like REST style, use Ribbon; If you like the community version of the interface oriented style, use Feign.

Feign essentially implements Ribbon, but the latter is in the debugging method, in order to meet the interface calling habits of some developers!

Now let's close the service consumer springcloud-consumer-dept-80 and replace it with springcloud-consumer-dept-feign (port number is still 80): (it can still be accessed normally, that is, the calling method is changed compared with the Ribbon)

8. Hystrix: Service fuse

Problems faced by distributed systems

Applications in complex distributed architecture have dozens of dependencies, and each dependency will inevitably fail at some time!

8.1 service avalanche

When calling between multiple microservices, suppose that microservice B and microservice C are called for service A, and microservice B and microservice C call other microservices, which is the so-called "fan out". If the call response time of A microservice on the fan out link is too long or unavailable, the call to microservice A will occupy more and more system resources, Then cause system collapse, the so-called "avalanche effect".

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-1C2Y8eWZ-1620106023602)(D: \ desktop \ 001\idea note \ idea picture \ avalanche effect. png)]

For high traffic applications, a single back-end dependency may cause all resources on all servers to saturate in tens of seconds. Worse than failure, these applications may also lead to increased delays between services, tight backup queues, threads and other system resources, resulting in more cascading failures of the whole system. All these indicate the need to isolate and manage failures and delays to achieve the failure of a single dependency without affecting the operation of the whole application or system.

We need to get rid of the car!

8.2 what is Hystrix?

Hystrix is an open source library used to deal with the delay and fault tolerance of distributed systems. In distributed systems, many dependencies inevitably fail to call, such as timeout, exception, etc. hystrix can ensure that when a dependency fails, it will not lead to the service failure of the whole system, avoid cascading failures, and improve the elasticity of distributed systems.

"Circuit breaker" itself is a switching device. When a service unit fails, it returns a service expected and treatable alternative response (FallBack) to the caller through the fault monitoring of the circuit breaker (similar to fusing a fuse), rather than waiting for a long time or throwing an exception that cannot be handled by the calling method, This can ensure that the thread of the service caller will not be occupied unnecessarily for a long time, so as to avoid the spread and even avalanche of faults in the distributed system.

[the external chain image transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the image and upload it directly (img-GWXvY3gV-1620106023603)(D: \ desktop \ 001\idea note \ idea image \ processing avalanche effect. png)]

8.3 what can hystrix do?

  • service degradation
  • Service fuse
  • Service current limiting
  • Near real-time monitoring
  • ...

When everything is normal, the request flow can be as follows:

When there is a potential blocking service in many back-end systems, it can block the whole user request:

With the increase of high-capacity traffic, the potential of a single back-end dependency will cause all resources on all servers to saturate in a few seconds.

Every point in the application that may cause network requests through the network or client library is a potential source of failure. Worse than failure, these applications can also lead to increased latency between services, backing up queues, threads, and other system resources, resulting in more cascading failures across systems.

When you wrap each base dependency with Hystrix, the architecture shown in the above diagram changes similar to the following diagram. Each dependency is isolated from each other, limited to the resources it can fill when the delay occurs, and included in the fallback logic, which determines the response to any type of failure in the dependency:

Official website information: https://github.com/Netflix/Hystrix/wiki

8.4 service fuse

  • What is service?

    Circuit breaker mechanism is a microservice link protection mechanism to win avalanche effect.

    When a microservice of the fan out link is unavailable or the response time is too long, the service will be degraded, which will fuse the call of the microservice of the node and quickly return the corresponding error information. After detecting that the microservice call response of the node is normal, restore the link. In the spring cloud framework, the fuse mechanism is implemented through hystrix. Hystrix will monitor the calls between microservices. When the failed calls reach a certain threshold, the default is 20 calls in 5 seconds, and the fuse mechanism will be started. The annotation of the fuse mechanism is: @ HystrixCommand.

    The service can solve the following problems:

    • When the dependent object is unstable, it can achieve the purpose of rapid failure;
    • After a fast failure, it can dynamically test whether the dependent object is restored according to a certain algorithm.
  • Introductory case

    Create a new springcloud-provider-dept-hystrix-8001 module and copy the POM in springcloud-provider-dept-8001 XML, resources, and java code to initialize and adjust.

    Import hystrix dependency

    <!--Import Hystrix rely on-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    

    Adjust yaml profile

    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    
    #spring configuration
    spring:
      application:
        name: springcloud-provider-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: org.gjt.mm.mysql.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
        username: root
        password: 123456
    
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      instance: 
        instance-id: springcloud-provider-dept-hystrix-8001 # Modify the default description information on eureka!
    
    
    #info configuration
    info:
      app.name: kuangshen-springcloud
      company.name: blog.kuangstudy.com
    

    perfer-ip-address: false

    perfer-ip-address: true

    Modify controller

    /**
     * @Auther: csp1999
     * @Date: 2020/05/17/22:06
     * @Description: Provide Restful services
     */
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptService deptService;
    
        /**
         * Query department information according to id
         * If there is an exception in the query based on id, follow the alternative code of hystrixGet
         * @param id
         * @return
         */
        @HystrixCommand(fallbackMethod = "hystrixGet")
        @RequestMapping("/dept/get/{id}")//Query by id
        public Dept get(@PathVariable("id") Long id){
            Dept dept = deptService.queryById(id);
            if (dept==null){
                throw new RuntimeException("this id=>"+id+",The user does not exist or the information cannot be found~");
            }
            return dept;
        }
    
        /**
         * Query alternatives according to id (fuse)
         * @param id
         * @return
         */ 
        public Dept hystrixGet(@PathVariable("id") Long id){
            return new Dept().setDeptno(id)
                    .setDname("this id=>"+id+",No corresponding information,null---@Hystrix~")
                    .setDb_source("stay MySQL This database does not exist in");
        }
    }
    

    Add the support annotation @ enablercircuitbreaker for the main startup class

    @SpringBootApplication
    @EnableEurekaClient // The startup class of EnableEurekaClient client automatically registers the service with the registry after the service is started
    @EnableDiscoveryClient // Service discovery~
    @EnableCircuitBreaker // Add supporting comments for fuse
    public class HystrixDeptProvider_8001 {
        public static void main(String[] args) {
            SpringApplication.run(HystrixDeptProvider_8001.class,args);
        }
    }
    

    Test:

    After using fuse, when accessing a nonexistent id, the data displayed on the foreground page is as follows:

    Instead of using the fused springcloud-provider-dept-8001 module to access the same address, the following conditions will occur:

    Therefore, it is necessary to use fuse in order to avoid errors in the whole application or web page due to exceptions or errors in the background of a micro service.

8.5 service degradation

What is service degradation?

Service degradation means that when the pressure on the server increases sharply, some services and pages are not handled strategically or handled in a simple way according to the actual business conditions and traffic, so as to release the server resources to ensure the normal or efficient operation of the core business. To put it bluntly, it is to give system resources to services with high priority as much as possible.

Resources are limited and requests are unlimited. If the service is not degraded during the peak period of concurrency, on the one hand, it will certainly affect the performance of the overall service. If it is serious, it may lead to downtime and unavailability of some important services. Therefore, in the peak period, in order to ensure the availability of core function services, some services must be degraded. For example, in the double 11 event, the services unrelated to the transaction are all downgraded, such as viewing ant forest, viewing historical orders, etc.

The method of degradation can be based on the business, and the service can be delayed. For example, the delay will add points to the user, which will only be put into a cache and executed after the service is stable; Or close the service within the granularity, such as the recommendation of relevant articles.

[the external chain picture transfer fails. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (IMG mxsfnxxp-1620106023612) (D: \ desktop \ 001\idea notes \ idea pictures \ service degradation. png)]

It can be seen from the above figure that when the traffic of service A increases sharply and the traffic of B and C is less at A certain time, in order to alleviate the pressure of service A, B and C need to temporarily close some service functions to undertake some services of A, so as to share the pressure for A, which is called service degradation.

Issues to be considered for service degradation:

  1. Which services are core services and which are non core services
  2. Which services can support degradation, which services cannot support degradation, and what is the degradation strategy
  3. In addition to service degradation, is there a more complex business release scenario and what is the strategy?

Automatic degradation classification

  1. Timeout degradation: it mainly configures the timeout time and timeout retry times and mechanism, and uses asynchronous mechanism to detect the reply
  2. Degradation of failure times: it mainly refers to some unstable APIs. When the number of failed calls reaches a certain threshold, it will be degraded automatically. Similarly, asynchronous mechanism should be used to detect the reply
  3. Failure degradation: for example, if the remote service to be called hangs (network failure, DNS failure, http service returns an error status code, rpc service throws an exception), it can be directly degraded. The processing schemes after degradation include: default value (for example, if the inventory service is suspended, it will return to the default stock), bottom data (for example, if the advertisement is suspended, it will return some static pages prepared in advance), cache (some data previously temporarily stored)
  4. Current limit downgrade: when second killing or snapping up some restricted goods, the system may crash due to too much traffic. At this time, the current limit will be used to limit the traffic. When the current limit threshold is reached, the subsequent requests will be downgraded; The degraded processing scheme can make: queuing page (divert the user to the queuing page and try again later), no goods (directly inform the user that there is no goods), error page (if the activity is too hot, try again later).

Introductory case

Create a new degraded configuration class deptclientservicefailbackfactory. In the service package under the springcloud API module java

@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory {

    @Override
    public DeptClientService create(Throwable cause) {
        return new DeptClientService() {
            @Override
            public Dept queryById(Long id) {
                return new Dept()
                        .setDeptno(id)
                        .setDname("id=>" + id + "There is no corresponding information. The client provides degraded information. The service has been shut down now")
                        .setDb_source("no data~");
            }
            @Override
            public List<Dept> queryAll() {
                return null;
            }

            @Override
            public Boolean addDept(Dept dept) {
                return false;
            }
        };
    }
}

Specify the degraded configuration class DeptClientServiceFallBackFactory in DeptClientService

@Component //Register in spring container
//@FeignClient: Micro service client annotation, value: specify the name of the micro service, so that the Feign client can directly find the corresponding micro service
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallBackFactory.class)//fallbackFactory specifies the degraded configuration class
public interface DeptClientService {

    @GetMapping("/dept/get/{id}")
    public Dept queryById(@PathVariable("id") Long id);

    @GetMapping("/dept/list")
    public List<Dept> queryAll();

    @GetMapping("/dept/add")
    public Boolean addDept(Dept dept);
}

Enable demotion in the springcloud consumer dept feign module

server:
  port: 80

# Eureka configuration
eureka:
  client:
    register-with-eureka: false # Do not register yourself with Eureka
    service-url: # Visit one of the three registries at random
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

# Enable degraded feign hystrix
feign:
  hystrix:
    enabled: true

8.6 difference between service fusing and degradation

  • Service fusing - > server: a service timeout or abnormality causes fusing, which is similar to fuse (Self Fusing)
  • Service degradation - > client: considering the overall website request load, when a service is blown or closed, the service will no longer be called. At this time, on the client, we can prepare a FallBackFactory and return a default value (default value). It will lead to the decline of the overall service, but at least it can be used, which is better than hanging up directly.
  • The causes of triggering are different. Service fusing is generally caused by a service (downstream service) failure, and service degradation is generally considered from the overall load; The levels of management objectives are different. Fusing is actually a framework level process, and each micro service needs to be (without hierarchy), while degradation generally needs to have hierarchy for the business (for example, degradation generally starts from the most peripheral services)
  • The implementation methods are different. Service degradation is code intrusive (completed by the controller and / or automatic degradation), and fusing is generally called self fusing.

Fusing, degradation, current limiting:

Flow restriction: limit concurrent request access. If the threshold is exceeded, it will be rejected;

Degradation: services are prioritized, sacrificing non core services (unavailable) to ensure the stability of core services; Considering the overall load;

Fusing: the dependent downstream service failure triggers fusing to avoid causing the system crash, and the system automatically executes and recovers

8.7 Dashboard flow monitoring

Create a new springcloud consumer hystrix dashboard module

Add dependency

<!--Hystrix rely on-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--dashboard rely on-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--Ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--Eureka-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--Entity class+web-->
<dependency>
    <groupId>com.haust</groupId>
    <artifactId>springcloud-api</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Hot deployment-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

Main startup class

@SpringBootApplication
// Open Dashboard
@EnableHystrixDashboard
public class DeptConsumerDashboard_9001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumerDashboard_9001.class,args);
    }
}

Add the following code to the main startup class under the springcloud provider Dept hystrix-8001 module and add monitoring (fixed code)

@SpringBootApplication
@EnableEurekaClient //The startup class of EnableEurekaClient client automatically registers the service with the registry after the service is started
public class DeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8001.class,args);
    }

    //Add a Servlet
    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        //Visiting this page is the monitoring page
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
       
        return registrationBean;
    }
}

visit: http://localhost:9001/hystrix

Enter the monitoring page:

The effect is as follows:

Keywords: Java Spring Distribution

Added by cnl83 on Fri, 18 Feb 2022 14:07:16 +0200