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
-
data sheet
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
- Add on startup class
-
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; } }