Spring cloud -- Rest is called with RestTemplate

Posted by porto88 on Thu, 06 Jan 2022 02:10:23 +0100

Overview of microservices

1 what is micro service?

Microservice architecture is an architecture mode, or architecture style. Its length divides a single application into a group of small services. Each service runs in its own independent process. Services coordinate and configure with each other to provide final value for users. Services communicate with each other through lightweight communication mechanism (HTTP), Each service is built around a specific business and can be independently deployed to the production environment. In addition, a unified and centralized service management mechanism should be avoided as far as possible. For a specific service, an appropriate language and tool (Maven) should be selected 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.

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

  • Microservices

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

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

Microservice architecture is an architecture model. Its body length divides a single application into a group of small services. Services coordinate and cooperate with each other to provide final value for users. Each service runs in its own independent process, and lightweight communication mechanism = = (such as HTTP) 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, According to the business context, select the appropriate language and tool (such as Maven) = = to build it.

Advantages and disadvantages of microservices

advantage

The principle of single responsibility;

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

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

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

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

Microservices can be developed in different languages;

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

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

Microservices allow the use and integration of the latest technologies;

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

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

shortcoming

Developers have to deal with the complexity of distributed systems;
Multi service operation and maintenance is difficult. With the increase of services, the pressure of operation and maintenance is also increasing; System deployment dependency;
Inter service communication cost;
Data consistency;
System integration test problems; Performance and monitoring issues;

1, Spring cloud getting started overview

Relationship between SpringCloud and SpringBoot

  • SpringBoot focuses on the development of individual micro suits by KAISU
  • SpringCloud is a microservice coordination and management framework that focuses on the overall situation. It integrates and manages individual microservices developed by SpringBoot, and provides integrated services among microservices: configuration management, service discovery, circuit breaker, routing, proxy, event stack, global lock, decision-making campaign, distributed session, etc;
  • SpringBoot can be used independently of SpringCloud to develop projects, but SpringCloud is inseparable from SpringBoot and belongs to dependency relationship;
  • SpringBoot focuses on the rapid and convenient development of individual micro services, and SpringCloud focuses on the global service governance framework

Dubbo and spring cloud technology selection

  1. Distributed + service governance Dubbo
    The current mature Internet architecture, application service splitting + message middleware

  2. Comparison between Dubbo and spring cloud
    Take a look at community activity:

https://github.com/dubbo

https://github.com/spring-cloud

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

Spring cloud Download

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


Self study reference books:

SpringCloud Netflix Chinese Documentation: https://springcloud.cc/spring-cloud-netflix.html
SpringCloud Chinese API document (official document translation): https://springcloud.cc/spring-cloud-dalston.html
SpringCloud China Community: http://springcloud.cn/
SpringCloud Chinese website: https://springcloud.cc

2, Use steps

Create project

CREATE TABLE `dept` (
  `deptno` bigint NOT NULL AUTO_INCREMENT,
  `dname` varchar(255) NOT NULL,
  `dbsource` varchar(50) NOT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;



Parent dependency

<?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>org.example</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springcloud-api</module>
        <module>springcloud-provider-8001</module>
    </modules>

    <properties>
        <project.build.sourEncoding>UTF-8</project.build.sourEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
<!--    Packaging method-->
    <packaging>pom</packaging>

    <dependencyManagement>
        <dependencies>
<!--            springCloud rely on-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR12</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
<!--            springBoot rely on-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.12.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--            database-->

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.27</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.24</version>
            </dependency>
<!--            mybatis starter-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.0</version>
            </dependency>

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.10</version>
            </dependency>
<!--            junit-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency><!--            log4j-->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>2.12.1</version>
            </dependency>



        </dependencies>
    </dependencyManagement>

</project>

springcloud-api

Interface

package com.my.pojo;

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

import java.io.Serializable;

@Data
@NoArgsConstructor
@Accessors(chain = true)//Chain writing
public class Dept implements Serializable {//Entity classes need to inherit serialization classes and database table mappings
    private Long deptno;
    private String dname;

    //It indicates which database the data exists in. A service corresponds to a database. The same information may be in different databases
    private String dbsource;

    public Dept(String dname) {
        this.dname = dname;
    }
    /*
    Dept =dept = new Dept();

    dept.setDeptNo(11).setDname("sa").setDb_source("db01")
     */
}

pom

<?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>org.example</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 Dependence on your own needs,If the parent dependency is already configured,You don't need to write-->
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

</project>

springcloud-provider-8001 provider

pom

<?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>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

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

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
<!--        Entity class required,to configure api module-->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <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-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

mybatis-config

<?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>

application

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


Interface
DeptDao

import com.my.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

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

DeptService

import com.my.pojo.Dept;

import java.util.List;

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

DeptServiceImpl

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

import java.util.List;

@Service
public class DeptServiceImpl implements DeptService{
    @Autowired
    private DeptDao deptDao;
    @Override
    public boolean addDept(Dept dept) {
        return deptDao.addDept(dept);
    }

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

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

DeptController

import com.my.pojo.Dept;
import com.my.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

//Provide Restful services for external calls
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;

    @RequestMapping("/dept/add")
    public boolean add(@RequestBody Dept dept){
        return deptService.addDept(dept);
    }
    @GetMapping("/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id){
        return deptService.queryById(id);
    }
    @GetMapping("/dept/list")
    public List<Dept> list(){
        return deptService.queryAll();
    }
}


Startup class

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

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

    }
}

Mapper

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.my.dao.DeptDao">
    <insert id="addDept" parameterType="Dept">
        insert into dept (dname,dbsource) values (#{dname},DATABASE());
    </insert>
    <select id="queryById" parameterType="Long" resultType="Dept">
        select * from dept where deptno = #{deptno};
    </select>
    <select id="queryAll"  resultType="Dept">
        select * from dept ;
    </select>

</mapper>

springcloud-consumer-80 consumer

Inject the rest template into the container through the configuration class. After injection, you can easily access the remote http service through the RestTemplate, providing a simple restful service template

rely on

<?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>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

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

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
<!--    Consumers do not need to connect to the database, they only need entity classes and web-->
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--        Hot deployment-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

</project>

configuration file

server:
  port: 80

Configuration class

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

@Configuration
public class ConfigBean {//The configuration class is equivalent to ApplicationContext in Spring xml
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

controller


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

import java.util.List;
@RestController
public class DeptConsumerController {
    //The consumer does not have a service layer
    //RestTemplate calls directly to inject the template into spring
    @Autowired
    private RestTemplate restTemplate;//Three parameters: url, entity and class
    //It provides 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";
//     The url prefix requested by the provider is the same http://localhost:8001/dept/get?1


    @RequestMapping("/con/get/{id}")
    public Dept get(@PathVariable("id") Long id){
        //The request obtained in another module is get, so get is also used here
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);

    }
    @RequestMapping("/con/add")
    public boolean add(Dept dept){
        //The request obtained in another module is get, so get is also used here
        return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);

    }
    @RequestMapping("/con/list")
    public List<Dept> list(){
        //The request obtained in another module is get, so get is also used here
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);

    }

}


Startup class

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

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

Provider startup





The function of this annotation is to encapsulate the passed json format string to the parameter where the annotation is located, provided that the attribute name in json is consistent with the attribute name in the parameter.

Topics: Java Spring Cloud Microservices