SpringCloud-Mikroservice [Praktisch] | Dienstaufteilung und Remote-Aufruf

Inhaltsverzeichnis

1: Dienstaufteilung und Fernanruf

1. Leistungsaufteilung

2. Rufen Sie zwischen Diensten an

3. Anbieter und Verbraucher 


1: Dienstaufteilung und Fernanruf

1. Leistungsaufteilung

Was Sie bei der Aufteilung von Diensten beachten sollten

1. Einzelverantwortung: Entwickeln Sie nicht wiederholt dasselbe Geschäft für verschiedene Microservices.

2. Datenunabhängigkeit: Greifen Sie nicht auf die Datenbanken anderer Microservices zu;

3. Serviceorientiert: Stellen Sie Ihr Unternehmen als Schnittstelle für den Aufruf anderer Microservices bereit.

Fall: Übergeordnetes Projektcloud-demo, der Unterprojekt-Bestelldienst fragt die Bestellung basierend auf der ID ab und der Benutzerdienst fragt die Benutzertabelle basierend auf der ID ab

Schritt 1: Datenbanktabellen vorbereiten – Datenbanktrennung

tb_user-Tabelle der cloud_user-Datenbank

tb_order-Tabelle der cloud_order-Datenbank

Schritt 2: Cloud-Demo des übergeordneten Projekts – Projekttrennung

Verwenden Sie pom.xml hauptsächlich, um einige Versionsnummern anzugeben

<?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>cn.itcast.demo</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>1.0</version>
    <modules>
        <module>user-service</module>
        <module>order-service</module>
    </modules>

    <packaging>pom</packaging>
    <!--SpringBoot项目-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!--版本号-->
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR10</spring-cloud.version>
        <mysql.version>5.1.47</mysql.version>
        <mybatis.version>2.1.1</mybatis.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- springCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>
</project>

Schritt 3: Teilprojekt-Bestellservice

Projektstrukturverzeichnis:

pom.xml

<?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>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>order-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

PoJo-KlasseOrder

package cn.itcast.order.pojo;

import lombok.Data;

@Data
public class Order {
    private Long id;
    private Long price;
    private String name;
    private Integer num;
    private Long userId;
    private User user;
}

Benutzer der Pojo-Klasse

package cn.itcast.order.pojo;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

 Mapper-Schnittstelle

package cn.itcast.order.mapper;

import cn.itcast.order.pojo.Order;
import org.apache.ibatis.annotations.Select;

public interface OrderMapper {

    @Select("select * from tb_order where id = #{id}")
    Order findById(Long id);
}

Dienstaufruf-Mapper-Schnittstelle

package cn.itcast.order.service;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 4.返回
        return order;
    }
}

Controller ruft Service an

package cn.itcast.order.web;

import cn.itcast.order.pojo.Order;
import cn.itcast.order.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {

   @Autowired
   private OrderService orderService;

    @GetMapping("/{orderId}")
    // @RequestMapping("/order")  和@GetMapping("/{orderId}")等价于@GetMapping("/user/{orderId})
    public Order queryOrderByUserId(@PathVariable("orderId") Long orderId) {
        // 根据id查询订单并返回
        return orderService.queryOrderById(orderId);
    }
}

application.yml-Konfiguration

server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

Schritt 4: Teilprojekt Benutzerservice

Projektstrukturverzeichnis:

 pom.xml

<?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>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

Benutzer der Pojo-Klasse

package cn.itcast.order.pojo;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
    private String address;
}

 Mapper-Schnittstelle

package cn.itcast.user.mapper;

import cn.itcast.user.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {
    
    @Select("select * from tb_user where id = #{id}")
    User findById(@Param("id") Long id);
}

Dienstaufruf-Mapper-Schnittstelle

package cn.itcast.user.service;

import cn.itcast.user.mapper.UserMapper;
import cn.itcast.user.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public User queryById(Long id) {
        return userMapper.findById(id);
    }
}

Controller ruft Service an

package cn.itcast.user.web;

import cn.itcast.user.pojo.User;
import cn.itcast.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 路径: /user/110
     *
     * @param id 用户id
     * @return 用户
     */
    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id) {
        return userService.queryById(id);
    }
}

application.yml-Konfiguration

server:
  port: 8081
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
mybatis:
  type-aliases-package: cn.itcast.user.pojo
  configuration:
    map-underscore-to-camel-case: true
logging:
  level:
    cn.itcast: debug
  pattern:
    dateformat: MM-dd HH:mm:ss:SSS

Starten Sie diese beiden Server (die Startklassen beider Projekte müssen mit @MapperScan annotiert werden).

Auf die Bestellung wird separat zugegriffen und die Benutzerinformationen sind null.

Nur Benutzerzugriff

2. Rufen Sie zwischen Diensten an

Das vorherige Projekt wurde bereitgestellt. Sie können die Bestellinformationen „Bestellung“ allein anhand der ID überprüfen und Sie können die Benutzerinformationen „Benutzer“ überprüfen! Doch nun bitten Kunden darum, die Bestellvoraussetzungen zu prüfen und auch die Benutzerinformationen in Erfahrung zu bringen!

Anforderung: Geben Sie beim Abfragen der Bestellung anhand der Bestell-ID die Benutzerinformationen zurück, zu denen die Bestellung gehört. 

Analyse: Das Bestellmodul kann nur Bestellinformationen herausfinden, und das Benutzermodul kann nur Benutzerinformationen herausfinden; aber was Benutzer jetzt benötigen, ist, Benutzerinformationen während der Abfrage herauszufinden Bestellinformationen.

Daher müssen wir die Funktion des Bestellmoduls ändern, sodass wir beim Abfragen der Bestellinformationen auch gegenseitige Benutzerinformationen über die Benutzer-ID in den Bestellinformationen abfragen können.

Denken:Ist es möglich, das Bestellmodul direkt zu verwenden, um die Daten des Benutzermoduls zu überprüfen? Offensichtlich nicht, wir haben bereits das Entwicklungsgeschäft analysiert, das nicht wiederholt werden sollte; wir können nur Remote-Anrufe an Benutzer aus Bestellungen initiieren!

lösen:

①Tatsächlich werden die Benutzerinformationen über eine Linkadresse @GetMapping("/user/{id}) nach außen angezeigt. Über diese Linkadresse können Sie auf die Datenbank zugreifen und die Benutzerinformationen an den Browser übertragen.

② Wenn das Bestellmodul zu diesem Zeitpunkt eine Verbindungsanforderung des http-Protokolls ausgeben kann, kann es auch Benutzerinformationsdaten zurückgeben und diese dann mit den ursprünglichen Bestellinformationsdaten kombinieren, um die Anforderung zu erfüllen.

Nun also die Kernfrage: Wie sendet man HTTP-Anfragen im Java-Code des Bestellinformationsmoduls!

Spring bietet einRestTemplate-Klasse-Tool, um es zu vervollständigen! Die spezifischen Implementierungsschritte sind wie folgt:

Schritt 1: Registrieren Sie RestTemplate

Fügen Sie die RestTemplate-Klasse in die Startklasse OrderApplication ein!

package cn.itcast.order;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
    
    // 注册RestTemplate
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

Schritt 2: Der Dienst ruft RestTemplate remote auf

Rufen Sie die Methode getForObject() über diese RestTemplate-Klasse auf: Der erste Parameter ist die URL-Adresse und der zweite Parameter ist der Typ, der zurückgegeben werden soll.

package cn.itcast.order.service;

import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    // 注入RestTemplate
    @Autowired
    private RestTemplate restTemplate;

    public Order queryOrderById(Long orderId) {
        // 1.查询订单
        Order order = orderMapper.findById(orderId);
        // 2.发出请求查询用户信息
        String url = "http://localhost:8081/user/"+order.getUserId();
        User user = restTemplate.getForObject(url, User.class);
        // 3. 把用户信息封装到order
        order.setUser(user);
        // 4.返回
        return order;
    }
}

Zu diesem Zeitpunkt wird nur auf „Bestellung“ zugegriffen und Benutzerinformationen können angezeigt werden.

Zusammenfassung der Microservice-Aufrufmethoden

①Remote-Aufruf basierend auf der von RestTemplate initiierten http-Anfrage;

② Die HTTP-Anfrage für einen Remote-Anruf ist ein sprachunabhängiger Aufruf, solange Sie die IP-Adresse, den Port, den Schnittstellenpfad und die Anforderungsparameter der anderen Partei kennen.

3. Anbieter und Verbraucher 

DienstAnbieter: Ein Dienst, der von anderen Microservices in einem Unternehmen aufgerufen wird. (Stellen Sie Schnittstellen zu anderen Microservices bereit);

ServiceConsumer: Ein Service, der andere Microservices in einem Unternehmen aufruft. (Aufrufschnittstellen, die von anderen Microservices bereitgestellt werden);

Wer ist also der Anbieter des oben genannten Bestell- und Benutzerservices? Wer ist der Verbraucher?

Denken Sie: Service A ruft Service B auf und Service B ruft Service C auf. Welche Rolle spielt Service B also?

Dienst B ist im Verhältnis zu Dienst A ein Anbieter, und Dienst B ist im Verhältnis zu Dienst C ein Verbraucher. Dies ist relativ, sodass die Rolle eines Dienstes nicht in Unternehmen unterteilt werden kann.

Fassen Sie die Serviceabrufbeziehung zusammen

①Dienstanbieter: Macht die Schnittstelle verfügbar, die von anderen Microservices aufgerufen werden soll.

②Service-Consumer: Rufen Sie die von anderen Microservices bereitgestellte Schnittstelle auf.

③Die Rollen von Anbieter und Verbraucher sind tatsächlichrelativ;Ein Dienst kann ein Dienst am sein gleichzeitig Anbieter und Servicekonsumenten.

Supongo que te gusta

Origin blog.csdn.net/m0_61933976/article/details/133167625
Recomendado
Clasificación