Detailed explanation of spring cloud and Git online configuration

SpringCloud

How to learn at this stage?

Three tier architecture + MVC
    
Frame:
    Spring IOC AOP
    SpringBoot,New generation JavaEE Development standard, automatic assembly
    modularization~  all in one,The code has not changed~
    
Four core issues of microservice architecture?
    1.There are many services. How can clients access them
    2.So many services? How do services communicate?
    3.So many services? How to manage?
    4.What if the service hangs up?
    
Solution:
    SpringCloud Ecology! SpringBoot
    
    1.SpringCloud NetFlix One stop solution!
    	api Gateway, zuul assembly
    	Feign --- HttpClient --- Http Communication mode, synchronization, blocking
    	Service registration discovery: Eureka
    	Fuse mechanism: Hystrix
    	. . . . . . 
    
    2.Apache Dubbo Zookeeper Semi automatic, need to integrate others!
    	API: No, find a third-party component or implement it yourself
    	Dubbo
    	Zookeeper
    	No: with the help of Hystrix
    	Dubbo This plan is not perfect~
    
    3.SpringCloud Alibaba One stop solution! Simpler
    	
    New concept: Service Grid~Server Mesh
    	istio
    
    All changes are inseparable from their ancestors
    	1.API
    	2.HTTP,RPC
    	3.Registration and discovery
    	4.circuit breaker
    

Note: this part is about spring cloud Netflix that has stopped maintenance. It can be compared with spring cloud Alibaba in a similar way.

1. 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? Describe the pitfalls you encountered in project development (microservice shortcomings)

1.7. What are the micro service technology stacks you know? Please list one or two

1.8. eureka and zookeeper can provide the functions of service registration and discovery. Please tell us the difference between the two?

...

2. Overview of microservices

2.1. What is micro service

What is micro service? 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:

​ Generally speaking, microservice architecture is an architectural mode, or architectural style. It advocates dividing 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. Each service is built around specific business and can be independently deployed to the production environment. In addition, unified and centralized service management system should be avoided as far as possible. For a specific service, appropriate language and tools should be selected 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;

Some people may think that the official words are too harsh. Let's understand from the technical dimension:

​ 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, and one business 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 and has its own independent database.

2.2. Microservices and microservice architecture

Microservices

It emphasizes the size of the service. A certain point of the event he focuses on 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 or modules in the IDEA

IDEA Used in tools Maven Developed independent small Module,It specifically uses SpringBoot The development of a small module, professional things to professional modules to do, a module to do this thing
 The emphasis is on individual, and each individual completes a specific task or function!

Microservice architecture

A new form of architecture, proposed by Martin Fowler in 2014

Microservice architecture is an architecture model, which advocates dividing 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, and lightweight communication mechanism is adopted 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 language and tools should be selected to build it according to the business context.

2.3 advantages and disadvantages of microservices

advantage

  • Single responsibility principle
  • Each business requirement or code is small enough to be understood;
  • The development is simple and the development efficiency is improved. A service may be dedicated to only one thing;
  • Microservices can be developed independently by a small team consisting of 2-5 developers;
  • Microservices are loosely coupled and functionally meaningful services, which are independent in both development and deployment stages;
  • 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. Value can be realized without cooperation;
  • Microservices allow you to take advantage of the latest technologies
  • Microservices are just the code of business logic 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

Disadvantages:

  • 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
  • Inter service communication cost
  • Data consistency
  • System integration test
  • Performance monitoring

2.4 what are the micro service technology stacks?

Microservice entry Landing technology
Service development SpringBoot,Spring,SpringMVC
Service configuration and management Archaius of Netflix and Diamond of Alibaba
Service registration and discovery Eureka, Consul, Zookeeper, etc
Service call Rest,RPC,gRPC
Service fuse Hystrix, Envoy, etc
load balancing Ribbon, Nginx, etc
Service interface call (simplified tool for client to call service) Feign et al
Message queue Kafka, RabbitMQ, ActiveMQ, etc
Service configuration center management SpringCloudConfig, Chef, etc
Service routing (API gateway) Zuul et al
Service monitoring Zabbix, Nagios, Metrics, specifier, etc
Full link tracking Zipkin, Brave, Dapper, etc
Service deployment Docker, OpenStack, Kubernetes, etc
Data flow operation development package Spring cloud stream (encapsulating sending and receiving messages with Redis, Rabbit, Kafka, etc.)
Event message bus SpringCloud Bus

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 micro service architectures used by major IT companies?

  • Ali: dubbo + HFS
  • JD: JSF
  • Sina: Motan
  • Dangdang DubboX
  • ......

3. Comparison of micro Service Frameworks

Function point / service framework Netflix/SpringCloud Motan gRPC Thrift Dubbo/DubboX
Functional positioning Complete microservice framework RPC framework, but it integrates ZK or consult to realize basic service registration / discovery in cluster environment RPC framework RPC framework Service Framework
Support Rest Yes, Ribbon supports a variety of pluggable serialization options no no no no
Support RPC no Yes (Hession2) yes yes yes
Support multiple languages Yes (Rest form)? no yes yes no
load balancing Yes (server zuul + client Ribbon), zuul service, dynamic routing, cloud load balancing, Eureka (for middle tier servers) Yes (client) no no Yes (client)
Configure services Netflix Archaius, spring cloudconfig server centralized configuration Yes (provided by zookeeper) no no no
Service call chain monitoring Yes (zuul). Zuul provides edge services and API gateways no no no no
High availability / fault tolerance Yes (server side Hystrix + client Ribbon) Yes (client) no no Yes (client)
Typical application cases Netflix Sina Google Facebook
Community activity high commonly high commonly Maintenance resumed after 2017, after 5 years of interruption
Learning difficulty secondary low high high low
Rich documents high commonly commonly commonly high
other Spring cloud bus brings more management endpoints to our applications Support downgrade Netflix is developing and integrating gRPC internally IDL definition There are many companies practicing

3. Spring cloud getting started overview

3.1 what is spring cloud

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

SpringCloud, based on SpringBoot, provides a set of microservice solutions, including service registration and discovery, configuration center, full link monitoring, service gateway, load balancing, fuse and other components. In addition to the highly abstract encapsulation of open-source components based on NetFlix, there are also some selection neutral open-source components.

Taking advantage of the development convenience of SpringBoot, SpringCloud cleverly simplifies the development of distributed system infrastructure. SpringCloud provides developers with some tools to quickly build distributed systems, including configuration management, service discovery, fuse, routing, micro agent, event bus, global lock, decision-making campaign, distributed session and so on. They can use the development style of SpringBoot to achieve one click Startup and deployment.

Spring cloud does not make wheels repeatedly. It just combines the relatively mature service frameworks developed by various companies and can stand the actual test. It is repackaged through the SpringBoot style, shielding the complex configuration and implementation principles. Finally, it leaves a set of distributed system development kit that is easy to understand, deploy and maintain for developers.

SpringCloud is a one-stop solution under the distributed microservice architecture. It is a collection of landing technologies of various microservice architectures, commonly known as microservices.

3.2 relationship between SpringCloud and SpringBoot

  • SpringBoot focuses on developing individual micro services quickly and easily.
  • 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 between microservices: configuration management, service discovery, fuse, routing, micro agent, event bus, global lock, decision-making campaign, distributed session and so on.
  • SpringBoot can be used independently of SpringCloud to develop projects, but SpringCloud cannot be separated from SpringBoot and belongs to dependency
  • 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

Currently mature Internet Architecture: application service splitting + message oriented middleware

2. Comparison between Dubbo and spring cloud

You can see the community activity

https://github.com/dubbo

https://github.com/spring-cloud

result:

Dubbo Spring
Service registry Zookeeper Spring Cloud NetFlix Eureka
Service invocation mode RPC REST API
Service monitoring Dubbo-monitor Spring Boot Admin
Fuse imperfect Spring Cloud Netflix Hystrix
Service gateway nothing Spring Cloud Netflix Zuul
Distributed configuration nothing Spring Cloud Config
Service tracking nothing Spring Cloud Sleuth
Message bus nothing Spring Cloud Bus
data stream nothing Spring Cloud Stream
Batch task nothing Spring Cloud Task

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 invocation, 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 one contract, and there is no strong dependence at the code level, which is more appropriate in the microservice environment emphasizing rapid evolution.

Difference between brand machine and assembly machine

Obviously, the function of spring cloud is more powerful and covers a wider range than Dubbo. As a fist project of spring, it can also be perfectly integrated with other spring projects such as Spring Framework, Spring Boot, Spring Data and Spring Batch, which are very important for microservices. The microservice architecture built by Dubbo is like assembling a computer. We have a high degree of freedom of choice in all links, but the final result is likely to be dim because of the poor quality of a memory, which is always worrying. However, if you are an expert, these are not problems; Spring cloud is like a brand machine. Under the integration of Spring Source, it has done a lot of compatibility tests to ensure that the machine has higher stability. However, if you want to reuse things other than original components, you need to have a sufficient understanding of its foundation.

Community support and renewal

Most importantly, Dubbo stopped updating for about five years, although it was restarted in July 2017. For the new needs of technological development, developers need to expand and upgrade themselves (for example, Dangdang made DubboX), which is obviously not suitable for many small and medium-sized software organizations that want to adopt the micro service architecture. Small and medium-sized companies do not have such a strong technical ability to modify the Dubbo source code + a complete set of surrounding solutions. Not every company has been tested by Alibaba's Daniel + real online production environment.

Design pattern + micro service splitting idea

Summary:

Dubbo, the once popular open source RPC service framework in China, made many users happy after restarting maintenance, but at the same time, it also welcomed some voices of doubt. With the rapid development of Internet technology, can Dubbo keep up with the times? What are the advantages and differences between Dubbo and spring cloud? Will there be any measures to ensure the subsequent update frequency of Dubbo?

Liu Jun, one of the main persons in charge of development and maintenance

Liu Jun, senior R & D Engineer of Alibaba middleware, led several release plans after Dubbo restart and maintenance, focusing on high-performance RPC framework and micro service related fields. He was responsible for the R & D and guidance of Netease koala RPC framework for internal use, and participated in the design and development process of service governance platform, distributed tracking system, distributed consistency framework and so on.

The problem areas to be solved are different: Dubbo is positioned as an RPC framework, and the goal of spring cloud is 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
  • Circuit Breakers
  • Distributed messaging
  • ......

3.5 where is spring cloud

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

The version number of this thing is a little special

Spring Cloud It is a large-scale comprehensive project composed of many sub projects. Each sub project has different release rhythm and maintains its own release version number. Spring Cloud Through a list of resources BOM(Bill of Materials)To manage the sub project list of each version. In order to avoid confusion with the release number of subprojects, all are named instead of version number.
The naming method of these version names adopts the name of London underground station, and corresponds to the chronological order of versions according to the order of alphabet, such as the earliest Release edition: Angel,the second Release edition: Brixton,And then Camden,Dalston,Edgware,At present, it corresponds to the version by time.

Reference books:

4. Spring cloud project learning

4.1 General introduction

  • We will use a Dept Department module as a general case of microservices. The Consumer consumer (Client) calls the services provided by the Provider (Server) through REST.
  • Recall the previous knowledge of Spring, Spring MVC, MyBatis and so on...
  • Review of Maven's subcontracting module architecture
A simple Maven The module structure is as follows:
    
--- app-parent: A parent item( app-parent)Aggregate many subprojects( app-util,app-dao,app-web...)
    |-- pom.xml
    |
    |-- app-core
    ||----pom.xml
    |
    |-- app-web
    ||----pom.xml
    ......

A parent project has multiple sub modules and sub modules

MicroServiceCloud has three sub modules under its parent Project for the first time

  • Microservicecloud API [encapsulated overall entity / interface / public configuration, etc.]
  • microservicecloud-provider-dept-8001 [service provider]
  • microservicecloud-consumer-dept-80 [serving consumers]

Do it!

4.2. Spring cloud version selection

https://start.spring.io/actuator/info

Selection of various component technologies in spring cloud:

The Red Cross indicates the technology that is worth learning but not recommended. This learning document mainly focuses on SpringCloud Netflix
Below is the most used component technology
The picture data is January 2020

4.3. Establishment of Rest learning environment: Service Provider

  1. Create a common maven parent project, springcloud, and import pom dependencies

    <?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.kuang</groupId>
        <artifactId>springcloud</artifactId>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>springcloud-api</module>
            <module>springcloud-provider-dept-8001</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.13.2</junit.version>
            <lombok.version>1.18.22</lombok.version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <!--SpringCloud Dependence of-->
                <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>2021.0.2</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--SpringBoot-->
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-dependencies</artifactId>
                    <version>2.6.7</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--database-->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>8.0.28</version>
                </dependency>
                <!--data source-->
                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid</artifactId>
                    <version>1.2.9</version>
                </dependency>
                <!--SpringBoot starter-->
                <!--mybatis starter-->
                <dependency>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                    <version>2.2.2</version>
                </dependency>
                <!--Logs and tests-->
                <dependency>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-core</artifactId>
                    <version>1.2.11</version>
                </dependency>
                <!--junit-->
                <dependency>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                    <version>${junit.version}</version>
                </dependency>
                <!--lombok-->
                <dependency>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                    <version>${lombok.version}</version>
                </dependency>
                <!--Log4j-->
                <dependency>
                    <groupId>log4j</groupId>
                    <artifactId>log4j</artifactId>
                    <version>1.2.17</version>
                </dependency>
            </dependencies>
        </dependencyManagement>
    
    </project>
    
  2. Create a new sub module springcloud API in the parent project and import the sub module dependencies

    <?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.kuang</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>springcloud-api</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <!--Current Module The dependency you need. If the parent dependency has a version configured, you don't need to write it here-->
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    
  3. Create a new database db01 and a new table dept, as shown in the figure below

  4. The new entity class Dept corresponds to the database

    @Data
    @NoArgsConstructor
    @Accessors(chain = true) //Chain writing
    public class Dept implements Serializable { //Dept entity class, orm mysql--dept class, table relation mapping
    
        private Long deptno; //Primary key
        private String dname;
    
        //This data is the field of which database exists ~ micro service. A service corresponds to a database, and the same information may exist in different databases
        private String db_source;
    
        public Dept(String dname){ //constructor 
            this.dname = dname;
        }
    
        /*
        Chain writing:
            Dept dept = new Dept();
    
            dept.setDeptNo(11).setDname('ssss').setDb_source('001');
    
         */
    
    }
    
  5. Create a new sub module springcloud-provider-dept-8001 in the parent project and import dependencies

    <?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.kuang</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>springcloud-provider-dept-8001</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <!--We need to get the entity class, so we need to configure it api module-->
            <dependency>
                <groupId>com.kuang</groupId>
                <artifactId>springcloud-api</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <!--junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <!--test-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-test</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--jetty-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jetty</artifactId>
            </dependency>
            <!--Hot deployment tool-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
    
        </dependencies>
    
    </project>
    
  6. Create a new spring configuration file, mybaits configuration file and mapper configuration file. The structure is as follows

  7. The contents of the configuration file are as follows:

    application.yml

    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      application:
        name: springcloud-provider-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    

    mybatis-config.xml

    <?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">
    
    <configuration>
        <settings>
            <!--Enable L2 cache-->
            <setting name="cacheEnabled" value="true"/>
        </settings>
    </configuration>
    

    DeptMapper.xml

    <?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">
    
    <mapper namespace="com.kuang.springcloud.dao.DeptDao">
    
        <insert id="addDept" parameterType="Dept">
            insert into db01.dept (dname, db_source)
            values (#{dname},DATABASE());
        </insert>
    
        <select id="queryDeptById" resultType="Dept" parameterType="Long">
            select * from db01.dept where deptno = #{deptno};
        </select>
    
        <select id="queryAll" resultType="Dept">
            select * from db01.dept;
        </select>
    
    </mapper>
    
  8. New mapper (dao) layer, service layer and controller layer are constructed as follows

  9. The contents of interface and class files are as follows:

    DeptDao

    @Mapper
    @Repository
    public interface DeptDao {
    
        public boolean addDept(Dept dept);
    
        public Dept queryDeptById(Long id);
    
        public List<Dept> queryAll();
    
    }
    

    DeptService

    public interface DeptService {
    
        public boolean addDept(Dept dept);
    
        public Dept queryDeptById(Long id);
    
        public List<Dept> queryAll();
    
    }
    

    DeptServiceImpl

    @Service
    public class DeptServiceImpl implements DeptService{
    
        @Autowired
        private DeptDao deptDao;
    
        @Override
        public boolean addDept(Dept dept) {
            return deptDao.addDept(dept);
        }
    
        @Override
        public Dept queryDeptById(Long id) {
            return deptDao.queryDeptById(id);
        }
    
        @Override
        public List<Dept> queryAll() {
            return deptDao.queryAll();
        }
    }
    

    DeptController

    //Provide Restful service!
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptService deptService;
    
        @PostMapping("/dept/add")
        public boolean addDept(Dept dept){
            return deptService.addDept(dept);
        }
    
        @GetMapping("/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return deptService.queryDeptById(id);
        }
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll(){
            return deptService.queryAll();
        }
    }
    
  10. Write the startup class at the same level as the controller, service and dao folders

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

4.4. Establishment of Rest learning environment: serving consumers

  1. Create a new sub module springcloud-consumer-dept-80 in the parent project and import dependencies

    <?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.kuang</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>springcloud-consumer-dept-80</artifactId>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <!--Entity class+web-->
        <dependencies>
            <dependency>
                <groupId>com.kuang</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 tool-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
            </dependency>
        </dependencies>
    
    </project>
    
  2. Create a new profile application yml

    server:
      port: 80
    
  3. Create a new configuration class configbean Java, get the RestTemplate and inject it into the Bean

    @Configuration
    public class ConfigBean { //@Configuration -- spring applicationContext.xml
    
        @Bean
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
    }
    
  4. Create a new consumer interface, deptconsumercontroller java

    @RestController
    public class DeptConsumerController {
    
        //Understanding: consumers should not have a service layer~
        //RestFul RestTemplate...  For us to call directly! Register in Spring
        //(url, entity: map, class < T > responsetype)
        @Autowired
        private RestTemplate restTemplate;//Provide a variety of convenient methods to access remote http services, and a simple restful service template~
    
        private static final String REST_URL_PREFIX = "http://localhost:8001";
    
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept){
            return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
        }
    
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list(){
            return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
        }
    
    }
    
  5. Create a new consumer startup class DeptConsumer_80.java

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

4.5 general process of using different technologies in spring cloud

1,Import dependency
2,Write configuration file
3,Turn on this function @Enable...
4,Configuration class

5. Eureka service registration and discovery

5.1. What is Eureka

  • Eureka: how?
  • Netflix followed the AP principle when designing Eureka
  • Eureka is a sub module of Netflix, that is, one of the core modules. Eureka is a REST based service, which is used to locate services to realize cloud middle tier service discovery and failover. 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 call configuration file. The function is similar to Dubbo's Registration Center, such as Zookeeper;

5.2 principle explanation

  • Basic structure of Eureka
    • Spring cloud encapsulates the Eureka module developed by NetFlix to realize service registration and discovery (compared with Zookeeper)
    • Eureka adopts the C-S architecture design. Eureka server is the server of service registration function. It is the service registration center
    • Other micro services in the system. The client using Eureka connects to Eureka server and maintains a heartbeat connection. In this way, the maintenance personnel of the system can monitor the normal operation of each micro service in the system through EurekaServer, and some other modules of spring cloud (such as Zuul) can find other micro services in the system through EurekaServer and perform relevant logical operations;
    • Comparison with Dubbo architecture
    • Eureka consists of two components: Eureka Server and Eureka Client.
    • Eureka Server provides service registration service. 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 available 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 Eureka Server (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 90 seconds)
  • Three roles
    • Eureka Server: provides service registration and discovery. zookeeper
    • Service Provider: registers its own service in Eureka so that consumers can find it.
    • Service Consumer: the Service Consumer obtains the registered service list from Eureka to find the consumer service.

Self protection mechanism: better to die than to live

  • When EurekaServer node loses too many clients in a short time (network partition failure may occur), the node will enter self-protection mode. Once in this mode, EurekaServer will protect the information in the service registry and will not delete the data in the service registry (that is, it will not log off any microservices). When the network fault recovers, EurekaServer node will automatically exit the self-protection mode.

5.3 Eureka implementation code

  1. Create a new sub module springcloud-eureka-7001 and import 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.7.RELEASE</version>
    </dependency>
    <!--actuator Improve monitoring information-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  2. Create a new profile application yml

    server:
      port: 7001
    
    #Eureka configuration
    eureka:
      instance:
        hostname: localhost #Instance name of Eureka server
      client:
        register-with-eureka: false #Indicates whether to register yourself with the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    
  3. Create a new startup class EurekaServer_7001.java, set EurakeServer annotation

    //After startup, access http://localhost:7001/
    @SpringBootApplication
    @EnableEurekaServer //The startup class of EnableEurekaServer server can accept others to register~
    public class EurekaServer_7001 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer_7001.class,args);
        }
    }
    
  4. Add build code to the parent dependency to solve the problem of invalid info

    <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <goals>
                                <goal>build-info</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
  5. Import Eureka dependency in the server module springcloud-provider-dept-8001

    <!--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.7.RELEASE</version>
    </dependency>
    <!--actuator Improve monitoring information-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
  6. Create a new profile application yml

    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      application:
        name: springcloud-provider-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://localhost:7001/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-8001 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    #Info configuration, invalid, create a separate build info Properties solution, pay attention to the format
    info:
      app-name: kuangshen-springcloud
      company-name: blog.kuangstudy.com
    
  7. Create a new info configuration file meta-inf / build info properties

    build.app_name=kuangshen-springcloud
    build.company_name=blog.kuangstudy.com
    
  8. In the server's controller file, deptcontroller Configure a new method in Java to obtain the specific information of the registered micro service

    //Provide Restful service!
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptService deptService;
    
        //Get some configuration information and get specific micro services!
        @Autowired
        private DiscoveryClient client;
    
        @PostMapping("/dept/add")
        public boolean addDept(Dept dept){
            return deptService.addDept(dept);
        }
    
        @GetMapping("/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return deptService.queryDeptById(id);
        }
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll(){
            return deptService.queryAll();
        }
    
        //Register the micro service and get some messages
        @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 and applicationName
            List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
    
            for (ServiceInstance instance : instances) {
                System.out.println(
                        instance.getHost()+"\t"+
                        instance.getPort()+"\t"+
                        instance.getUri()+"\t"+
                        instance.getServiceId()
                );
            }
    
            return this.client;
        }
    }
    
  9. Add EurekaClient and DiscoveryClient annotations to the server's startup class

    //Startup class
    @SpringBootApplication
    @EnableEurekaClient //Automatically register in Eureka after the service starts!
    @EnableDiscoveryClient //Service discovery~
    public class DeptProvider_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProvider_8001.class,args);
        }
    }
    
  10. First run springcloud-eureka-7001, then run springcloud-provider-dept-8001. The main interface is as follows. You can click to view the relevant information of the server

  11. visit http://localhost:7001/dept/discovery You can view the details of the micro service, and the terminal will output the details

5.3. Eureka cluster environment configuration

Structural diagram:

Code demonstration:

  1. Modify the interface configuration under Disk C, enter the folder C:\Windows\System32\drivers\etc\hosts, and add different URLs at the end of the file to map to the localhost interface

  2. Create two new sub modules, springcloud-eureka-7002 and springcloud-eureka-7003, with a structure similar to that of springcloud-eureka-7001

    Startup class

    //After startup, access http://localhost:7001/
    @SpringBootApplication
    @EnableEurekaServer //The startup class of EnableEurekaServer server can accept others to register~
    public class EurekaServer_7001 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer_7001.class,args);
        }
    }
    =======================================
    //After startup, access http://localhost:7002/
    @SpringBootApplication
    @EnableEurekaServer //The startup class of EnableEurekaServer server can accept others to register~
    public class EurekaServer_7002 {
        public static void main(String[] args) {
            SpringApplication.run(EurekaServer_7002.class,args);
        }
    }
    =======================================
    //After startup, access http://localhost:7003/
    @SpringBootApplication
    @EnableEurekaServer //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);
        }
    }
    

    configuration file

    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 the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    #######################################
    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 the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7003.com:7003/eureka/
    #######################################
    server:
      port: 7003
    
    #Eureka configuration
    eureka:
      instance:
        hostname: eureka7003.com #Instance name of Eureka server
      client:
        register-with-eureka: false #Indicates whether to register yourself with the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/
    

    The dependency is the same as springcloud-eureka-7001

    <!--Guide Package-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    
    </dependencies>
    
  3. Modify the service provider's configuration file to publish it to three Eureka

    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      application:
        name: springcloud-provider-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-8001 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    #Info configuration, invalid, create a separate build info Properties solution, pay attention to the format
    info:
      app-name: kuangshen-springcloud
      company-name: blog.kuangstudy.com
    
  4. Run three eurekas and one service provider. Two of the Eureka interfaces are as follows. It can be seen that each Eureka can see the other two eurekas

5.4 comparison of Zookeeper

Review CAP principles

RDBMS(Mysql,Oracle,sqlServer)===> ACID

NoSQL(redis,mongdb)===> CAP

What is ACID?

  • A (Atomicity)
  • C (Consistency)
  • I (Isolation)
  • D (Durability)

What is CAP?

  • C (Consistency) strong Consistency
  • A (Availability)
  • P (Partition tolerance)

Three CP's and three CA's that cannot be satisfied

Core theory of CAP

  • A distributed system cannot meet the three requirements of consistency, availability and partition fault tolerance at the same time
  • According to the CAP principle, NoSQL database is divided into three categories: meeting the CA principle, meeting the CP principle and meeting the AP principle:
    • CA: single point cluster, which meets the requirements of consistency and availability, and generally has poor scalability (poor fault tolerance of P partition)
    • CP: A system that meets the requirements of consistency and partition fault tolerance. Generally, the performance is not particularly high (A, poor availability)
    • AP: a system that meets the requirements of availability and partition fault tolerance. Generally, it may have lower requirements for consistency (poor C consistency)

As a service registry, what's better about Eureka 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.

Since partition fault tolerance P must be guaranteed in distributed systems, we can only trade off between A and C.

  • Zookeeper guarantees CP;
  • Eureka guarantees AP;

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 accept that the service is directly down and unavailable. In other words, the service registration function requires higher availability than consistency. However zk, when the master node loses contact with other nodes due to network failure, the remaining nodes will be re elected as leaders. The problem is that the election leader takes too long, 30~120s, and the whole zk cluster is unavailable during the election, which leads to the paralysis of the registration service during the election. In the cloud deployment environment, zk cluster loses the master node due to network problems, which is a high probability event. Although the service can be restored eventually, the long-term unavailability of registration caused by long election time cannot be tolerated.

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, if the connection fails, Eureka's client will automatically switch to other nodes. As long as one Eureka is still there, the availability of the registration service can be guaranteed, but it is only found

The information may not be up-to-date. In addition, Eureka 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:

  1. Eureka no longer removes services that should expire because they haven't received a heartbeat for a long time from the registration list
  2. Eureka can still accept the registration and query requests of new services, but it will not be synchronized to other nodes (that is, ensure that the current node is still available)
  3. 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

Ribbon has been built in spring cloud starter Netflix Eureka client. Importing ribbon dependency will conflict.

6.1 introduction to Ribbon

Spring Cloud Ribbon is a set of client-side load balancing tools based on Netflix Ribbon.

In short, ribbon is an open source project released by Netflix. Its main function is to provide software load balancing algorithms and service calls on the client. Ribbon client component provides a series of perfect configuration items, such as connection timeout, Retry, etc. Simply put, it is to list all the machines behind the load balancer (LB) 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 easily use ribbon to implement a custom load balancing algorithm

GitHub document address: https://github.com/Netflix/ribbon

Note: Ribbon has now entered maintenance mode
Ribbon's function: LB load balancing, in short, is to evenly allocate users' requests to multiple services, so as to achieve the HA (high availability) of the system.

Common load balancing software includes Nginx, LVS, hardware F5, etc.

The difference between Ribbon local load balancing client and Nginx server load balancing:

Nginx is server load balancing. All client requests will be handed over to nginx, and then nginx will forward the requests. That is, load balancing is realized by the server.

Ribbon is a local (client) load balancing. When calling the micro service interface, it will obtain the registration information service list in the registry and cache it to the JVM local, so as to realize the RPC remote service call technology locally

Centralized LB

That is, an independent LB facility (which can be hardware, such as F5, or software, such as Nginx) is used between the service consumer and the service provider. The facility is responsible for forwarding the access request to the service provider through some policy

In process 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, which is just a class library integrated into the consumer process, through which the consumer obtains the address of the service provider.

Ribbon is actually a client component of software to realize load balancing. It can be used in combination with other clients that need requests. The combination with Eureka is just one example

Sketch Map:

6.2. Initial experience of Ribbon

  1. Don't rely on the import of epsilon rib 80 module, otherwise it will lead to a conflict in the import of epsilon rib 80 module

    <!--Eureka-->
    <!-- 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.7.RELEASE</version>
    </dependency>
    
  2. Add Eureka configuration in this module

    server:
      port: 80
    
    #Eureka configuration
    eureka:
      client:
        register-with-eureka: false #Do not register yourself with Eureka
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
  3. In the configuration class, add the @ LoadBalanced annotation to implement RestTemplate using configuration load balancing

    @Configuration
    public class ConfigBean { //@Configuration -- spring applicationContext.xml
    
        //Configure load balancing to implement RestTemplate
        @Bean
        @LoadBalanced //Ribbon
        public RestTemplate getRestTemplate(){
            return new RestTemplate();
        }
    
    }
    
  4. In the controller layer, deptconsumercontroller Change the access address to the service name in Java

    @RestController
    public class DeptConsumerController {
    
        //Understanding: consumers should not have a service layer~
        //RestFul RestTemplate...  For us to call directly! Register in Spring
        //(url, entity: map, class < T > responsetype)
        @Autowired
        private RestTemplate restTemplate;//Provide a variety of convenient methods to access remote http services, and a simple restful service template~
    
        //Ribbon, our address here should be a variable, accessed through the service name
        //private static final String REST_URL_PREFIX = "http://localhost:8001";
        private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
    
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept){
            return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
        }
    
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list(){
            return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
        }
    
    }
    
  5. Run three Eureka clusters and test the service providers and consumers

6.3. Use Ribbon to realize load balancing

  1. Create two new databases, db02 and db03, the same as db01

    CREATE DATABASE /*!32312 IF NOT EXISTS*/`db02` /*!40100 DEFAULT CHARACTER SET utf8 */;
    
    USE `db02`;
    
    /*Table structure for table `dept` */
    
    DROP TABLE IF EXISTS `dept`;
    
    CREATE TABLE `dept` (
      `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
      `dname` varchar(60) DEFAULT NULL,
      `db_source` varchar(60) DEFAULT NULL,
      PRIMARY KEY (`deptno`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Department table';
    
    /*Data for the table `dept` */
    
    insert  into `dept`(`deptno`,`dname`,`db_source`) 
    values (1,'Development Department','db02'),(2,'Ministry of Personnel','db02'),(3,'Finance Department','db02'),(4,'Marketing Department','db02'),(5,'Operation and maintenance department','db02');
    
    #######################################
    
    CREATE DATABASE /*!32312 IF NOT EXISTS*/`db03` /*!40100 DEFAULT CHARACTER SET utf8 */;
    
    USE `db03`;
    
    /*Table structure for table `dept` */
    
    DROP TABLE IF EXISTS `dept`;
    
    CREATE TABLE `dept` (
      `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
      `dname` varchar(60) DEFAULT NULL,
      `db_source` varchar(60) DEFAULT NULL,
      PRIMARY KEY (`deptno`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Department table';
    
    /*Data for the table `dept` */
    
    insert  into `dept`(`deptno`,`dname`,`db_source`) 
    values (1,'Development Department','db03'),(2,'Ministry of Personnel','db03'),(3,'Finance Department','db03'),(4,'Marketing Department','db03'),(5,'Operation and maintenance department','db03');
    
  2. The two service provider modules in Xinjiang, springcloud-eureka-8002 and springcloud-eureka-8003, are the same as springcloud-eureka-8001, import the same dependencies, and modify the configuration file to the corresponding database and interface

    pom.xml

    <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.7.RELEASE</version>
        </dependency>
        <!--actuator Improve monitoring information-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    
        <!--We need to get the entity class, so we need to configure it api module-->
        <dependency>
            <groupId>com.kuang</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    
    </dependencies>
    

    application.yml

    server:
      port: 8002
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      application:
        name: springcloud-provider-dept #The three service names are consistent
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-8002 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    #Info configuration, invalid, create a separate build info Properties solution, pay attention to the format
    info:
      app-name: kuangshen-springcloud
      company-name: blog.kuangstudy.com
    

    DeptMapper.xml

    <?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">
    
    <mapper namespace="com.kuang.springcloud.dao.DeptDao">
    
        <insert id="addDept" parameterType="Dept">
            insert into db02.dept (dname, db_source)
            values (#{dname},DATABASE());
        </insert>
    
        <select id="queryDeptById" resultType="Dept" parameterType="Long">
            select * from db02.dept where deptno = #{deptno};
        </select>
    
        <select id="queryAll" resultType="Dept">
            select * from db02.dept;
        </select>
    
    </mapper>
    

    The rest of the files are the same as the springcloud-provider-dept-8001 module with different names

  3. Run three eureka clusters, three service provider modules and one consumer module, visit the main interface of eureka 7001, and find two standby eureka pages and one service. After the service, there are three service providers to choose from

  4. After running the service consumer for many times, it is found that the service consumer accesses three service providers successively according to the polling algorithm (selected from the active service providers by default) (here, three different databases are used for simulation for observation)

  5. We can also use different algorithms to access the service provider, add @ Bean in the configuration class, rewrite the corresponding method and return; You can also create and write custom classes in the upper directory of the startup class, add the @ RibbonClient annotation to the startup class, and specify the corresponding custom class after the annotation. It will not be demonstrated here.

7. Feign load balancing

7.1 introduction

Feign is a declarative web service client, which makes it easier to call between microservices, similar to the controller calling service. Spring cloud inherits Ribbon and Eureka, and can provide a load balanced http client when using feign.

Just create an interface and add annotations!

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

  1. Microservice name [ribbon]
  2. Interface and notes [feign]

What can Feign do?

  • Feign aims to make it easier to write Java Http clients
  • The template + resthttp method is used to encapsulate the previous set of requests. 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, some client classes are usually encapsulated for each micro service to wrap the invocation of these dependent services. Therefore, Feign made further encapsulation on this basis and helped 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, and a Feign Annotation on it is enough.) 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

  • 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 call in a declarative way, which is elegant and simple.

7.2 code implementation

  1. Import feign dependency in entity class module

    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.7.RELEASE</version>
    </dependency>
    
  2. Create a new service layer interface DeptClientService in the entity class module springcloud API, add FeignClient annotation, and its value is the service provider

    @Component
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
    public interface DeptClientService {
    
        @GetMapping("/dept/get/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll();
    
        @PostMapping("/dept/add")
        public boolean addDept(Dept dept);
    
    }
    
  3. Create a new feign consumer module springcloud consumer dept feign, which is similar to the consumer module springcloud-consumer-dept-80. Only the controller layer and startup class are changed.

    Import Feign dependencies

    <!--feign-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
        <version>1.4.7.RELEASE</version>
    </dependency>
    

    Create a file named demarcontroller.submercontroller java

    @RestController
    public class DeptConsumerController {
    
        @Autowired
        private DeptClientService deptClientService;
    
        @RequestMapping("/consumer/dept/add")
        public boolean add(Dept dept){
            return this.deptClientService.addDept(dept);
        }
    
        @RequestMapping("/consumer/dept/get/{id}")
        public Dept get(@PathVariable("id") Long id){
            return this.deptClientService.queryById(id);
        }
    
        @RequestMapping("/consumer/dept/list")
        public List<Dept> list(){
            return this.deptClientService.queryAll();
        }
    
    }
    

    Start class FeignDeptConsumer_80.java

    @SpringBootApplication
    @EnableEurekaClient
    @EnableFeignClients(basePackages = {"com.kuang.springcloud"})
    public class FeignDeptConsumer_80 {
        public static void main(String[] args) {
            SpringApplication.run(FeignDeptConsumer_80.class,args);
        }
    }
    
  4. Start the eureka cluster, test the service providers and feign consumers, and the query can also be realized

8,Hystrix

Problems faced by distributed systems

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

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 a few 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 the failures and delays need to be isolated and managed to facilitate the failure of a single dependency, and the whole application or system cannot be cancelled.

​ We need to abandon the car‘

What is Hystrix

​ Hystrix is an open source library for dealing with delay and fault tolerance of distributed systems. In distributed systems, many dependencies inevitably fail to call, such as timeout and exception. Hystrix can ensure that in the case of a dependency failure, it will not lead to overall service failure, 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, so as to ensure that the thread of the service caller will not be occupied unnecessarily for a long time, Thus, the spread of faults in the distributed system and even avalanche are avoided.

What can I do

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

Official website information

http://github.com/Netflix/Hystrix/wiki

Sketch Map:

8.1 service fusing

What is it?

​ Fuse mechanism is a microservice link protection mechanism against 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. When it is detected that the microservice call response of the node is normal, the call link is restored. In the spring cloud framework, the fuse mechanism is implemented through hystrix. Hystrix will monitor the calls between microservices. When the failed calls reach a certain threshold, the default is 20 calls in 5 seconds, and the failure will start the fuse mechanism. The annotation of the fuse mechanism is @ HystrixCommand.

Implementation code:

  1. Create a new service provider, springcloud-provider-dept-hystrix-8001, which is the same as springcloud-provider-dept-8001. Add a hystrix dependency

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

    Modify profile

    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-hystrix-8001 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
        prefer-ip-address: true # true to display the ip address of the service~
    
  2. Override the controller layer deptcontroller Implementation of Hystrix service with Java

    //Provide Restful service!
    @RestController
    public class DeptController {
    
        @Autowired
        private DeptService deptService;
    
        @GetMapping("/dept/get/{id}")
        @HystrixCommand(fallbackMethod = "hystrixGet")
        public Dept get(@PathVariable("id") Long id){
            Dept dept = deptService.queryDeptById(id);
    
            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, null--@Hystrix")
                    .setDb_source("no this database in MySQL");
        }
    
    }
    
  3. Startup class adds support for Hystrix @ EnableHystrix

    //Startup class
    @SpringBootApplication
    @EnableEurekaClient //Automatically register in Eureka after the service starts!
    @EnableDiscoveryClient //Service discovery~
    @EnableHystrix //Add support for fusing. The new version includes enablercircuitbreaker
    public class DeptProviderHystrix_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProviderHystrix_8001.class,args);
        }
    }
    
  4. Start the Eureka cluster, hystrix service providers and consumers, visit Eureka first, and you can specify the service provider to display the ip address

  5. Use the consumer to query the information that does not exist in the database. If no error is found, the page displays the specified information

8.2 service degradation

​ Service degradation refers to the strategic degradation of some services and pages according to the current business conditions and traffic when the server pressure increases sharply, so as to release server resources and ensure the normal operation of core tasks.

What is service degradation
Service degradation refers to low priority processing of less important services. To put it bluntly, it is to give system resources to services with high priority as much as possible. Resources are limited and requests are unlimited. If the service is not degraded during the peak period of concurrency, on the one hand, it will certainly affect the performance of the overall service. If it is serious, it may lead to downtime and unavailability of some important services. Therefore, in the peak period, in order to ensure the availability of the core functions and services of the website, some services should be degraded.

It is a strategy used by consumers to deal with the non response of service providers.

Implementation code:

  1. Create a new service class deptclientservicefallbackfactory in the entity class module springcloud API Java, implement the FallbackFactory method, return DeptClientService, rewrite the method, and inject this class into @ Component in Spring

    //Demotion~
    @Component
    public class DeptClientServiceFallbackFactory implements FallbackFactory {
        @Override
        public DeptClientService create(Throwable cause) {
            return new DeptClientService() {
                @Override
                public Dept queryById(Long id) {
                    return new Dept()
                            .setDeptno(id)
                            .setDname("id=>"+id+"There is no corresponding information. The client provides degraded information. The service has been shut down now")
                            .setDb_source("no data~");
                }
    
                @Override
                public List<Dept> queryAll() {
                    return null;
                }
    
                @Override
                public boolean addDept(Dept dept) {
                    return false;
                }
            };
        }
    }
    
  2. Specify the class pointed to by fallbackFactory in the DeptClientService interface of the service layer in the springcloud API of the entity class module

    @Component
    @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)
    public interface DeptClientService {
    
        @GetMapping("/dept/get/{id}")
        public Dept queryById(@PathVariable("id") Long id);
    
        @GetMapping("/dept/list")
        public List<Dept> queryAll();
    
        @PostMapping("/dept/add")
        public boolean addDept(Dept dept);
    
    }
    
  3. Import dependencies in springcloud consumer dept feign

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.10.RELEASE</version>
    </dependency>
    
  4. In the configuration file application Start demotion feign. In YML Hystrix (different configuration for new version)

    server:
      port: 80
    
    #Enable degraded feign Hystrix (different configuration for new version)
    feign:
      circuitbreaker:
        enabled: true
    
    #Eureka configuration
    eureka:
      client:
        register-with-eureka: false #Do not register yourself with Eureka
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
  5. Start Eureka cluster and consumer springcloud consumer dept feign, and use consumers to access. If the service cannot be found, the scheduled content will be displayed without error.

8.3 simple comparison between service fusing and service degradation

Service fusing: at the service end, a service timeout or abnormality causes fusing and the fuse ~.

Service degradation: for the client ~, considering the request load of the whole website, 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). The overall service level has decreased, but it can be used anyway.

8.4. Dashboard flow monitoring

Control panel information:

  • How to see

    • seven colors of the spectrum

    • A circle

      Solid circle: there are two meanings. It represents the health of the instance through the change of color

      Its hea lt h decreases from green < yellow < orange < red

      In addition to the change of color, the size of the solid circle will also change according to the request flow of the instance. The larger the flow, the larger the solid circle. Therefore, through the display of the solid circle, we can quickly find fault instances and high pressure instances in a large number of instances.

    • frontline

      Curve: it is used to record the relative change of flow within 2 minutes. It can be used to observe the rising and falling trend of flow!

Implementation code:

  1. Create a monitoring page, springcloud consumer hystrix dashboard, and import hystrix and dashboard dependencies

    <!--Hystrix rely on-->
    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.10.RELEASE</version>
    </dependency>
    <!--Dashboard rely on-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        <version>2.2.10.RELEASE</version>
    </dependency>
    
  2. Create a new profile application yml

    server:
      port: 9001
    
    hystrix:
      dashboard:
        proxy-stream-allow-list: "localhost"
    
  3. Create a new startup class DeptConsumerDashboard_9001.java

    @SpringBootApplication
    @EnableHystrixDashboard //Turn on monitoring
    public class DeptConsumerDashboard_9001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptConsumerDashboard_9001.class,args);
        }
    }
    
  4. Put the service provider springcloud-provider-dept-hystrix-8001 into the monitoring panel, import hystrix and monitoring dependencies, and add a Servlet in the startup class

    <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        <version>2.2.10.RELEASE</version>
    </dependency>
    <!--actuator Improve monitoring information-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    
    //Startup class
    @SpringBootApplication
    @EnableEurekaClient //Automatically register in Eureka after the service starts!
    @EnableDiscoveryClient //Service discovery~
    @EnableHystrix //Add support for fusing. The new version includes enablercircuitbreaker
    public class DeptProviderHystrix_8001 {
        public static void main(String[] args) {
            SpringApplication.run(DeptProviderHystrix_8001.class,args);
        }
    
        //Add a Servlet
        public ServletRegistrationBean hystrixMetricsStreamServlet(){
            ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
            registrationBean.addUrlMappings("/actuator/hystrix.stream");
            return registrationBean;
        }
    }
    
  5. Start EurekaServer_7001,DeptProviderHystrix_8001 and DeptConsumerDashboard_9001 for testing

    • Access the Hystrix Dashboard panel

    • After querying the service provider, use the / hyactor page to view the service provider

    • Fill in the Dashboard page information according to the query page for monitoring

    • Finally, view the monitoring page

9. Zuul routing gateway

9.1 overview

What is Zuul?

​ Zuul includes two main functions of request routing 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 processing process of requests, 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 micro 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 website documents: https://github.com/Netflix/zuul

Zuul schematic diagram:

9.2 code implementation:

  1. Create a new springcloud-zuul-9527 module to increase dependency

    <!--Entity class+web-->
    <dependencies>
    
        <!--zuul rely on-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    
        <!--Hystrix rely on-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
        <!--Dashboard rely on-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    
        <!--feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    
        <!--Eureka-->
        <!-- 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.7.RELEASE</version>
        </dependency>
    
        <dependency>
            <groupId>com.kuang</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 tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>
    
  2. Create a new profile application YML, configure Zuul

    server:
      port: 9527
    
    spring:
      application:
        name: springcloud-zuul
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: zuul9527.com #Modify the default description information on eureka!
        hostname: "localhost" #Modify host name
        prefer-ip-address: true # true to display the ip address of the service~
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    
    
    #Info configuration, invalid, create a separate build info Properties solution, pay attention to the format
    info:
      app-name: kuangshen-springcloud
      company-name: blog.kuangstudy.com
    
    zuul:
      routes:
        mydept:
          serviceId: springcloud-provider-dept
          path: /mydept/**
      ignored-services: "*" #You can no longer use this path to access, ignored: ignore, hide all
      prefix: /kuang #Set uniform prefix when accessing
    
  3. Create a new startup class and start Zuul

    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy //Open Zuul
    public class ZuulApplication_9527 {
        public static void main(String[] args) {
            SpringApplication.run(ZuulApplication_9527.class,args);
        }
    }
    
  4. Start Eureka, provider8001 and zuul9527 for testing

Warning: repeated attempts to debug, modify springboot and springcloud versions, add interceptor configuration classes, increase ribbon time, modify configuration files and other operations in this part can not solve the problem that other services cannot be accessed through Zuul. It can only add Zuul to eureka and access Zuul services. No available solution has been found in this version. At present, only other methods can be used to realize the function of the gateway.

10. SpringCloud config distributed configuration (Git)

10.1 overview

Problems faced by distributed systems -- configuration files

Microservice means to split the business in a single application into a sub service. The granularity of each service is relatively small, so there will be a large number of services in the system. Because 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 microservice brings an application YML, isn't it crazy to modify hundreds of configuration files!

What is the spring cloud config distributed configuration center

​ SpringCloud Config provides centralized external configuration support for microservices in the microservice architecture, and the configuration server provides a centralized external configuration for all links of different microservice applications.

​ SpringCloud 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. git is used to configure the storage environment, which is helpful to configure the default version of the server. And the git client tool can be used to manage and access the configuration content conveniently.

What can spring cloud config distributed configuration center do

  • Centrally manage profiles
  • Different environments, different configurations, dynamic configuration updates, deployment by environment, such as / dev /test /prod /beta /release
  • The configuration is dynamically adjusted during operation. It is no longer necessary to write a configuration file on the machine where each service is deployed. 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 change of the configuration and apply the new configuration
  • Expose the configuration information in the form of REST interface

Integration of SpringCloud Config distributed configuration center and github

​ Since spring cloud config uses git to store configuration files by default (there are other ways, such as supporting SVN and local files), Git is the most recommended and the form of http/https access is used;

10.2. Git environment construction

  1. Registration code cloud Gitee account, login, and create a new warehouse springcloud config. The settings are shown in the figure below

  2. Download and install the latest version of Git. Right click under the Git local warehouse folder to open git bash here

  3. Enter the following command in git to see if it exists ssh file. If it exists, it will be d copied to the file directory and deleted after backup to ensure that it does not exist

    ~/.ssh
    
  4. Enter the following command in git and press enter three times in succession to generate ssh public key (the mailbox can be entered at will, just the key name. It is customary to enter the mailbox)

    ssh-keygen -t ed25519 -C "406623380@qq.com"
    

  5. Enter the following instructions to view the SSH key, add the public key in the code cloud settings / security settings / SSH public key, copy all the information of the public key here and set the title

    cat ~/.ssh/id_ed25519.pub
    

  6. Click clone / download copy ssh address on the front page of the code cloud project, and then enter the following command in git to clone the project

    git clone git@gitee.com:wydilearn/springcloud-config.git
    

    Enter yes to continue clone

  7. Enter the following four instructions to create a new application in the local warehouse The YML file is uploaded to the Gitee warehouse and displayed in the master branch

    git add .
    git status #You can view the newly created file
    git commit -m "first commit" #When submitting new documents, you can choose the name of this submission
    git push origin master #Upload files to the master branch
    

  8. The newly uploaded files can be viewed in the project of code cloud

10.3. Server connection Git configuration

  1. Import a cloud spring config dependent server configuration module

    <dependencies>
        <!--config-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-config-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
            <version>3.1.2</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Eureka-->
        <!-- 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.7.RELEASE</version>
        </dependency>
    </dependencies>
    
  2. Create a new profile application YML connects to the remote warehouse and obtains the https address of the warehouse in Gitee as the uri

    server:
      port: 3344
    spring:
      application:
        name: springcloud-config-server
        # Connect to remote warehouse
      cloud:
        config:
          server:
            git:
              uri: https://gitee.com/wydilearn/springcloud-config.git # https, not git
    
  3. Create a new startup class Config_Server_3344.java, enable server configuration

    @SpringBootApplication
    @EnableConfigServer //
    public class Config_Server_3344 {
        public static void main(String[] args) {
            SpringApplication.run(Config_Server_3344.class,args);
        }
    }
    
  4. Start the module for testing, and access the following three paths to access the files in Gitee warehouse

10.4 client connection and server access

  1. Create a new configuration file config client. Under the local springcloud config project yml

    spring:
      profiles:
        active: dev
        
    ---
    server:
      port: 8201
    #spring configuration
    spring:
      profiles: dev
      application:
        name: springcloud-provider-dept
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
    ---
    server:
      port: 8202
    #spring configuration
    spring:
      profiles: test
      application:
        name: springcloud-provider-dept
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
  2. Use Git to upload the configuration file to the Gitee project, which is similar to the previous file upload operation

  3. Create a new client configuration module springcloud-config-client-3355 in the IDEA. The import dependency is slightly different from the server module dependency

    <dependencies>
        <!--config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--Eureka-->
        <!-- 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.7.RELEASE</version>
        </dependency>
    </dependencies>
    
  4. Create two new configuration files application YML and bootstrap yml

    bootstrap.yml

    # System level configuration
    spring:
      cloud:
        config:
          uri: http://localhost:3344 # connect to the local service and get the information from Gitee through the local service
          name: config-client #The resource name that needs to be read from git without suffix
          profile: dev #Which production environment in the file
          label: master #Which branch http://localhost:3344/master/config-client-dev.yml
    

    application.yml

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

    No port is configured at this time. The default is dev port 8201. You can set the port yourself

  5. Create a new controller layer file configclientcontroller Java get the configuration file in Gitee and show it

    @RestController
    public class ConfigClientController {
    
        @Value("${spring.application.name}")
        private String applicationName;
        @Value("${eureka.client.service-url.defaultZone}")
        private String eurekaServer;
        @Value("${server.port}")
        private String port;
        @RequestMapping("/config")
        public String getConfig(){
            return "applicationName:" + applicationName +
                   "eurekaServer:" + eurekaServer +
                   "port:" + port;
        }
    }
    
  6. New startup class ConfigClient_3355.java

    @SpringBootApplication
    public class ConfigClient_3355 {
        public static void main(String[] args) {
            SpringApplication.run(ConfigClient_3355.class,args);
        }
    }
    
  7. At the same time, start the server configuration module and the client configuration module for testing, and the configuration information can be read through the client module

10.5 remote configuration and actual test

  1. Create a new configuration file config Eureka. In the local git project YML and config-dept.yml and upload. Git upload operation is the same as before

    config-dept.yml

    spring:
      profiles:
        active: dev
    
    ---
    
    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      profiles: dev
      application:
        name: springcloud-config-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db02?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-8001 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
            
    ---
    
    server:
      port: 8001
    
    #mybatis configuration
    mybatis:
      type-aliases-package: com.kuang.springcloud.pojo
      config-location: classpath:mybatis/mybatis-config.xml
      mapper-locations: classpath:mybatis/mapper/*.xml
    
    #spring configuration
    spring:
      profiles: test
      application:
        name: springcloud-config-dept
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
        username: root
        password: 123456
    
    #Eureka's configuration, where is the service registered
    eureka:
      client:
        service-url:
          defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
      instance:
        instance-id: springcloud-provider-dept-8001 #Modify the default description information on eureka!
        hostname: localhost #Modify host name
    
    #Solve url filtering problem
    management:
      endpoints:
        web:
          exposure:
            include: "*"
    

    config-eureka.yml

    spring:
      profiles:
        active: dev
    
    ---
    
    server:
      port: 7001
    
    #spring configuration
    spring:
      profiles: dev
      application:
        name: springcloud-config-eureka
    
    #Eureka configuration
    eureka:
      instance:
        hostname: eureka7001.com #Instance name of Eureka server
      client:
        register-with-eureka: false #Indicates whether to register yourself with the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          # Cluster (Association):
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
          
    ---
    
    server:
      port: 7001
    
    #spring configuration
    spring:
      profiles: test
      application:
        name: springcloud-config-eureka
    
    #Eureka configuration
    eureka:
      instance:
        hostname: eureka7001.com #Instance name of Eureka server
      client:
        register-with-eureka: false #Indicates whether to register yourself with the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          # Cluster (Association):
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
          
    ---
    
    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 the eureka registry
        fetch-registry: false #If fetch registry is false, it indicates that it is the registry
        service-url: #Monitoring page~
          # Stand alone: defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
          # Cluster (Association):
          defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
    
  2. Create a new springcloud-config-eureka-7001 module with the same content as springcloud-eureka-7001, import dependencies, and create a new configuration file application YML and bootstrap yml

    <!--Guide Package-->
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-eureka-server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <!--config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    
    </dependencies>
    

    application.yml

    spring:
      application:
        name: springcloud-config-eureka-7001
    

    bootstrap.yml

    spring:
      cloud:
        config:
          name: config-eureka
          label: master
          profile: dev
          uri: http://localhost:3344
    
  3. Create a new springcloud-config-dept-8001 module with the same content as springcloud-provider-dept-8001. Import dependencies and create an application YML and bootstrap yml

    <dependencies>
    
        <!--Hystrix rely on-->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    
        <!--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.7.RELEASE</version>
        </dependency>
        <!--actuator Improve monitoring information-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    
        <!--We need to get the entity class, so we need to configure it api module-->
        <dependency>
            <groupId>com.kuang</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--test-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <!--Hot deployment tool-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    
        <!--config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    
    </dependencies>
    

    application.yml

    spring:
      application:
        name: springcloud-config-dept-8001
    

    bootstrap.yml

    spring:
      cloud:
        config:
          name: config-dept
          label: master
          profile: test
          uri: http://localhost:3344
    
  4. Start springcloud-config-server-3344, springcloud-config-eureka-7001 and springcloud-config-dept-8001 to test. It is found that the service is registered in Eureka and the database can be queried through the service

11. SpringCloud Netflix mind map

Tags: Spring Cloud

Posted by idris on Sat, 14 May 2022 17:54:19 +0300