01-Spring Cloud分布式开发-服务调用

 简介

微服务是系统架构上的一种设计风格,

主旨是将一个原本独立的系统拆分成多个小型服务,

这些小型服务都在各自独立的进程中运行.

服务之间通过基于HTTP的RESTful API进行通信协作.

 

每一个小型服务都围绕系统中某一项耦合度较高的业务功能进行构建,

并且每个服务都维护着自身的数据存储/业务开发/自动化测试案例以及独立部署机制.

 

使用微服务设计风格的原因:

  1. 不断扩大的需求使得单体应用变得越来越臃肿
  2. 单体应用系统部署在一个进程内,修改一个很小的功能会导致其他功能模块都需要重先部署, 从而影响其他功能的运行
  3. 随着系统的发展, 单体应用的维护成本会变得越来越大, 难以控制.

 

微服务设计风格的优势:

  1. 每个服务都运行在自己的进程内, 在部署上有稳定的边界, 服务之间互不影响.
  2. 可以更准确地评估每个服务的性能容量

去中心化:

去中心化管理数据 

去中心化可以让数据管理更加细致化, 用过采用更合适的技术让数据存储和性能达到最优

 

容错设计:

部分服务出现故障时, 不影响其他服务的正常运行

 

Spring Cloud是基于Spring Boot实现的微服务架构开发工具.

为微服务架构中涉及的配置管理/服务治理/断路器/智能路由/微代理/控制总线/全局锁/决策竞选/分布式会话/集群状态管理等操作提供了一种简单的开发方式

一. 搭建父工程

1.  选择一个简单的Maven工程模板进行父工程创建

 

 

 

 2.  进入工作空间, 打开Settings设置文件编码为UTF-8

 

 然后, 启用注解处理:

 

 3. pom.xml文件, 将pom文件修改为如下(很简单的)

将打包方式改为pom:

<properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <maven.compiler.source>1.8</maven.compiler.source>
  <maven.compiler.target>1.8</maven.compiler.target>
  <junit.version>1.7.2</junit.version>
  <log4j.version>1.2.17</log4j.version>
  <lombok.version>1.18.20</lombok.version>
  <mysql.version>5.1.47</mysql.version>
  <druid.version>1.2.6</druid.version>
  <mybatis.plus.boot.version>3.4.3.3</mybatis.plus.boot.version>
</properties>

 依赖管理, 导入需要的依赖(注意spring boot和spring cloud版本适配性, 其他依赖根据自行需要导入):

<dependencyManagement>
  <dependencies>
    <!-- spring boot 2.2.2 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>2.2.2.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <!-- spring cloud Hoxton.SR4 -->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Hoxton.SR4</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <!-- spring cloud alibaba 2.2.1.RELEASE -->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-alibaba-dependencies</artifactId>
      <version>2.2.1.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>${mysql.version}</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid-spring-boot-starter</artifactId>
      <version>${druid.version}</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
    </dependency>
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>${mybatis.plus.boot.version}</version>
    </dependency>
    <dependency>
      <groupId>org.junit.platform</groupId>
      <artifactId>junit-platform-commons</artifactId>
      <version>${junit.version}</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>${log4j.version}</version>
    </dependency>

  </dependencies>
</dependencyManagement>

 二. 创建model: cloud-commons

 1. 删除src目录, 新建Module, 创建一个通用包模块cloud-commons, 用于放置工程模块的公共代码

 

 2. 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>springcloud2021</artifactId>
        <groupId>com.huzz</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-commons</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.8</version>
        </dependency>
    </dependencies>

</project>

3. 现在在该模块下创建一个实体类包:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private Integer id;

    private String username;

    private String password;
}

再创建一个用于接口返回的通用实体:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult<T> {

    private String code;

    private T data;

    private String message;

    public CommonResult(String code, String message) {
        this(code, null, message);
    }
}

 三. 创建服务提供者: cloud-provider-user8001

 1. 在父工程下创建新的module:

 2. 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>springcloud2021</artifactId>
        <groupId>com.huzz</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-provider-user8001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <!-- 引入自己定义的通用包 -->
        <dependency>
            <groupId>com.huzz</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>
</project>

 3. 在src/main/resources下新建application.yml文件, 内容如下:

server:
  port: 8001

spring:
  application:
    name: cloud-user-service
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db21?useUicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

mybatis-plus:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.huzz.entity

 4. 写业务逻辑(controller, service, mapper. 和平时的一模一样)

UserController:

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping("/provider/user/create")
    public CommonResult create(@RequestBody User user) {
        int result = userService.create(user);
        return result > 0 ?
                new CommonResult(2000, "成功") : new CommonResult(5000, "失败");
    }

    @GetMapping ("/provider/user/find/{userId}")
    public CommonResult findUserById(@PathVariable("userId") Integer userId) {
        User user = userService.findUserById(userId);
        return user != null ?
                new CommonResult(2000, user,"成功") : new CommonResult(5000, "失败");
    }
}

UserServiceImpl:

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public int create(User user) {
        return userMapper.create(user);
    }

    @Override
    public User findUserById(Integer userId) {
        return userMapper.findUserById(userId);
    }
}

 UserMapper:

@Mapper
public interface UserMapper {
    /**
     * 新建记录
     * @param user
     * @return
     */
    public int create(User user);

    /**
     * 根据id进行查询
     * @param userId
     * @return
     */
    public User findUserById(@Param("userId") Integer userId);
}

UserMapper.xml:

<mapper namespace="com.huzz.mapper.UserMapper">

    <insert id="create" parameterType="User" useGeneratedKeys="true" keyProperty="id" >
        INSERT INTO user (username, password) VALUES (#{username}, #{password});
    </insert>
    <resultMap id="BaseResultMap" type="User">
        <id column="id" property="id" jdbcType="INTEGER" />
        <id column="username" property="username" jdbcType="VARCHAR" />
        <id column="password" property="password" jdbcType="VARCHAR" />
    </resultMap>
    <select id="findUserById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        SELECT id, username, password FROM user WHERE id = #{userId}
    </select>
</mapper>

执行main方法, 能运行就OK:

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

四. 创建服务消费者: cloud-consumer-user80

1. 创建过程与创建服务提供者相同

pom.xml结构也是类似的, 将需要的依赖加上就行.

application.yml:

server:
  port: 80

#
spring:
  application:
    name: cloud-consumer-service

2. 创建config

注册服务调用的REST模板

@Configuration
public class ApplicationContextConfig {

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

3. 创建controller

 

@RestController
public class UserController {

    public static final String PAYMENT_URL = "http://localhost:8001";

    @Resource
    private RestTemplate restTemplate;

    @GetMapping("/consumer/user/create")
    public CommonResult<User> create(User user) {
        return restTemplate.postForObject(PAYMENT_URL + "/provider/user/create", user, CommonResult.class);
    }

    @GetMapping("/consumer/user/find/{userId}")
    public CommonResult<User> getPaymentById(@PathVariable("userId") Integer userId) {
        return restTemplate.getForObject(PAYMENT_URL + "/provider/user/find/" + userId, CommonResult.class);
    }
}

打开PostMan进行测试服务消费者:

 

 OK, 访问成功!!

 以上步骤完成了服务消费者到提供者的调用

posted @ 2021-10-08 18:33  Huzz44  阅读(204)  评论(0)    收藏  举报