The basic case

Section 1 Case Description

In this section, we will simulate a call between microservices in the usual way (we will further refine the case step by step using Spring Cloud components).

There is a function called “Interview Express” in the App. When job seekers open the interview express, they will make two-way matching according to the needs of enterprise clients. An operation is as follows: Start a scheduled task for the enterprise user, and match a certain number of candidates to the enterprise resource pool every day according to the employment conditions recorded by the enterprise. Then the system needs to check the matching candidates before sending them to the resource pool: The default status of the resume (public/Hidden) is displayed. If the default status of the resume has been set to “Hidden” by the candidate, the “Send” operation is not performed. “Automatic delivery function” in “automatic delivery micro service”, “resume status query function” in “resume micro service”, then it involves “automatic delivery micro service” call “resume micro service” resume query. In this scenario, the auto-delivery microservice is a service consumer and the resume microservice is a service provider.

Section 2 preparing the case database environment

Resume Basic information sheet R_resume

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for r_resume
-- ----------------------------
DROP TABLE IF EXISTS `r_resume`;
CREATE TABLE `r_resume` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sex` varchar(10) DEFAULT NULL COMMENT 'gender',
  `birthday` varchar(30) DEFAULT NULL COMMENT Date of birth,
  `work_year` varchar(100) DEFAULT NULL COMMENT 'Years of service',
  `phone` varchar(20) DEFAULT NULL COMMENT 'Mobile number',
  `email` varchar(100) DEFAULT NULL COMMENT 'email',
  `status` varchar(80) DEFAULT NULL COMMENT 'Current status',
  `resumeName` varchar(500) DEFAULT NULL COMMENT 'Resume name',
  `name` varchar(40) DEFAULT NULL,
  `createTime` datetime DEFAULT NULL COMMENT 'Creation date',
  `headPic` varchar(100) DEFAULT NULL COMMENT 'avatar',
  `isDel` int(2) DEFAULT NULL COMMENT 'Delete default value 0- Not deleted 1- Deleted',
  `updateTime` datetime DEFAULT NULL COMMENT 'Resume Update Time',
  `userId` int(11) DEFAULT NULL COMMENT 'user ID',
  `isDefault` int(2) DEFAULT NULL COMMENT 'Default resume 0- default 1- Non-default',
  `highestEducation` varchar(20) DEFAULT ' ' COMMENT 'Highest degree',
  `deliverNearByConfirm` int(2) DEFAULT '0' COMMENT 'Send attached resume confirmation 0- Confirmation required 1- No confirmation required',
  `refuseCount` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of resumes rejected',
  `markCanInterviewCount` int(11) NOT NULL DEFAULT '0' COMMENT 'Marked as number of interviews available',
  `haveNoticeInterCount` int(11) NOT NULL DEFAULT '0' COMMENT 'Number of interviews notified',
  `oneWord` varchar(100) DEFAULT ' ' COMMENT 'Introduce yourself in a sentence',
  `liveCity` varchar(100) DEFAULT ' ' COMMENT 'Residential City',
  `resumeScore` int(3) DEFAULT NULL COMMENT 'Resume score',
  `userIdentity` int(1) DEFAULT '0' COMMENT 'User Identity 1- Student 2- Worker',
  `isOpenResume` int(1) DEFAULT '3' COMMENT 'Talent Search - Open RESUME 0- Closed, 1- open, 2- Resume does not meet Posting criteria passive closed 3- Never set open resume'.PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2195388 DEFAULT CHARSET=utf8;
 
SET FOREIGN_KEY_CHECKS = 1;
Copy the code

Section 3 case engineering environment preparation

We constructed the engineering environment based on SpringBoot, and our engineering module relationship is as follows:

  1. Create a parent project lagou-parent
  2. Create a common module lagou-service-common project to provide data models, common classes, and components
  3. Build a resume micro service module lagou-service-resume project to complete CRUD and provide API interface
  4. Establish an automatic delivery microservice module lagou-service-autoDeliver to call the resume microservice module through the interface

The structure of the whole project is as follows:

3.1 Construct the lagou-parent project


      
<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 project package is poM -->
    <packaging>pom</packaging>
    <! -- Spring Boot parent boot dependency -->

    <! -- Spring Boot parent boot dependency -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6. RELEASE</version>
    </parent>
    <dependencies>
        <! - web depend on -- -- >
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <! -- Log dependency -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <! -- Test dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <! - lombok tools - >
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.4</version>
            <scope>provided</scope>
        </dependency>
        <! -- Actuator helps you monitor and manage Spring Boot apps -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <! -- Hot deployment -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <! Build plugins -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <encoding>utf-8</encoding>
                </configuration>
            </plugin>
            <! -- Package plugin -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
Copy the code

3.2 Public Services

  1. The name of the new Maven project is Lagou-service-common

  2. Import dependence

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>
Copy the code
  1. Create a POJO for your resume
@Data
@Entity
@Table(name="r_resume")
public class Resume {
    @Id
    private Long id; / / the primary key
    private String sex; / / gender
    private String birthday; / / birthday. }Copy the code

3.3 Resume micro services

This project carries on the query operation for the resume, and provides the query interface, queries the open state of a resume

Create a new module, lagou-service-resume, create routine CRUD operations, create Dao, service, Controller three layers, plus a startup program

ResumeDao

public interface ResumeDao extends JpaRepository<Resume.Long> {}Copy the code

ResumeService

public interface ResumeService {
    Resume findDefaultResumeByUserId(Long userId);
}
Copy the code

ResumeServiceImpl

@Service
public class ResumeServiceImpl implements ResumeService {

    @Autowired
    private ResumeDao resumeDao;

    @Override
    public Resume findDefaultResumeByUserId(Long userId) {
        Resume resume=new Resume();
        resume.setUserId(userId);
        resume.setIsDefault(1);
        Example<? extends Resume> example=Example.of(resume);
        returnresumeDao.findOne(example).get(); }}Copy the code

ResumeController

@RestController
@RequestMapping("/resume")
public class ResumeController {

    @Autowired
    private ResumeService resumeService;

    //http://localhost:8080/resume/openstate/1545133
    @GetMapping("/openstate/{userId}")
    public Integer findDefaultResumeState(@PathVariable Long userId){

        returnresumeService.findDefaultResumeByUserId(userId).getIsOpenResume(); }}Copy the code

LagouResumeApplication

@SpringBootApplication
@EntityScan("com.lagou.edu.pojo")
public class LagouResumeApplication {
    public static void main(String[] args) { SpringApplication.run(LagouResumeApplication.class, args); }}Copy the code

Application. Yml file

server:
  port: 8080
spring:
  application:
    name: lagou-service-resume

  datasource:
   driver-class-name: com.mysql.jdbc.Driver
   #url: jdbc:mysql://localhost:3306/lagou? useUnicode=true&characterEncoding=utf8
   url: jdbc:mysql://localhost:3306/lagou? useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
   username: root
   password: root

  jpa:
   database: MySQL
   show-sql: true
   hibernate:
    naming:
     physical-strategy:
      org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl Avoid converting hump names to underline names
Copy the code

3.4 Delivery Service

The delivery service is simply an interface to call the resume micro-service to complete the query

AutodeliverApplicaton

@SpringBootApplication
public class AutodeliverApplicaton {
    public static void main(String[] args) {
        SpringApplication.run(AutodeliverApplicaton.class,args);
    }
    // Use Resttemple to make a remote call, injecting the object first
    @Bean
    public RestTemplate getRestTemplete(a){
        return newRestTemplate(); }}Copy the code

AutoDeliverController

@RestController
@RequestMapping("/autodeliver")
public class AutoDeliverController {
    @Autowired
    private RestTemplate restTemplate;

    //http://localhost:8090/autodeliver/checkState/1545133
    @GetMapping("/checkState/{userId}")
    public Integer findResumeOpenState(@PathVariable Long userId){
        // Invoke the remote service --> resume microservice

        // Get the result directly
        Integer forObject = restTemplate.getForObject("http://localhost:8080/resume/openstate/" + userId, Integer.class); 
        returnforObject; }}Copy the code

application.yml

server:
  port: 8090
Copy the code

Section 4 Case code problem analysis

We call the resume status interface of the resume microservice using the RestTemplate in the automatic delivery microservice. What are the problems in a microservice distributed cluster environment? How to solve it?

Existing problems:

  • 1) In service consumers, we hard-coded THE URL address into the code, which is not convenient for later maintenance.
  • 2) The service provider has only one service. Even if the service providers form clusters, the service consumers still need to implement load balancing by themselves.
  • 3) Among service consumers, the status of service providers is not clear.
  • 4) When the service consumer invokes the service provider, if there is a fault, can it be found in time and not throw an exception page to the user?
  • 5) Is there room for optimization in RestTemplate? Can you play like Dubbo?
  • 6) How to realize the unified authentication of so many micro-services?
  • 7) It is troublesome to modify multiple configuration files every time! ?
  • 8)…

The problems mentioned above are some of the inevitable problems in microservices architecture:

  • 1) Service management: automatic registration and discovery, status supervision
  • 2) Service load balancing
  • 3) fuse
  • 4) Remote procedure call
  • 5) Gateway interception and route forwarding
  • 6) Unified certification
  • 7) Centralized configuration management, real-time automatic update of configuration information

Summary believe to see here, we have resonance. Isn’t this our normal CRUD? Then maintain an interface address written by others, according to the business to call, others jump, their own jump. A little better, can also do some logging, wechat push. Enterprise internal business out of the problem is not too big, hang up on the hang up. It is time to reverse this inexorable phenomenon

Basic demo code github.com/langkemaoxi…