SpringCloud quick start (based on crazy explanation)

Keywords: Java Spring Cloud

Spring cloud learning notes

1, Study Preface

1.1 learning premise

  • Proficient in using SpringBoot microservice rapid development framework
  • Learned about Dubbo + Zookeeper distributed Foundation
  • The computer configuration memory shall not be less than 8G(16G and above are recommended)

1.2 article outline

Five components of Spring Cloud

  • Service registration and discovery - Netfilx Eureka
  • Load balancing:
    • Client load balancing - Netfilx Ribbon
    • Server load balancing - Feign (it also depends on the Ribbon, but changes the calling method RestTemplate to the Service interface)
  • Paragraph Manager - Netflix Hystrix
  • Service gateway - NetFlix Zuul
  • Distributed configuration - Spring Cloud Config

1.3 common interview questions

1.1 what is micro service?

1.2 how do microservices communicate independently?

1.3 what are the differences between springcloud and Dubbo?

1.4 SpringBoot and SpringCloud, please talk about your understanding of them

1.5 what is service fusing? What is service degradation?

1.6 what are the advantages and disadvantages of microservices? Tell me about the pitfalls you encountered in project development

1.7 what are the microservice technology stacks you know? List one or two

1.8 Eureka and Zookeeper can provide service registration and discovery. Please tell us the difference between them

...

2, Overview of microservices

2.1. What is micro service?

concept

Microservice architecture is a popular architecture idea in recent years. It is difficult to sum up its concept.

What exactly is a micro service? We hereby quote Martin Fowler, chief scientist of ThoughtWorks, who put forward a paragraph in 2014:

Original text: https://martinfowler.com/articles/microservices.html

Sinicization: https://www.cnblogs.com/liuning8023/p/4493156.html

At present, there is no unified and standard definition of microservices in the industry.
But generally speaking, microservice architecture is an architecture mode, or an architecture style. Its length divides a single application into a group of small services. Each service runs in its own independent process. Services coordinate and configure with each other to provide final value for users. Services communicate with each other through lightweight communication mechanism (HTTP), Each service is built around a specific business and can be independently deployed to the production environment. In addition, a unified and centralized service management mechanism should be avoided as far as possible. For a specific service, an appropriate language and tool (Maven) should be selected to build it according to the business context, There can be a very lightweight centralized management to coordinate these services, services can be written in different languages, or different data stores.

From the perspective of Technology:

  • The core of microservicing is to split the traditional one-stop application into one service according to the business and completely decouple it. Each microservice provides a service with a single business function. One service does one thing. From a technical point of view, it is a small and independent processing process. The concept of similar process can be started or destroyed independently, Have their own independent database.

2.2. Microservices and microservice architecture

Microservices

It emphasizes the size of services. It focuses on a certain point. It is a service application that specifically solves a problem / provides landing corresponding services. In a narrow sense, it can be regarded as micro service projects in the IDEA or Moudel. The IDEA tool uses independent small Moudel developed by Maven. It specifically uses a small module developed by SpringBoot. Professional things are done by professional modules, and each module does one thing. The emphasis is on individuals, and each individual completes a specific task or function.

Microservice architecture

A new architecture form was proposed by Martin Fowler in 2014.

Microservice architecture is an architecture model. Its body length divides a single application into a group of small services. Services coordinate and cooperate with each other to provide final value for users. Each service runs in its own independent process. Lightweight communication mechanism * * (such as HTTP) is used between services to cooperate with each other. Each service is built around specific business and can be independently deployed to the production environment. In addition, unified and centralized service management mechanism should be avoided as far as possible. For a specific service, Appropriate languages and tools (such as Maven) * * should be selected according to the business context to build them.

2.3 advantages and disadvantages of microservices

advantage

  • The principle of single responsibility;

  • Each service is cohesive and small enough, and the code is easy to understand, so that it can focus on a specified business function or business requirement;

  • Development is simple and efficient. A service may be dedicated to only one thing;

  • Microservices can be developed independently by a small team, which only needs 2-5 developers;

  • Microservices are loosely coupled and functionally meaningful services, which are independent in the development stage or deployment stage;

  • Microservices can be developed in different languages;

  • It is easy to integrate with third parties. Microservices allow easy and flexible integration and automatic deployment through continuous integration tools, such as jenkins, Hudson and bamboo;

  • Microservices are easy to be understood, modified and maintained by a developer, so that small teams can pay more attention to their work results and reflect their value without cooperation;

  • Microservices allow the use and integration of the latest technologies;

  • Microservices are just business logic code and will not be mixed with HTML, CSS or other interfaces;

  • Each microservice has its own storage capacity. It can have its own database or a unified database;

shortcoming

  • Developers have to deal with the complexity of distributed systems;

  • Multi service operation and maintenance is difficult. With the increase of services, the pressure of operation and maintenance is also increasing;

  • System deployment dependency;

  • Communication cost between services;

  • Data consistency;

  • System integration test problems;

  • Performance and monitoring issues;

2.4 what are the microservice technology stacks?

Microservice Technology EntryLanding technology
Service developmentSpringBoot, Spring, Spring MVC, etc
Service configuration and managementArchaius of Netfix, Diamond of Ali, etc
Service registration and discoveryEureka, Consul, Zookeeper, etc
Service callRest,PRC,gRPC
Service fuseHystrix, Envoy, etc
load balancing Ribbon, Nginx, etc
Service interface call (simplified tool for client to call service)Fegin et al
Message queueKafka, RabbitMQ, ActiveMQ, etc
Service configuration center managementSpringCloudConfig, Chef, etc
Service routing (API gateway)Zuul et al
Service monitoringZabbix, Nagios, Metrics, specifier, etc
Full link trackingZipkin, Brave, Dapper, etc
Data flow operation development packageSpring cloud stream (encapsulating sending and receiving messages with Redis, Rabbit, Kafka, etc.)
Time message stackSpringCloud Bus
Service deploymentDocker, OpenStack, Kubernetes, etc

2.5 why choose Spring Cloud as the micro service architecture

  1. Selection basis

    • Overall solution and framework maturity
    • Community heat
    • Maintainability
    • learning curve
  2. What are the current microservice architectures used by major IT companies?

    • Ali: dubbo+HFS

    • JD: JFS

    • Sina: Motan

    • Dangdang: DubboX

      ...

  3. Comparison of micro Service Frameworks

    Function point / service frameworkNetflix/SpringCloudMotangRPCThri tDubbo/DubboX
    Functional positioningComplete microservice frameworkRPC framework, but it integrates ZK or consult to realize basic service registration and discovery in cluster environmentRPC frameworkRPC frameworkService Framework
    Support RestYes, the Ribbon supports a variety of pluggable serial number choicesnononono
    Support RPCnoYes (Hession2)yesyesyes
    Support multiple languagesYes (Rest form)noyesyesno
    load balancing Yes (server zuul + client Ribbon), zuul service, dynamic routing, cloud load balancing, Eureka (for middle tier servers)Yes (client)nonoYes (client)
    Configure servicesNetfix Archaius, Spring Cloud Config Server, centralized configurationYes (provided by Zookeeper)nonono
    Service call chain monitoringYes (zuul). Zuul provides edge services and API gatewaysnononono
    High availability / fault toleranceYes (server side Hystrix + client Ribbon)Yes (client)nonoYes (client)
    Typical application casesNetflixSinaGoogleFacebook
    Community activityhighcommonlyhighcommonlyMaintenance resumed after 2017, after 5 years of interruption
    Learning difficultysecondarylowhighhighlow
    Document richnesshighcommonlycommonlycommonlyhigh
    otherSpring Cloud Bus brings more management endpoints to our applicationsSupport downgradeNetflix is developing and integrating gRPC internallyIDL definitionThere are many companies practicing

3, Spring cloud getting started overview

3.1 what is spring cloud?

Spring official website: https://spring.io/

3.2 relationship between SpringBoot and SpringCloud

  • SpringBoot focuses on KAISU's convenient development of individual micro services;

  • SpringCloud is a microservice coordination and management framework that focuses on the overall situation. It integrates and manages individual microservices developed by SpringBoot, and provides integrated services among microservices: configuration management, service discovery, circuit breaker, routing, proxy, event stack, global lock, decision-making campaign, distributed session, etc;

  • SpringBoot can be used independently of SpringCloud to develop projects, but SpringCloud is inseparable from SpringBoot and belongs to dependency relationship;

  • SpringBoot focuses on the rapid and convenient development of individual micro services, and SpringCloud focuses on the overall service governance framework;

3.3. Dubbo and SpringCloud technology selection

1. Distributed + service governance Dubbo

The current mature Internet architecture, application service splitting + message middleware

2. Comparison between Dubbo and spring cloud

Take a look at community activity:

https://github.com/dubbo

https://github.com/spring-cloud

Comparison results:

The biggest difference: Spring Cloud abandons Dubbo's RPC communication and adopts HTTP based REST

Strictly speaking, these two methods have their own advantages and disadvantages. Although to some extent, the latter sacrifices the performance of service calls, it also avoids the problems caused by the above-mentioned native RPC. Moreover, REST is more flexible than RPC. The dependence of service providers and callers only depends on a contract, and there is no strong dependence at the code level. This advantage is more appropriate in the current microservice environment that emphasizes rapid evolution.

Difference between brand machine and assembly machine

The difference between community support and renewal

**Summary: * * the two solve different problem domains: Dubbo is positioned as an RPC framework, while spring cloud aims at a one-stop solution under the microservice architecture.

3.4 what can spring cloud do?

  • Distributed/versioned configuration

  • Service registration and discovery

  • Routing

  • Service to service calls

  • Load balancing configuration

  • Circuit Breakers

  • Distributed messaging

  • ...

3.5. Spring cloud Download

Official website: http://projects.spring.io/spring-cloud/

Self study reference books:

  • SpringCloud Netflix Chinese Documentation: https://springcloud.cc/spring-cloud-netflix.html

  • SpringCloud Chinese API document (official document translation): https://springcloud.cc/spring-cloud-dalston.html

  • SpringCloud China Community: http://springcloud.cn/

  • SpringCloud Chinese website: https://springcloud.cc

4, Spring cloud rest environment construction: Service Provider

4.1 introduction and SQL environment

  • We will use a Dept Department module as a general case of micro services. The Consumer consumer (Client) calls the services provided by the Provider (Server) through REST
  • Review previous studies of Spring, Spring MVC, Mybatis, etc
  • Maven's package allocation module architecture review
A simple Maven The module structure is as follows:

-- app-parent: A parent item(app-parent)Aggregated many subprojects(app-util\app-dao\app-web...)
  |-- pom.xml
  |
  |-- app-core
  ||---- pom.xml
  |
  |-- app-web
  ||---- pom.xml
  ......

A parent project has multiple Moudule sub modules

Spring cloud has three sub modules under its parent project for the first time

  • Springcloud API [encapsulated overall entity / interface / public configuration, etc.]
  • springcloud-consumer-dept-80 [service provider]
  • springcloud-provider-dept-8001 [service consumer]

Database used

Create a database named db01

Then enter the following statement

DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (
  `deptno` bigint NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) COLLATE utf8mb4_bin DEFAULT NULL,
  `db_source` varchar(60) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='Department table';

INSERT INTO `dept` VALUES ('1', 'Development Department', 'db01');
INSERT INTO `dept` VALUES ('2', 'Ministry of Personnel', 'db01');
INSERT INTO `dept` VALUES ('3', 'Finance Department', 'db01');
INSERT INTO `dept` VALUES ('4', 'Marketing Department', 'db01');
INSERT INTO `dept` VALUES ('5', 'Operation and maintenance department', 'db01');

4.2. Create parent project

  • Create a new parent project springcloud. Remember that packaging is a pom mode

  • It is mainly to define POM files and uniformly extract the jar packages common to subsequent sub modules, which is similar to an abstract parent class

    pom.xml of parent class

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.fafa</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>springcloud-api</module>
            <module>springcloud-provider-dept-8001</module>
            <module>springcloud-consumer-dept-80</module>
        </modules>
    
        <!--Packaging method  pom-->
        <packaging>pom</packaging>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <junit.version>4.12</junit.version>
            <log4j.version>1.2.17</log4j.version>
            <lombok.version>1.16.18</lombok.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>0.2.0.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--springCloud Dependence of-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>Greenwich.SR1</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--SpringBoot-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.1.4.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--database-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.21</version>
                </dependency>
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>1.1.10</version>
                </dependency>
                <!--SpringBoot starter-->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>1.3.2</version>
                </dependency>
                <!--Log test~-->
                <dependency>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-core</artifactId>
                    <version>1.2.3</version>
                </dependency>
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>${log4j.version}</version>
                </dependency>
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${lombok.version}</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    </project>
    

4.3. Create api

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>springcloud</artifactId>
        <groupId>com.fafa</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-api</artifactId>

    <!--Current Module The dependency you need. If the parent dependency has been configured, you don't need to write it here-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

Dept entity class of pojo

package com.fafa.springcloud.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

/**
 * Department category
 * Entity classes must implement serialization (because of network transmission)
 * orm Class table relation mapping
 * @author Sire
 *
 */
@Data
@NoArgsConstructor
// @Accessors chain programming
@Accessors(chain =  true)

public class Dept implements Serializable {

    private Long deptno;

    private String dname;
    /**
     * This data is stored in the field ~ microservice of that database,
     *  A service corresponds to a database, and the same information may exist in different databases
     */
    private String dbSource;

    /**
     * Since the id is automatically generated and the database is automatically written, you can only pass the name!
     * @param dname
     */
    public Dept(String dname) {
        this.dname = dname;
    }

    /**
     Chain writing:
     Dept dept = new Dept();
     dept.setDeptNo(11).setDname('sssss').setDbSource('001');

     */

}

4.3. Create a producer (Provider)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>springcloud</artifactId>
        <groupId>com.fafa</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-provider-dept-8001</artifactId>

    <properties>

    </properties>

    <dependencies>
        <!--We need to get the entity class, so we need to configure it api moudle-->
        <dependency>
            <groupId>com.fafa</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--Junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!--Jetty Application server, and Tomcat equally-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>

        <!--Web starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--logback-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>

        <!--data source-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>


    </dependencies>

</project>

application.yml

server:
  port: 8001

# Configuration of mybatis
mybatis:
#  Scan package
  type-aliases-package: com.fafa.springcloud.pojo
#  mybatis configuration file (if config location is used here, you will be prompted that it cannot be found)
  configuration-properties: classpath:mybatis/mybatis-config.xml
#  Mapping profile for mybatis
  mapper-locations: classpath:mybatis/mapper/*.xml
#  Hump naming on
  configuration:
    map-underscore-to-camel-case: true


#spring configuration
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?userUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root

Mybatis-config.xml (under mybatis in resources)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis Core profile-->
<configuration>
    <settings>
        <!--Enable L2 cache-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

Deptmapper.xml (under resources/mybatis/mapper)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--mybatis Core profile-->
<mapper namespace="com.fafa.springcloud.dao.DeptDao">

    <insert id="addDept" parameterType="dept">
        insert into db01.dept(dname,db_source)
        values(#{dname},DATABASE());
    </insert>

    <select id="qureryById" resultType="dept">
        select * from dept where deptno = #{deptno};
    </select>

    <select id="queryAll" resultType="dept">
        select * from dept;
    </select>

</mapper>

Dao layer

DeptDao.interface

package com.fafa.springcloud.dao;

import com.fafa.springcloud.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 21:53
 */
@Mapper
@Repository
public interface DeptDao {
    /**
     * Add Department
     * @param dept
     * @return
     */
    public boolean addDept(Dept dept);

    /**
     * Find users by id
     * @param id
     * @return
     */
    public Dept qureryById(@Param("deptno") Long id);

    /**
     * Query all users
     * @return
     */
    public List<Dept> queryAll();

}

Service layer

DeptService.interface

package com.fafa.springcloud.service;

import com.fafa.springcloud.pojo.Dept;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:21
 */
public interface DeptService {
    /**
     * Add Department
     * @param dept
     * @return
     */
    public boolean addDept(Dept dept);

    /**
     * Find users by id
     * @param id
     * @return
     */
    public Dept qureryById(@Param("deptno") Long id);

    /**
     * Query all users
     * @return
     */
    public List<Dept> queryAll();
}

DeptServiceImpl.java

package com.fafa.springcloud.service;

import com.fafa.springcloud.dao.DeptDao;
import com.fafa.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:22
 */
@Service
public class DeptServiceImpl implements DeptService{
    @Autowired
    DeptDao deptDao;

    @Override
    public boolean addDept(Dept dept) {
        return  deptDao.addDept(dept);
    }

    @Override
    public Dept qureryById(Long id) {
        return deptDao.qureryById(id);
    }

    @Override
    public List<Dept> queryAll() {
        return deptDao.queryAll();
    }
}

Controller layer

DeptController.java

package com.fafa.springcloud.controller;

import com.fafa.springcloud.pojo.Dept;
import com.fafa.springcloud.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:24
 */
@RestController
public class DeptController {
    @Autowired
    DeptService deptService;

    @RequestMapping("/addDept")
    public Boolean addDept(Dept dept){
        return deptService.addDept(dept);
    }

    @GetMapping("/queryById/{id}")
    public Dept queryById(@PathVariable("id") Long id){
        Dept dept = deptService.qureryById(id);
        return dept;
    }

    @GetMapping("/queryAll")
    public List<Dept> queryAll(){
        return deptService.queryAll();
    }

}

Main startup class

package com.fafa.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:30
 */
@SpringBootApplication
public class SpringBootStarter {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootStarter.class, args);
    }

}

4.4. Create a Consumer

The consumer does not need to connect to the database, but only needs to write to the Controller layer and call the producer (Provider) through REST

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>springcloud</artifactId>
        <groupId>com.fafa</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-dept-80</artifactId>

    <dependencies>
        <dependency>
            <groupId>com.fafa</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--Web starter-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

application.yaml

server:
  port: 80

ConfigBean.java (register RestTemplate in Spring container)

package com.fafa.springcloud.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-16 21:10
 */
@Configuration
public class ConfigBean {
    // This is equivalent to registering bean s with xml in spring

    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

DeptController.java

package com.fafa.springcloud.controller;

import com.fafa.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-16 21:03
 */

@RestController
public class DeptController {
    /**
     * Understanding: consumers should not have a service layer
     *RestTemplate ...... We can call it directly! Register in Spring
     *(URL,Entity: map, class < T > responsetype)
     */
    @Autowired
    //Provide a variety of convenient methods for remote access to http services and a simple Restful service template
    private RestTemplate restTemplate;


    /**
     * constant
     * **/
    private final String REST_URL_PREFIX = "http://localhost:8001";

    /**
     *
     * @param id
     * @return
     */
    @RequestMapping("/consumer/dept/get/{id}")
    public Dept getDept(@PathVariable("id") Long id){
        return restTemplate.getForObject(REST_URL_PREFIX + "/queryById/" + id,
                                         Dept.class);
    }

    @RequestMapping("/consumer/dept/add")
    public boolean addDept(Dept dept){
        HashMap<String, Object> map = new HashMap<>();
        map.put("dname",dept.getDname());
        map.put("deptNo",dept.getDeptno());
        map.put("dbSource",dept.getDbSource());
        System.out.println(map);
        return restTemplate.postForObject(REST_URL_PREFIX + "/addDept",
                                          map, Boolean.class);
    }

    @RequestMapping("/consumer/dept/list")
    public List<Dept> queryAll(){
        return restTemplate.getForObject(REST_URL_PREFIX + "/queryAll" , List.class);
    }

}

Main startup class

SpringCloudConsumer.java

package com.fafa.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-16 21:34
 */
@SpringBootApplication
public class SpringCloudConsumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsumer.class, args);
    }
}

4.5 Startup Test

  • First the producers, then the consumers
  • Producer (8001) consumer (80)

5, Service Registry (Eureka)

5.1. What is Eureka

  • Netfilx follows the API principles when it comes to Eureka
  • Eureka is a sub module of Netflix and one of the core modules. Eureka is a REST based service. It is used to locate services to realize service discovery and failover in the cloud middleware layer. Service registration and discovery are very important for microservices. With service registration and discovery, you can access services only by using the service identifier without modifying the service invocation configuration file, The function is similar to Dubbo's registry, such as Zookeeper

5.2 principle understanding

  • Eureka basic architecture

    • Spring cloud encapsulates the Eureka module developed by Netflix to realize service registration and discovery (compared with Zookeeper)

    • Eureka adopts C-S architecture design. Eureka server is the server of service registration function. It is the service registration center

    • Other microservices in the system use Eureka's client to connect to Eureka server and maintain heartbeat connection. In this way, the maintenance personnel of the system can monitor the normal operation of various microservices in the system through Eureka server. Some other modules of spring cloud (such as Zuul) can discover other microservices in the system and execute relevant logic through Eureka server

    • Compare with Dubbo architecture

    • Eureka consists of two components: Eureka Server and Eureka Client

    • Eureka Server provides service registration. After each node is started, it will be registered in Eureka Server. In this way, the service registry in Eureka Server will store the information of all class service nodes, and the information of service nodes can be seen intuitively in the interface

    • Eureka Client is a Java client, which is used to simplify the interaction of Eureka Server. The client also has a built-in load balancer using polling load algorithm. After the application starts, a heartbeat will be sent to EurekaServer (the default cycle is 30 seconds). If Eureka Server does not receive the heartbeat of a node in multiple heartbeat cycles, Eureka Server will remove the service node from the service registry (the default cycle is 90s)

  • Three roles

    • Eureka Server: provides service registration and discovery
    • Service Provider: the service producer registers its own services in Eureka so that the service consumer can find them
    • Service Consumer: the Service Consumer. Get the registered service list from Eureka to find the consumer service
  • Current project status

5.3 construction steps

eureka-server

  1. Establishment of springcloud-eureka-7001 module

  2. pom.xml configuration

    <!--Guide Package~-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <!--Import Eureka Server rely on-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
    
  3. application.yml

server:
  port: 7001

# Eureka configuration
eureka:
  instance:
    # Instance name of Eureka server
    hostname: 127.0.0.1
  client:
    # Indicates whether to register yourself with Eureka Registry (this module itself is a server, so it is not required)
    register-with-eureka: false
    # If the fetch registry is false, it means that it is the registry and the client is changed to true
    fetch-registry: false
    # Eureka monitoring page~
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

The default port and access path of Eureka in the source code:

  1. Main startup class

    /**
     * @Auther: csp1999
     * @Date: 2020/05/18/10:26
     * @Description: After startup, access http://127.0.0.1:7001/
     */
    @SpringBootApplication
    // @The startup class of EnableEurekaServer server can accept others to register~
    @EnableEurekaServer
    public class EurekaServer_7001 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer_7001.class,args);
        }
    }
    
    
  2. Access after successful startup http://localhost:7001/ Get the following page

eureka-client

Adjust the previously created springlouc-provider-dept-8001

  1. Import Eureka dependencies

    <!--Eureka rely on-->
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    
    
  2. Eureka configuration added in application

    # Eureka configuration: configure the service registry address
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:7001/eureka/
    
    
  3. Add the @ EnableEurekaClient annotation to the main startup class

    @SpringBootApplication
    // @Enable Eureka client enables Eureka client annotation and automatically registers the service with the registry after the service is started
    @EnableEurekaClient
    public class DeptProvider_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProvider_8001.class,args);
        }
    }
    
  4. First start the 7001 server, then start the 8001 client for testing, and then access the monitoring page http://localhost:7001/ The production results are shown in the figure. It is successful

  5. Modify the default description information on Eureka

    # Eureka configuration: configure the service registry address
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:7001/eureka/
      instance:
        # Modify the default description information on Eureka
        instance-id: springcloud-provider-dept-8001
    
  6. Configure monitoring information about service loading

    Add dependency in pom.xml

    <!--actuator Improve monitoring information-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    

    Add configuration in application.yml

    # info configuration
    info:
      # Name of the project
      app.name: haust-springcloud
      # Company name
      company.name: School of software, Xiyuan campus, Henan University of science and technology
    

    Refresh the project, and the result is shown in the figure below

Eureka's self-protection mechanism: living is better than dying

In a word, if a micro service is unavailable at a certain time, eureka will not clean it immediately, but will still save the information of the micro service!

  • By default, if the eureka server does not receive the instance heartbeat within a certain period of time, the instance will be deleted from the registry (the default is 90 seconds). However, if a large number of instance heartbeats are lost in a short period of time, the eureka server's self-protection mechanism will be triggered. For example, during development and testing, microservice instances need to be restarted frequently, However, we rarely restart the eureka server together (because the eureka Registry will not be modified during development). When the number of heartbeats received in one minute decreases significantly, the protection mechanism will be triggered. You can see Renews threshold and Renews(last min) in the eureka management interface. When the latter (heartbeat received in the last minute) is less than the former (heartbeat threshold), the protection mechanism will be triggered and a red warning will appear: emergency! eureka may be incorrectly claiming instances are up when the're not. Needs are lesser that hold and hence the instances are not registering expired just to be safe.
  • The purpose of this protection mechanism is to avoid network connection failure. In case of network failure, the microservice and the registry cannot communicate normally, but the service itself is healthy and should not be cancelled. If eureka mistakenly deletes the microservice due to network failure, the microservice will not be re registered with eureka server even if the network is restored, Because the registration request will be initiated only when the micro service is started, and only the heartbeat and service list request will be sent later. In this way, although the instance is running, it will never be perceived by other services. Therefore, when the eureka server loses too many client heartbeats in a short time, it will enter the self-protection mode. In this mode, eureka will protect the information in the registry and will not log off any microservices. When the network fault recovers, eureka will automatically exit the protection mode. The self-protection mode can make the cluster more robust.
  • However, in the development and testing phase, we need to restart publishing frequently. If the protection mechanism is triggered, the old service instance is not deleted. At this time, the request may run to the old instance, and the instance has been closed, which will lead to request errors and affect the development and testing. Therefore, in the development and testing stage, we can turn off the self-protection mode by adding the following configuration to the eureka server configuration file: Eureka. Server. Enable self-protection = false [turning off the self-protection mechanism is not recommended]

For details, please refer to the following blog: https://blog.csdn.net/wudiyong22/article/details/80827594

Register the micro service and get some messages (which will be used by team development)

New method in DeptController.java

/**
 * DiscoveryClient It can be used to obtain some configuration information and get specific micro services!
 */
@Autowired
private DiscoveryClient client;

/**
 * Get some registered micro service information ~,
 * Be sure to note that the package imported here is under spring
 * @return
 */
@GetMapping("/dept/discovery")
public Object discovery() {
    // Get the list of micro services
    List<String> services = client.getServices();
    System.out.println("discovery=>services:" + services);
    // Get a specific microservice information through the specific microservice id, applicaioinName;
    List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
    for (ServiceInstance instance : instances) {
        System.out.println(
            instance.getHost() + "\t" + // Host name
            instance.getPort() + "\t" + // Port number
            instance.getUri() + "\t" + // uri
            instance.getServiceId() // Service id
        );
    }
    return this.client;
}

Add @ EnableDiscoveryClient annotation to the main startup class

@SpringBootApplication
// @Enable Eureka client enables Eureka client annotation and automatically registers the service with the registry after the service is started
@EnableEurekaClient
// @EnableEurekaClient opens the annotation of the service discovery client, which can be used to obtain some configuration information and obtain specific microservices
@EnableDiscoveryClient
public class DeptProvider_8001 {
    ...
}

The results are shown in the figure below:

5.4 Eureka: cluster environment configuration

[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 thpblpep-163560173313) (C: \ users \ sire \ appdata \ roaming \ typora \ user images \ image-20211017223149806. PNG)]

1. Initialization

New springcloud-eureka-7002 and springcloud-eureka-7003 modules

1. Add dependency for pom.xml (same as springcloud-eureka-7001)

<!--Guide Package~-->
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
    <!--Import Eureka Server rely on-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka-server</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
    <!--Hot deployment tool-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>
</dependencies>

2.application.yml configuration (same as springcloud-eureka-7001)

server:
  port: 7003

# Eureka configuration
eureka:
  instance:
    hostname: localhost # Instance name of Eureka server
  client:
    register-with-eureka: false # Indicates whether to register yourself with Eureka Registry (this module itself is a server, so it is not required)
    fetch-registry: false # If fetch registry is false, it indicates that it is the registry
    service-url: # Monitoring page~
      # Override Eureka's default port and access path -- > http://localhost:7001/eureka/
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3. Main startup class (same as springcloud-eureka-7001)

/**
 * @Auther: csp1999
 * @Date: 2020/05/18/10:26
 * @Description: After startup, access http://127.0.0.1:7003/
 */
@SpringBootApplication
// @The startup class of EnableEurekaServer server can accept others to register~
public class EurekaServer_7003 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServer_7003.class,args);
    }
}

2. Cluster members are interrelated

Configure some custom native names, find the native hosts file and open it

At the end of the hosts file, add the local name to access. The default is localhost

Modify the configuration of application.yml, as shown in the figure: springcloud-eureka-7001 configuration, springcloud-eureka-7002/springcloud-eureka-7003 to their corresponding names

Associate springcloud-eureka-7001 with springcloud-eureka-7002 and springcloud-eureka-7003 in the cluster

The complete application.yml under springcloud-eureka-7001 is as follows

server:
  port: 7001

#Eureka configuration
eureka:
  instance:
    hostname: eureka7001.com #Instance name of Eureka server
  client:
    register-with-eureka: false #Indicates whether to register yourself with Eureka Registry (this module itself is a server, so it is not required)
    fetch-registry: false #If fetch registry is false, it indicates that it is the registry
    service-url: #Monitoring page~
      #Override Eureka's default port and access path -- > http://localhost:7001/eureka/
      # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # Cluster (Association): 7001, 7002, 7003
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

At the same time, make springcloud-eureka-7002 associated with springcloud-eureka-7001 and springcloud-eureka-7003 in the cluster

The complete application.yml under springcloud-eureka-7002 is as follows

server:
  port: 7002

#Eureka configuration
eureka:
  instance:
    hostname: eureka7002.com #Instance name of Eureka server
  client:
    register-with-eureka: false #Indicates whether to register yourself with Eureka Registry (this module itself is a server, so it is not required)
    fetch-registry: false #If fetch registry is false, it indicates that it is the registry
    service-url: #Monitoring page~
      #Override Eureka's default port and access path -- > http://localhost:7001/eureka/
      # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # Cluster (Association): 7002, 7001, 7003
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/

Spring cloud-eureka-7003 can be configured in the same way

Modify Eureka configuration through the yml configuration file under springcloud-provider-dept-8001: configure the service registry address

# Eureka configuration: configure the service registry address
eureka:
  client:
    service-url:
      # Registration center address 7001-7003
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-provider-dept-8001 #Modify the default description information on Eureka

In this way, the simulation cluster is set up, and a project can be attached to three servers

5.5 difference between comparison and ZooKeeper

1. Review CAP principles

RDBMS (MySQL\Oracle\sqlServer) ===> ACID

NoSQL (Redis\MongoDB) ===> CAP

2. What is acid?
  • A (Atomicity)
  • C (Consistency)
  • I (Isolation)
  • D (Durability)
3. What is cap?
  • C (Consistency) strong consistency
  • A (Availability)
  • P (Partition tolerance)

Three in two of CAP: CA, AP, CP

4. The core of cap theory
  • A distributed system cannot meet the three requirements of consistency, availability and partition fault tolerance at the same time
  • According to the principle of CAP, NoSQL database is divided into three categories: meeting CA principle, meeting CP principle and meeting AP principle
  • CA: single point cluster. Systems that meet consistency and availability usually have poor scalability
  • CP: a system that meets consistency and partition fault tolerance. Generally, the performance is not particularly high
  • AP: a system that meets the requirements of availability and partition fault tolerance. Generally, it may have lower requirements for consistency
5. As a distributed service registry, where is Eureka better than Zookeeper?
  • The famous CAP theory points out that A distributed system cannot meet C (consistency), A (availability) and P (fault tolerance) at the same time. Because partition fault tolerance P must be guaranteed in distributed systems, we can only trade off between A and C.
  • Zookeeper guarantees CP - > systems that meet consistency and partition fault tolerance, and generally have low performance
    Eureka guarantees that AP - > systems that meet availability and partition fault tolerance may generally have lower requirements for consistency

Zookeeper guarantees CP

When querying the service list from the registry, we can tolerate that the registry returns the registration information a few minutes ago, but we can't receive the service and directly down it. In other words, the service registration function requires higher availability than consistency. However, a situation occurs in zookeeper. When the master node loses contact with other nodes due to network failure, the remaining nodes will re elect leaders. The problem is that the election leader takes too long, 30-120s, and the entire zookeeper cluster is unavailable during the election, which leads to the paralysis of the registration service during the election. In the cloud deployment environment, the loss of the master node of the zookeeper cluster due to network problems is a high probability event. Although the service can be restored eventually, the long election time leads to the long-term unavailability of registration, which is intolerable.

Eureka guarantees AP

Eureka understands this, so it gives priority to ensuring availability in design. Eureka's nodes are equal. The failure of several nodes will not affect the work of normal nodes, and the remaining nodes can still provide registration and query services. When registering with an Eureka client, if it finds that the connection fails, it will automatically switch to other nodes. As long as one Eureka is still there, the availability of the registration service can be maintained, but the information found may not be up-to-date. In addition, Eureka also has a self-protection mechanism. If more than 85% of the nodes do not have a normal heartbeat within 15 minutes, Eureka thinks that there is a network failure between the client and the registry. At this time, the following situations will occur:

  • Eureka is not removing services that should expire because they haven't received a heartbeat for a long time from the registration list

  • Eureka can still accept the registration and query requests for new services, but it will not be synchronized to other nodes (that is, ensure that the current node is still available)

  • When the network is stable, the new registration information of the current instance will be synchronized to other nodes

    Therefore, Eureka can deal with the loss of contact of some nodes due to network failure without paralyzing the whole registration service like zookeeper

6, Ribbon: load balancing (client based)

6.1 load balancing and Ribbon

What is Ribbon?

  • Spring Cloud Ribbon is a set based on Netfilx 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 Ribbon to implement a custom load balancing algorithm!

What can Ribbon do?

  • LB, or load balancer, is often used in microservices or distributed clusters.
  • Load balancing simply means that users' requests are evenly distributed to multiple servers, so as to achieve the HA (high availability) of the system.
  • Common load balancing software include Nginx, Lvs, etc.
  • Both Dubbo and spring cloud provide us with load balancing. The load balancing algorithm of spring cloud can be customized.
  • Simple classification of load balancing:
    • Centralized LB:
      • That is, an independent LB facility 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!
    • Advance program LB
      • Integrate LB logic into the consumer. The consumer knows which addresses are available from the service registry, and then selects an appropriate server from these addresses.
      • Ribbon belongs to in-process LB. it is just a class library integrated into the consumer process. The consumer obtains the address of the service provider through it!

6.2. Integrated Ribbon

springcloud-consumer-dept-80 adds Ribbon and Eureka dependencies to pom.xml

<!--Ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-ribbon</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>
<!--Eureka: Ribbon Need from Eureka What can I get from the service center-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

Configure Eureka in the application.yml file

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

The main startup class is annotated with @ EnableEurekaClient to open Eureka

package com.fafa.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-16 21:34
 */
//After the integration of Ribbon and Eureka, the client can call directly without caring about the IP address and port number
@SpringBootApplication
@EnableEurekaClient //Open Eureka client

public class SpringCloudConsumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsumer.class, args);
    }
}

Custom Spring configuration class: ConfigBean.java configures load balancing and implements RestTemplate

@Configuration
public class ConfigBean {/** This is equivalent to registering bean s with xml in spring**/

    /** Configure load balancing to implement RestTemplate**/
    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

Modify controller: DeptController

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

6.3. Use Ribbon to realize load balancing

flow chart:

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

2. Refer to springcloud-provider-dept-8001, add pom.xml dependency, mybatis and application.yml configuration under resourcece, and Java code for the other two clouds

3. Start all service tests (determine the number of services to start according to your 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.

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.java under the myRule package. Note: the package should not be the same level as the package where the main startup class is located, but should be the same level as the package where the startup class is located:

package com.fafa.myrule;

import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-22 16:03
 */
@Configuration
public class MyRule {

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

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

package com.fafa.springcloud;

import com.fafa.myrule.MyRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-16 21:34
 */
//After the integration of Ribbon and Eureka, the client can call directly without caring about the IP address and port number
@SpringBootApplication
@EnableEurekaClient //Open Eureka client
//The custom Ribbon class can be loaded when the micro service is started (the custom rules will overwrite the original default rules)
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)//Turn on load balancing and specify custom rules

public class SpringCloudConsumer {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsumer.class, args);
    }
}

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

package com.fafa.myrule;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-22 23:00
 */

public class MyRandomRule extends AbstractLoadBalancerRule {


    /**
     * If each service is accessed 5 times, the next service will be replaced (3 services in total)
     * <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 introduction to Feign

Feign is a declarative Web Service client, which makes it easier to call between microservices, similar to the controller calling service. Spring cloud integrates Ribbon and Eureka, and can use Feigin 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 for invoking 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, the RestTemplate is used to encapsulate Http requests to form a set of templated calling methods. However, in the actual development, because there may be more than one invocation of service dependencies, and often an 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 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 by annotation (similar to the Mapper annotation on Dao interface in the past, now it is a micro service interface with a Feign annotation on it), 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. Unlike 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.xml, resource, and java code under the springcloud-consumer-dept-80 module 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>
    
    

    Implemented through the Ribbon: - the original controller: DeptConsumerController.java

    package com.fafa.springcloud.controller;
    
    import com.fafa.springcloud.pojo.Dept;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * @author Sire
     * @version 1.0
     * @date 2021-10-16 21:03
     */
    
    @RestController
    public class DeptController {
        /**
         * Understanding: consumers should not have a service layer
         *  RestTemplate ...... We can call it directly! Register in Spring
         *(URL,Entity: map, class < T > responsetype)
         */
        @Autowired
        /** restTemplate Provide a variety of convenient methods for remote access to http services and a simple Restful service template**/
        private RestTemplate restTemplate;
    
    
        /**
         * constant
         * **/
        //Ribbon: the address here should be a variable accessed by the service name
        //private static final String REST_URL_PREFIX = "http://localhost:8001";
        private final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    
        /**
         *
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept getDept(@PathVariable("id") Long id){
            return restTemplate.getForObject(REST_URL_PREFIX + "/queryById/" + id,
                                             Dept.class);
        }
    
        @RequestMapping("/consumer/dept/add")
        public boolean addDept(Dept dept){
            HashMap<String, Object> map = new HashMap<>();
            map.put("dname",dept.getDname());
            map.put("deptNo",dept.getDeptno());
            map.put("dbSource",dept.getDbSource());
            System.out.println(map);
            return restTemplate.postForObject(REST_URL_PREFIX + "/addDept",
                                              map, Boolean.class);
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> queryAll(){
            return restTemplate.getForObject(REST_URL_PREFIX + "/queryAll" , List.class);
        }
    
    }
    
    

    Implemented through Feign: - controller after transformation: DeptConsumerController.java

    package com.fafa.springcloud.controller;
    
    import com.fafa.springcloud.pojo.Dept;
    import com.fafa.springcloud.service.DeptClientService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import java.util.HashMap;
    import java.util.List;
    
    /**
     * @author Sire
     * @version 1.0
     * @date 2021-10-16 21:03
     */
    
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptClientService service;
    
    
        /**
         *
         * @param id
         * @return
         */
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept getDept(@PathVariable("id") Long id){
            return this.service.qureryById(id);
        }
    
        @RequestMapping("/consumer/dept/add")
        public boolean addDept(Dept dept){
            return this.service.addDept();
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> queryAll(){
            return this.service.queryAll();
        }
    }
    
    

    Comparing Feign and Ribbon, the former shows the characteristics of interface oriented programming, the code looks more refreshing, and the Feign call method is more in line with our previous programming habit of calling the Service layer by the Controller layer when we were doing SSM or sprnboot projects!

    Main configuration class:

    package com.fafa.springcloud;
    
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    
    /**
     * @author Sire
     * @version 1.0
     * @date 2021-10-16 21:34
     */
    //After the integration of Ribbon and Eureka, the client can call directly without caring about the IP address and port number
    @SpringBootApplication
    @EnableEurekaClient //Open Eureka client
    @EnableFeignClients(basePackages = {"com.fafa.springcloud"}) // Scan package
    public class FeignConsumer {
        public static void main(String[] args) {
            SpringApplication.run(FeignConsumer.class, args);
        }
    }
    
    
  2. Transforming the spring cloud API module

    Add feign dependency to pom.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,

    package com.fafa.springcloud.service;
    
    import com.fafa.springcloud.pojo.Dept;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    
    import java.util.List;
    
    /**
     * @author Sire
     * @version 1.0
     * @date 2021-10-23 22:35
     */
    @Component
    // @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/add")
        public boolean addDept();
    
        @GetMapping("/dept/get/{id}")
        public Dept qureryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll();
    }
    
    

    7.3 how should Ribbon and Feign choose?

    According to 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 the Ribbon, but the latter is in the calling mode, in order to meet the interface calling habits used by some developers!

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

8, Service fuse

Problems faced by distributed systems

There are dozens of dependencies for applications in complex distributed architecture, and each dependency will inevitably fail at some time!

8.1 service avalanche

When calling between multiple microservices, suppose microservice A calls microservice B and microservice C, 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, resulting in system crash, The so-called "avalanche effect".

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. These all mean that failures and delays need to be isolated and managed 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 failure of the whole system service, avoid cascading failures, and improve the elasticity of distributed systems.

"Circuit breaker" itself is a kind of switching device. When a service unit fails, it returns a service expected and processable alternative response (FallBack) to the caller through the fault monitoring of the circuit breaker (similar to a blown 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.

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 potentially blocking service in many back-end systems, it can block the entire 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 the source of potential failures. 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 (with wall): 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 wrong response information. After detecting that the microservice call response of the node is normal, restore the call link. In the spring cloud framework, the fuse mechanism is implemented through hystrix. Hystrix will monitor the status of calls between microservices. When the failed call reaches 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 following problems can be solved by the service provider:

  • 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.xml, resource and Java code in springcloud provider Dept – 8001 for initialization and adjustment.

Import hystrix dependencies

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

Adjust yml profile

server:
  port: 8001

# mybatis configuration
mybatis:
  # pojo package under spring cloud API module
  type-aliases-package: com.haust.springcloud.pojo
  # Class path of mybatis-config.xml core configuration file under this module
  config-location: classpath:mybatis/mybatis-config.xml
  # mapper configuration file classpath under this module
  mapper-locations: classpath:mybatis/mapper/*.xml

# spring configuration
spring:
  application:
    #Project name
    name: springcloud-provider-dept
  datasource:
    # Druid data source
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: root

# Eureka configuration: configure the service registry address
eureka:
  client:
    service-url:
      # Registration center address 7001-7003
      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
    prefer-ip-address: true #After changing to true, the default display is the ip address instead of localhost

#info configuration
info:
  app.name: haust-springcloud #Name of the project
  company.name: com.haust #Company name

prefer-ip-address: false:

[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-jwqc8rba-16356017333) (C: \ users \ sire \ appdata \ roaming \ typora \ user images \ image-20211024182435860. PNG)]

prefer-ip-address: true:

Modify controller

package com.fafa.springcloud.controller;

import com.fafa.springcloud.pojo.Dept;
import com.fafa.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:24
 */
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;
    
	 /**
     * Query department information according to id
     * If an exception occurs in the query based on id, follow the alternative code of hystrixGet
     * @param id
     * @return
     */
    @GetMapping("/dept/get/{id}")
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public Dept get(@PathVariable("id") Long id){
        Dept dept = deptService.qureryById(id);
        /* Valuable code */
        if(dept == null){
            throw new RuntimeException("id =>" + id +",The user does not exist, or the information cannot be found!");
        }
        return dept;
    }

    //alternative method 
    public Dept hystrixGet(@PathVariable("id") Long id){
        return new Dept()
            .setDeptno(id)
            .setDname("id =>" + id + "No corresponding information found, null---@Hystrix")
            .setDbSource("no this database in MySQL");
    }

}

Add the support annotation @ enablercircuitbreaker to the main startup class

package com.fafa.springcloud;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-15 22:30
 */
@SpringBootApplication
@EnableEurekaClient  // Automatically register with Eureka after the server starts
@EnableDiscoveryClient // Service discovery~
@EnableCircuitBreaker // Add support for fusing

public class DeptProviderHystrix_8001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProviderHystrix_8001.class, args);
    }

}

Test:

After use, when accessing a nonexistent id, the foreground page displays the following data:

If the springcloud provider Dept – 8001 module that is not applicable accesses 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 server pressure increases sharply, some services and pages are not processed strategically or handled in a simple way according to the actual business conditions and traffic, so as to release server resources to ensure the normal or efficient operation of core business. To put it bluntly, it is to give system resources to high priority services as much as possible.

Resources are limited and requests are unlimited. If the service is not degraded during the concurrency peak period, 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 order to ensure the availability of core function services, some services must be degraded during peak periods. For example, when double 11 is active, all services unrelated to the transaction are downgraded, such as viewing ant deep forest, viewing historical orders, etc.

What are the main scenarios for service degradation? When the overall load of the whole microservice architecture exceeds the preset upper threshold or the upcoming traffic is expected to exceed the preset threshold, some unimportant or non urgent services or tasks can be delayed or suspended in order to ensure the normal operation of important or basic services.

The degradation method can be based on the business, and the service can be delayed. For example, the delay will increase the points for the user, but it will 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.

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 small 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, 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 cache data previously temporarily stored)

4) Current limit degradation: when second killing or snapping up some restricted goods, the system may crash due to too much traffic. At this time, current limit will be used to limit the traffic. When the current limit threshold is reached, subsequent requests will be degraded; The processing scheme after degradation can be: 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 DeptClientServiceFallBackFactory.java in the service package under the springcloud API module

package com.fafa.springcloud.service;

import com.fafa.springcloud.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-24 16:24
 */
@Component
public class DeptClientServiceFallBackFactory implements FallbackFactory {
    @Override
    public Object create(Throwable throwable) {
        return new DeptClientService() {
            @Override
            public boolean addDept() {
                return false;
            }

            @Override
            public Dept qureryById(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")
                    .setDbSource("no data~");
            }

            @Override
            public List<Dept> queryAll() {
                return null;
            }
        };
    }
}

Specify the degraded configuration class DeptClientServiceFallBackFactory in DeptClientService

package com.fafa.springcloud.service;

import com.fafa.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-23 22:35
 */
@Component
/**
 * @FeignClient:Microservice client annotation, value: specify the name of the microservice, so that Feign client can directly find the corresponding microservice
 * fallbackFactory Specifies the demotion configuration class
 * **/
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT" ,fallbackFactory = DeptClientServiceFallBackFactory.class)
public interface DeptClientService {
    @GetMapping("/dept/add")
    public boolean addDept();

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

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

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: # Access one of the three registries at random
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

# Open degraded feign.hystrix
feign:
  hystrix:
    enabled: true

8.6 difference between service fusing and degradation

  • Service fusing - > server: a service timeout or exception causes fusing ~, which is similar to a 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 a decline in the overall service, but at least it can be used, which is better than hanging up directly.
  • The triggering reasons are different. Service fusing is generally caused by a service (downstream service) fault, 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 method is 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 limit: 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; Automatic system execution and recovery

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 to add monitoring

@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());
        //Accessing 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:

9, Zuul routing gateway

summary

What is Zuul?

Zull includes two main functions: Request Routing (for jump) and filtering:

The routing function is responsible for forwarding external requests to specific micro service instances, which is the basis for realizing the unified entrance of external access, while the filter function is responsible for intervening in the request processing process, which is the basis for realizing request verification, service aggregation and other functions. Zuul and Eureka integrate, register zuul as an application under Eureka service governance, and obtain messages of other services from Eureka, that is, access to micro services in the future is obtained through zuul jump.

Note: Zuul service will eventually register with Eureka

It provides three functions: agent + routing + filtering!

What can Zuul do?

  • route
  • filter

Official documents: https://github.com/Netflix/zuul/

Introductory case

Create a new springcloud zuul module and import dependencies

<dependencies>

    <!--Import zuul rely on-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-zuul</artifactId>
        <version>1.4.6.RELEASE</version>
    </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.fafa</groupId>
        <artifactId>springcloud-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

</dependencies>

application.yml

server:
  port: 9527

spring:
  application:
    name: springcloud-zuul # Microservice name

# Eureka registry configuration
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

  instance: # id of the instance
    instance-id: zuul9527.com
    prefer-ip-address: true # Display ip

info:
  app.name: fafa.spring # entry name
  company.name: Hebei Petroleum Vocational and Technical University # corporate name

# zuul routing gateway configuration
zuul:
  # Routing related configuration
  # Original access route eg:http://www.codestu.com:9527/springcloud-provider-dept/dept/get/1
  # After zull route configuration, access the route eg:http://www.codestu.com:9527/keaifa/mydept/dept/get/1
  routes:
      mydept.serviceId: springcloud-provider-dept # Service provider routing name of eureka registry
      mydept.path: /mydept/** # Change the service provider route name of the eureka registry to a custom route name
  # You can no longer use this path to access, *: ignore and hide all service names ~ nore
  ignored-services: "*"
  # Set public prefix
  prefix: /keaifa

Main startup class

package com.fafa.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-26 23:22
 */
@SpringBootApplication
@EnableZuulProxy // Open Zuul
public class ZuulApplication_9527 {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication_9527.class,args);
    }
}

Test:

It can be seen that Zull routing gateway is registered in Eureka registry!

The above figure shows the routes accessed by the service interface when the Zull routing gateway is not configured. It can be seen that it is not safe to directly access with the name of the micro service (service provider). You can't expose the name of the micro service!

Therefore, after the Zull routing gateway is configured, the accessed routes are:

We can see that the microservice name is replaced and hidden, replaced by our custom microservice name mydept, and prefixed with haust, so as to encrypt the access of routing fan!

For details, refer to the springcloud Chinese community zuul component: https://www.springcloud.cc/spring-cloud-greenwich.html#_router_and_filter_zuul

10, Spring Cloud Config distributed configuration

Dalston.RELEASE

Spring Cloud Config provides server and client support for external configurations in distributed systems. With Config Server, you can manage external properties of applications in all environments. The conceptual mappings on the client and server are the same as the Spring Environment and PropertySource abstractions, so they fit well with spring applications, but can be used with any application running in any language. As applications go through the deployment process from developers to test and production, you can manage the configuration between these environments and determine that the application has everything you need to run when migrating. The default implementation of the server storage back end uses git, so it easily supports the configuration environment of the label version and can access various tools for managing content. It's easy to add an alternative implementation and insert it using the spring configuration.

summary

Configuration file problems faced by distributed systems

Microservice means to split the business in a single application into one sub service. The granularity of each service is relatively small, so there will be a large number of services in the system. Since each service needs the necessary configuration information to run, a set of centralized and dynamic configuration management facilities is essential. spring cloud provides configServer to solve this problem. Each of our microservices carries an application.yml, and hundreds of configuration files are modified, which is a headache!

What is the spring cloud config distributed configuration center?

spring cloud config provides centralized external support for microservices in the microservice architecture. The configuration server provides a centralized external configuration for all links of different microservice applications.

spring cloud config is divided into two parts: server and client.

The server is also called distributed configuration center. It is an independent micro service application, which is used to connect to the configuration server and provide the client with access interfaces such as obtaining configuration information, encryption and decryption information.

The client manages application resources and business-related configuration content through the specified configuration center, and obtains and loads configuration information from the configuration center at startup. The configuration server uses git to store configuration information by default, which is helpful for version management of environment configuration. The GIT client tool can be used to manage and access the configuration content conveniently.

What can the spring cloud config distributed configuration center do?

  • Centralized management profile

  • Different environments, different configurations, dynamic configuration updates, and deployment by environment, such as / dev / test / prod / beta / releases

  • The configuration is dynamically adjusted during operation. It is no longer necessary to write configuration files on each service deployed machine. The service will uniformly pull and configure its own information from the configuration center

  • When the configuration changes, the service does not need to restart, it can sense the configuration changes and apply the new configuration

  • Expose the configuration information in the form of REST interface

Integration of spring cloud config distributed configuration center and GitHub

spring cloud config uses git to store configuration files by default (there are other ways, such as self-contained SVN and local files), but Git is the most recommended and is accessed in the form of http / https.

Introductory case

Build environment

  • Create a Gitee or Github repository

  • Download warehouse items locally

  • Write application.yml locally

    spring:
        profiles:
         active: dev
    
    ---
    spring:
        profiles: dev
        application: 
            name: sringcloud-config-dev
    ---
    spring:
        profiles: test
        application: 
            name: sringcloud-config-dev
    
  • Submit the application.yml to the remote repository

    1. # Add all files to staging area
      git add .
      
    2. # View status
      git status
      
    3. #  Submit the contents in the staging area to the local warehouse -m and submit the information
      git commit -m "1"
      
    4. # Submit to remote warehouse
      git push origin master
      # If the submission fails, please enter the following command before proceeding to the previous step
      git pull
      

Server

Create a new springcloud-config-server-3344 module and import pom.xml dependency

<!--config-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>
<!--Web starter-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Eureka: Ribbon Need from Eureka What can I get from the service center-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-eureka</artifactId>
    <version>1.4.6.RELEASE</version>
</dependency>

Create an application.yml configuration file under resource. The Spring Cloud Config server provides configuration for remote clients from the git repository (required):

server:
  port: 3344

spring:
  application:
    name: springcloud-config-server
    # Connect to remote warehouse
  cloud:
    config:
      server:
        git:
          uri: https://gitee.com/lovely-hair/gitstudy01.git

# If this configuration is not added, the error Cannot execute request on any known server will be reported: the address of the Eureka server connection is incorrect
# Or directly comment out the eureka dependency. eureka is temporarily unavailable here
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false

Main startup class

package com.fafa.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

/**
 * @author Sire
 * @version 1.0
 * @date 2021-10-28 14:55
 */
@SpringBootApplication
@EnableConfigServer
public class ConfigServer3344 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServer3344.class,args);
    }
}

The default strategy for locating resources is to clone a git repository (in spring.cloud.config.server.git.uri) and use it to initialize a mini spring application. The Environment of the applet is used to enumerate property sources and publish them through JSON endpoints.

The HTTP service has resources in the following format:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

Where "application" is injected as spring.config.name in spring application (that is, it is usually "application" in conventional Spring Boot applications), "configuration file" is the active configuration file (or the attribute of comma separated list), and "label" is an optional git label (the default is "master").

Test access http://localhost:3344/application-dev.yml

[external link picture transfer failed. The source station may have an anti-theft chain mechanism. It is recommended to save the picture and upload it directly (img-0uyimuma-16356017354)( https://gitee.com/lovely-hair/blog-img/raw/master/img/20211028231636.png )]

Test access http://localhost:3344/application/test/master

Test access http://localhost:3344/master/application-dev.yml

If the test accesses a configuration that does not exist, it will not be displayed, such as: http://localhost:3344/master/application-aaa.yml

client

Submit the newly created config-client.yml under the springcloud config folder of the local git warehouse to the code cloud warehouse:

Create a new springcloud-config-client-3355 module and import dependencies

<!--config-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-start -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Create application.yml and bootstrap.yml configuration files under resources

bootstrap.yml is a system level configuration

# System level configuration
spring:
  cloud:
    config:
      name: config-client # The resource name that needs to be read from git without suffix
      profile: dev
      label: master
      uri: http://localhost:3344

application.yml is a user level configuration

# User level configuration
spring:
  application:
    name: springcloud-config-client

Create ConfigClientController.java under the controller package for testing

@RestController
public class ConfigClientController {

    @Value("${spring.application.name}")
    private String applicationName; //Get microservice name

    @Value("${eureka.client.service-url.defaultZone}")
    private String eurekaServer; //Get Eureka services

    @Value("${server.port}")
    private String port; //Get the port number of the server


    @RequestMapping("/config")
    public String getConfig(){
        return "applicationName:"+applicationName +
         "eurekaServer:"+eurekaServer +
         "port:"+port;
    }
}

Main startup class

@SpringBootApplication
public class ConfigClient {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClient.class,args);
    }
}

Test:

Start the server ConfigServer3344 and then the client ConfigClient

visit: http://localhost:8201/config/

Small case

Create config-dept.yml and config-eureka.yml locally and submit them to the code cloud warehouse

config-dept.yml

spring:
    profiles:
     active: dev
---
server:
  port: 8001

# Configuration of mybatis
mybatis:
#  Scan package
  type-aliases-package: com.fafa.springcloud.pojo
#  mybatis configuration file (if config location is used here, you will be prompted that it cannot be found)
  configuration-properties: classpath:mybatis/mybatis-config.xml
#  Mapping profile for mybatis
  mapper-locations: classpath:mybatis/mapper/*.xml
#  Hump naming on
  configuration:
    map-underscore-to-camel-case: true

#spring configuration
spring:
  profiles: dev
  application:
    # The three service names should be consistent
    name: springcloud-config-dept-dev
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db01?userUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root

# Eureka configuration: configure the service registry address
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    # Modify the default description information on Eureka
    instance-id: springcloud-provider-dept-8001
    # Display the ip address (the specific one is not localhost, but false by default)
    prefer-ip-address: true

# info configuration
info:
  # Name of the project
  app.name: fafa-springcloud
  # Company name
  company.name: School of software engineering, Hebei Petroleum Vocational and Technical University
  
---
server:
  port: 8001

# Configuration of mybatis
mybatis:
#  Scan package
  type-aliases-package: com.fafa.springcloud.pojo
#  mybatis configuration file (if config location is used here, you will be prompted that it cannot be found)
  configuration-properties: classpath:mybatis/mybatis-config.xml
#  Mapping profile for mybatis
  mapper-locations: classpath:mybatis/mapper/*.xml
#  Hump naming on
  configuration:
    map-underscore-to-camel-case: true

#spring configuration
spring:
  profiles: test
  application:
    # The three service names should be consistent
    name: springcloud-config-dept-test
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db02?userUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root

# Eureka configuration: configure the service registry address
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    # Modify the default description information on Eureka
    instance-id: springcloud-provider-dept-8001
    # Display the ip address (the specific one is not localhost, but false by default)
    prefer-ip-address: true

# info configuration
info:
  # Name of the project
  app.name: fafa-springcloud
  # Company name
  company.name: School of software engineering, Hebei Petroleum Vocational and Technical University

config-eureka.yml

spring:
    profiles:
     active: dev

---
server:
  port: 7001
  
# spring configuration
spring:
    profiles: dev
    application: 
        name: sringcloud-config-eureka-dev

# Eureka configuration
eureka:
  instance:
    # Instance name of Eureka server
    hostname: eureka7001.com
  client:
    # Indicates whether to register yourself in Eureka registry first (this module itself is a server, so it is not required)
    register-with-eureka: false
    # Fetch registry: false indicates that you are the registry, and the of the client is changed to true
    fetch-registry: false
    service-url:
      #Override Eureka's default port and access path -- > http://localhost:7001/eureka/
      # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # Cluster (Association): 7001, 7002, 7003
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      
---
server:
  port: 7001
  
# spring configuration
spring:
    profiles: test
    application: 
        name: sringcloud-config-eureka-test

# Eureka configuration
eureka:
  instance:
    # Instance name of Eureka server
    hostname: eureka7001.com
  client:
    # Indicates whether to register yourself in Eureka registry first (this module itself is a server, so it is not required)
    register-with-eureka: false
    # Fetch registry: false indicates that you are the registry, and the of the client is changed to true
    fetch-registry: false
    service-url:
      #Override Eureka's default port and access path -- > http://localhost:7001/eureka/
      # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      # Cluster (Association): 7001, 7002, 7003
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

Create a new springcloud-config-eureka-7001 module and copy the contents under the original springcloud-eureka-7001 module to this module.

1. Clear the application.yml configuration of this module and create a bootstrap.yml connection remote configuration

spring:
  cloud:
    config:
      name: config-eureka # Profile name in warehouse
      label: master
      profile: dev
      uri: http://localhost:3344

2. Add spring cloud config dependency in pom.xml

<!--config-->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-config -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

3. Main startup

@SpringBootApplication
@EnableEurekaServer //The startup class of EnableEurekaServer server can accept others to register~
public class ConfigEurekaServer_7001 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigEurekaServer_7001.class,args);
    }
}

4. Test

Step 1: start Config_Server_3344, and visit http://localhost:3344/master/config-eureka-dev.yml test

Part II: start configurekaserver_ 7001, access http://localhost:7001/ test

If the above figure is displayed, it is successful

Create a new springcloud-config-dept-8001 module and copy the contents of springcloud-provider-dept-8001

Similarly, import the spring cloud config dependency, clear application.yml, create a new bootstrap.yml configuration file, and configure

spring:
  cloud:
    config:
      name: config-dept
      label: master
      profile: dev
      uri: http://localhost:3344

Main startup class

@SpringBootApplication
@EnableEurekaClient //Automatically register in Eureka after the service starts!
@EnableDiscoveryClient //Service discovery~
@EnableCircuitBreaker /
public class ConfigDeptProvider_8001 {
    public static void main(String[] args) {
        SpringApplication.run(ConfigDeptProvider_8001.class,args);
    }

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

Attention · if it appears here

Action: Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean

Please add the following code in application.yaml

Test:

As shown in the picture, it is success. Sprinkle flowers at the end!!!

Posted by ashutosh.titan on Sat, 30 Oct 2021 09:22:20 -0700