【 微服务场景模拟 】

首先,我们需要模拟一个服务调用的场景。方便后面学习微服务架构

建表:

CREATE DATABASE IF NOT EXISTS springcloud CHARACTER SET utf8;
USE springcloud;

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(32) DEFAULT NULL,
  `password` varchar(32) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` int(11) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `created` date DEFAULT NULL,
  `updated` date DEFAULT NULL,
  `note` varchar(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO tb_user VALUES(null,"yang1","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang2","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang3","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang4","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang5","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang6","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang7","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang8","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang9","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang10","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang11","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang12","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang13","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang14","1234561","y1",11,1,20180828,20190101,20190101,"1");
INSERT INTO tb_user VALUES(null,"yang15","1234561","y1",11,1,20180828,20190101,20190101,"1");

1、创建父工程(聚合工程)

创建 maven 工程:
在这里插入图片描述

填写项目信息:
在这里插入图片描述

修改 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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.ys.demo</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <modules>
        <module>user-service</module>
    </modules>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </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>Finchley.SR1</spring-cloud.version>
        <mybatis.starter.version>1.3.2</mybatis.starter.version>
        <mapper.starter.version>2.0.2</mapper.starter.version>
        <mysql.version>5.1.32</mysql.version>
        <pageHelper.starter.version>1.2.3</pageHelper.starter.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>
            <!-- 通用Mapper启动器 -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${mapper.starter.version}</version>
            </dependency>
            <!-- mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

在这里插入图片描述

删除 src 目录

2、服务提供者

我们新建一个项目,对外提供查询用户的服务。

选中 父工程:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

添加依赖:

<?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.ys.demo</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.ys.demo</groupId>
    <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>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>

</project>

新建配置文件:application.yml

server:
  port: 8081
spring:
  application:
    name: user-service
  datasource:
    url: jdbc:mysql://yangnanxi.cn:3306/springcloud
    username: yang
    password: 123456
    hikari:
      maximum-pool-size: 30
      minimum-idle: 10

新建启动类:UserServiceApplication

package cn.ys.user;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;

@SpringBootApplication
@MapperScan("cn.ys.user.mapper")
public class UserServiceApplication {

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

}

编写实体类:User

package cn.ys.user.pojo;

import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

@Table(name = "tb_user")
@Data
public class User {

    @Id
    @KeySql(useGeneratedKeys = true)
    private Long id;

    private String userName; // 用户名

    private String password; // 密码

    private String name; // 姓名

    private Integer age; // 年龄

    private Integer sex; // 性别,1 男性; 2 女性

    private Date birthday; // 出生日期

    private Date created; // 创建日期

    private Date updated; // 更新日期

    private String note; // 备注

}

IDEA 安装 lombok 插件:
在这里插入图片描述

编写 mapper :UserMapper

package cn.ys.user.mapper;

import cn.ys.user.pojo.User;
import tk.mybatis.mapper.common.Mapper;

public interface UserMapper extends Mapper<User> {
}

编写 service :UserService

package cn.ys.user.service;

import cn.ys.user.mapper.UserMapper;
import cn.ys.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.selectByPrimaryKey(id);
    }

}

报错:
在这里插入图片描述
解决方法:
Alt + Enter
在这里插入图片描述

编写 controller:UserController

添加一个对外查询的接口:

package cn.ys.user.controller;

import cn.ys.user.pojo.User;
import cn.ys.user.service.UserService;
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("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id){
        return userService.queryById(id);
    }

}

项目结构:
在这里插入图片描述

启动并测试:

启动项目,访问接口:http://localhost:8081/user/7

在这里插入图片描述

3、服务调用者

创建工程

在这里插入图片描述
在这里插入图片描述

与上面类似,这里不再赘述,需要注意的是,我们调用 user-service 的功能,因此不需要 mybatis 相关依赖了。

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>cloud-demo</artifactId>
        <groupId>cn.ys.demo</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.ys.demo</groupId>
    <artifactId>consumer-demo</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

</project>

编写代码

首先在启动类中注册 RestTemplate

package cn.ys;

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

@SpringBootApplication
public class ConsumerApplication {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

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

}

实体类 User

package cn.ys.consumer.pojo;

import lombok.Data;
import java.util.Date;

@Data
public class User {

    private Long id;

    private String userName; // 用户名

    private String password; // 密码

    private String name; // 姓名

    private Integer age; // 年龄

    private Integer sex; // 性别,1 男性; 2 女性

    private Date birthday; // 出生日期

    private Date created; // 创建日期

    private Date updated; // 更新日期

    private String note; // 备注

}

编写 controller

package cn.ys.consumer.controller;

import cn.ys.consumer.pojo.User;
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;
import org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping("consumer")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("{id}")
    public User queryById(@PathVariable("id") Long id ){
        String url = "http://localhost:8081/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    }

}

启动测试:

在这里插入图片描述

在下面 方框中启动:
在这里插入图片描述

因为我们没有配置端口,那么默认就是8080,我们访问:http://localhost:8080/consumer/1

在这里插入图片描述

一个简单的远程服务调用案例就实现了。

有没有问题?

简单回顾一下,刚才我们写了什么:

  • use-service:一个提供根据 id 查询用户的微服务
  • consumer-demo:一个服务调用者,通过 RestTemplate 远程调用 user-service

流程如下:

在这里插入图片描述

存在什么问题?

  • 在 consumer 中,我们把 url 地址硬编码到了代码中,不方便后期维护
  • consumer 需要记忆 user-service 的地址,如果出现变更,可能得不到通知,地址将失效
  • consumer 不清楚 user-service 的状态,服务宕机也不知道
  • user-service 只有 1 台服务,不具备高可用性
  • 即便 user-service 形成集群,consumer 还需自己实现负载均衡

其实上面说的问题,概括一下就是分布式服务必然要面临的问题:

  • 服务管理
    • 如何自动注册和发现
    • 如何实现状态监管
    • 如何实现动态路由
  • 服务如何实现负载均衡
  • 服务如何解决容灾问题
  • 服务如何实现统一配置

以上的问题,我们都将在 SpringCloud 中得到答案。

猜你喜欢

转载自blog.csdn.net/weixin_42112635/article/details/88293474