[Spring Cloud Basics] + [Spring Cloud Development Course Query Project] project

Spring Cloud Foundation

Microservices Basics

Introduction

  • Basic concepts, design and splitting principles of microservices
  • The relationship between microservices and Spring Cloud
  • Common components and functions of microservices
  • Course inquiry case basic introduction, system architecture design and interface design
  • Build Spring Cloud projects by modules
  • Course service integration, service registration and discovery
  • Integrate Feign to implement inter-service calls
  • Network management integration and development, and access services
  • Introduce the fuse and downgrade of the service, and conduct practical drills

Microservices Basics

  • What are microservices

  • Characteristics of Microservices

  • Pros and Cons of Microservices

  • Two Schools of Microservices

    • SpringCloud
    • Dubbo
  • Microservice split

  • microservice extension

  • Important modules of microservices

What are microservices

  • Pain points of monolithic applications
    • Inefficient deployment
    • Teamwork development costs are high
    • Poor system availability
  • What is servitization
    • Transform local method calls in traditional stand-alone applications into remote method calls generated by RPC and HTTP
    • Split the module out of the monolithic application
    • The user module can be independently developed, tested, launched, operated and maintained, and can be handed over to a dedicated team without coupling with the main module
  • an architectural style
  • Develop a single application as a suite of small services, each of which runs in its own process and communicates with each other through a lightweight mechanism, usually an HTTP resource API
  • These services are built around this business functionality and can be deployed independently through a fully automated deployment mechanism
  • Centralized management of these services is minimized (such as docker-related technologies), each service can be written in a different programming language, and can use a different data storage technology
  • A series, a part (choose a part of suitable components)

Characteristics of Microservices

  • Components are delivered as a service
  • product not project
  • Lightweight communication, independent process
  • Decentralized governance, decentralized governance
  • fault-tolerant design
  • will bring about adjustments to the organizational structure

Pros and Cons of Microservices

  • advantage:

    • The service is simple, easy to learn and use, relatively easy to maintain

    • Independent deployment, flexible expansion

    • Rich technology stack

  • shortcoming:

    • Operation and maintenance costs are too high
    • interface may not match
    • code may be duplicated
    • Increased architectural complexity

Two modules of microservice

  • Spring Cloud: many sub-projects

  • Dubbo: A high-performance, lightweight open source java RPC framework, which provides three core capabilities

    • Interface-Oriented Remote Method Invocation
    • Intelligent fault tolerance and load balancing
    • Service auto-registration and discovery
  • The capabilities provided by Dubbo are a subset of SpringCloud

core components Dubbo Spring Cloud
Service Registry Zookeepper Spring Cloud Netflix Eureka
Service call method RPC REST API
service gateway none Spring Cloud Netflix Zuul
breaker imperfect Spring Cloud Netflix Hystrix
distributed configuration none Spring Cloud Config
service tracking none Spring Cloud Sleuth
message bus none Spring Cloud Bus
data flow none Spring Cloud Stream
batch task none Spring Cloud Task
  • Communication protocol comparison
    • RPC vs REST
    • The RPC service provider and the call interface are too dependent
    • Dubbo service is sensitive to the platform and is difficult to reuse easily
  • document quality
    • Dubbo has Chinese documents
    • The volume of Spring Cloud documents is large, and more of them are biased toward integration. For more in-depth usage, you still need to view the detailed documents of its integration components.
  • Metaphor: Assembling a computer, a brand machine
  • You need to choose according to your own research and development level and stage

Splitting of Microservices

  • When to perform servitization
    • Phase 1: As long as the goal is to quickly develop and validate ideas
    • Further add more new features to attract more target users
    • At the same time, there are more than 10 developers. At this time, it is time to consider service splitting
  • Cases not suitable for splitting
    • Small team with weak technical foundation
    • The traffic is not high, the pressure is small, and the business changes are not big
    • Low-latency, high-concurrency systems that are sensitive to latency
  • Two Postures of Servicing Split
    • vertical split
    • horizontal split
    • Comprehensive Business Analysis

service extension

  • X axis - horizontal copy

  • Y axis - functional decoupling

  • Z axis - data partition

  • Automatically scale on demand

    • According to the degree of CPU responsibility, specific time (such as weekends), the queue length of message middleware, specific business rules, forecasts, etc. to resolve whether to expand

    • Automatically allocates a new service instance, improving availability

    • Improved scalability (automatically reduce servers after Double Eleven)

    • Optimum utilization and cost savings

Important modules of microservices

  • service description
  • registration center
  • service framework
  • load balancing
  • Circuit breakers and downgrades
  • gateway

Summarize

Spring Cloud develops course query function

Project overall introduction

  • Introduction to Spring Cloud
  • overall project design
  • Course List Module Development
  • Course price module development
  • Service registration and discovery Eureka
  • Calling Feign between services
  • Load Balancing Ribbon
  • Fuse Hystrix
  • Gateway Zuul
  • overall test
  • project summary

Introduction to Spring Cloud Core Components

  • Introduction to Spring Cloud

    • A mature microservice framework, positioned to provide developers with tools to quickly build distributed systems
  • core components

    core components Spring Cloud
    Service Registry Spring Cloud Netflix Eureka
    Service call method REST API、Feign、 Ribbon
    service gateway Spring Cloud Netflix Zuul
    breaker Spring Cloud Netflix Hystrix

Project technical design

  • Project Introduction

  • interface design

    • curriculum schedule
    • single course price
    • Consolidate course listings and prices
  • system data flow
    insert image description here

  • data sheet

    insert image description here

Create a new multi-module project

Course List Module Development

Annotations added above the mapper class

@Mapper
@Repository
public interface CourseMapper {
    
    
    @Select("SELECT * FROM course WHERE valid = 1")
    List<Course> findValidCourse();
}

Common Error Troubleshooting

When serializing, there must be Setter, Getter and toString methods in the class

# 实现自动映射,Mybatis 驼峰配置
mybatis.configuration.map_underscore-to-camel-case = true

Course price module development

The role and architecture of Eureka

  • Eureka service registration and discovery module

  • Why service registration and discovery are needed

    • IP change
    • difficult to maintain
    • Improve
  • architecture

    • Eureka Server

    • Eureka Client

Develop Eureka Server

  • Introducing Eureka

    • Introduce dependencies

      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
      </dependency>
      ...
      <!-- 表示SpringCloud的版本 -->
      <dependencyManagement>
      	<dependencies>
          	<dependency>
              	<groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-dependencies</artifactId>
                  <version>Greenwich.SR5</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
      </dependencyManagement>
      
    • configuration file

      spring.application.name=eureka-server
      server.port=8000
      eureka.instance.hostname=localhost
      #fetch-registry:获取注册表。不需要同步其他节点数据。
      eureka.client.fetch-registry=false
      #register-with-eureka代表是否将自己注册到Eureka Server,默认是true。
      eureka.client.register-with-eureka=false
      eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka/
      
    • start comment

      • Add on startup class@EnableEurekaServer

Perform Eureka Client transformation

 <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/

Some old versions also need to be added to the startup class @EnableEurekaClient

Use Feign to implement inter-service calls

  • Introduce dependencies

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
    
  • configuration file

    #openfeign消费的负载均衡后期再配
    
  • annotation

    //启动类的客户端
    @EnableFeignClients
    
  • Client (write the interface in the calling class (module), copy the controller method of the called service (module))

    package com.bennyrhys.course.client;
    
    import com.bennyrhys.entity.Course;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.GetMapping;
    
    import java.util.List;
    
    /**
     * 课程列表的Feign客户端
     */
    @FeignClient("course-list")
    public interface CourseListClient {
          
          
        @GetMapping("/course")
        List<Course> getList();
    }
    
  • Verify pom (automatically introduce dependencies of other services)

  • controller (the method of calling the course service in the price service)

  • verify

Using Ribbon to achieve load balancing

  • Two Types of Load Balancing

    • Client load balancing (Ribbon)

    • Server load balancing (Nginx)

  • load balancing strategy

    • RandomRule represents a random strategy
    • RoundRobinRule represents the round-robin strategy
    • ResponseTimeWeightedRule weighting, dynamically weighted according to the average response time of each Server
  • Configure different load balancing methods

    # Ribbon.NFLoadBanlancerRuleClassName
    # price服务调用course服务的负载均衡设置
    # openfeign消费的负载均衡
    course-list.ribbon.NFLoadBanlancerRuleClassName=com.netflix.loadbalancer.RoundRobinRule
    

Using Hystrix to implement circuit breakers

  • For example, getting user information is stuck, but the connection pool of the database has not been released. System crash, circuit breaker protection, if there is a problem in one place, it is guaranteed that it will not affect all unavailability and avoid the spread of faults

  • Introduce dependencies

    <!--        断路器 客户端-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
    
  • configuration

    #断路器 客户端(默认关闭)
    feign.hystrix.enabled=true
    
  • start comment

    @EnableCircuitBreaker
    
  • Circuit breaker implements class CourseListClientHystrix

    package com.bennyrhys.course.client;
    
    import com.bennyrhys.entity.Course;
    import java.util.ArrayList;
    import java.util.List;
    import org.springframework.stereotype.Component;
    
    /**
     * 描述:     断路器实现类
     */
    @Component
    public class CourseListClientHystrix implements CourseListClient{
          
          
    
        @Override
        public List<Course> getList() {
          
          
            List<Course> defaultCourses = new ArrayList<>();
            Course course = new Course();
            course.setId(1);
            course.setCourseId(1);
            course.setCourseName("默认课程");
            course.setValid(1);
            defaultCourses.add(course);
            return defaultCourses;
        }
    }
    
  • Indicates the circuit breaker class for calling the service

    /**
     * 课程列表的Feign客户端
     */
    @FeignClient(value = "course-list", fallback = CourseListClientHystrix.class)
    @Primary //防止调用服务的controller爆红线不好看
    public interface CourseListClient {
          
          
        @GetMapping("/course")
        List<Course> getList();
    }
    
  • circuit breaker effect

Integrate two services

  • Integrate course listings and course prices

  • Return entity CourseAndPrice

    Integer id;
    Integer courseId;
    String name;
    Integer price;
    
  • service

    @Override
        public List<CourseAndPrice> getCoursesAndPrice() {
          
          
            List<CourseAndPrice> courseAndPriceList = new ArrayList<>();
            List<Course> courses = courseListClient.courseList();
            for (int i = 0; i < courses.size(); i++) {
          
          
                Course course = courses.get(i);
                if (course != null) {
          
          
                    CoursePrice coursePrice = getCoursePrice(course.getCourseId());
                    CourseAndPrice courseAndPrice = new CourseAndPrice();
                    courseAndPrice.setPrice(coursePrice.getPrice());
                    courseAndPrice.setName(course.getCourseName());
                    courseAndPrice.setId(course.getId());
                    courseAndPrice.setCourseId(course.getCourseId());
                    courseAndPriceList.add(courseAndPrice);
                }
            }
            return courseAndPriceList;
        }
    }
    
  • accomplish

Realize the routing function through the gateway Zuul

  • two features

    • Signature verification, login verification redundancy problem

    • API Gateway allows routing of API requests (internal or external) to the correct address

  • integrated

    • Register yourself to the registration center of Eureka
    • Introduce dependencies
    • Configure routing address
  • Create a new mudle module sourse-zuul

  • Introduce dependencies

    <dependencies>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
      </dependencies>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
          </plugin>
        </plugins>
      </build>
    
  • configuration file

    spring.application.name=course-gateway
    server.port=9000
    logging.pattern.console=%clr(%d{${LOG_DATEFORMAT_PATTERN:HH:mm:ss.SSS}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}
    mybatis.configuration.map-underscore-to-camel-case=true
    eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
    
    #zuul.prefix=/bennyrhys
    zuul.routes.course-list.path=/list/**
    zuul.routes.course-list.service-id=course-list
    zuul.routes.course-price.path=/price/**
    zuul.routes.course-price.service-id=course-price
    
  • Start class annotation

    package com.bennyrhys.course;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.cloud.client.SpringCloudApplication;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    /**
     * 描述:     网关启动类
     */
    @EnableZuulProxy
    @SpringCloudApplication
    public class ZuulGatewayApplication {
          
          
    
        public static void main(String[] args) {
          
          
            SpringApplication.run(ZuulGatewayApplication.class, args);
        }
    }
    
  • Effect

Implement a gateway filter

  • pre filter runs before routing requests

  • The route filter can handle the actual route of the request

  • run filter after post route request

  • error If an error occurs while processing the request, the filter will run

  • Before filtering

    package com.bennyrhys.course.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    /**
     * 描述:     记录请求时间
     */
    @Component
    public class PreRequestFilter extends ZuulFilter {
          
          
    
        @Override
        public String filterType() {
          
          
            //过滤器的类型
            return FilterConstants.PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
          
          
            return 0;
        }
    
        @Override
        public boolean shouldFilter() {
          
          
            //是否启用过滤器
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
          
          
            RequestContext currentContext = RequestContext.getCurrentContext();
            currentContext.set("startTime", System.currentTimeMillis());
            System.out.println("过滤器已经记录时间");
            return null;
        }
    }
    
  • After filtering

    package com.bennyrhys.course.filter;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    /**
     * 描述:     请求处理后的过滤器
     */
    @Component
    public class PostRequestFilter extends ZuulFilter {
          
          
    
        @Override
        public String filterType() {
          
          
            return FilterConstants.POST_TYPE;
        }
    
        @Override
        public int filterOrder() {
          
          
            return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
          
          
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
          
          
            RequestContext currentContext = RequestContext.getCurrentContext();
            Long startTime = (Long) currentContext.get("startTime");
            long duration = System.currentTimeMillis() - startTime;
            String requestURI = currentContext.getRequest().getRequestURI();
            System.out.println("uri:" + requestURI + ",处理时长:" + duration);
            return null;
        }
    }
    

Guess you like

Origin blog.csdn.net/qq_45924975/article/details/129519113