SpringCloud(一)-手把手教你创建springcloud微服务父子项目

现在微服务思想大行其道,各个公司都在如火如荼的进行技术转型,掌握SpringCloud已经成为升职加薪的垫脚石,笔者将从本文开始从实战和原理记录SpringCloud的学习过程。

系列文章
SpringCloud(一)-手把手教你创建springcloud微服务父子项目
SpringCloud(二)-手把手教你搭建Eureka Server和Eureka Client
SpringCloud(三)-手把手教你通过Rinbbon实现客户端负载均衡
SpringCloud(四)-手把手教你使用OpenFeign
SpringCloud(五)-手把手教你使用Hystrix配置服务熔断和降级以及Hystrix Dashboard
SpringCloud(六)-手把手教你搭建SpringCloud Config配置中心
SpringCloud(七)-手把手教你使用消息总线Bus实现动态刷新
SpringCloud(八)-手把手教你使用Stream消息驱动

码云地址

https://gitee.com/zhaowenyi/springcloudtest/tree/master

初识SpringCloud

打开SpingCloud中文官网,一行"微服务集大成者,云计算最佳业务实践"赫然入目,由此可知SpringCloud在微服务领域的影响力。

SpringCloud 是由一系列技术栈组合而成:

  • Spring Cloud Config: 管理配置包,可以将配置文件放在远程服务器上集中化管理集群配置文件。支持本地存储,git,subversion。
  • Spring Cloud Bus:事件、消息总线,可以在集群中传播状态变化,比如配置文件变动,可以和Spring Cloud Config组合使用。
  • Netflix Eureka:服务注册与发现,一个基于REST服务,用于服务注册与发现,故障转移等功能
  • Netflix Hystrix:熔断器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而为延迟和故障提供更强大的容错能力。
  • Netflix Zuul:提供动态路由,监控和安全等边缘服务的框架。
  • Netflix Ribbon:提供云端负载均衡,有多种负载均衡可供选择,可和熔断器和服务发现组合使用
  • Open Feign: 是一款申明式,模块化的HTTP客户端

这还只是列出的一部分常用的框架,还有很多都没有列出来,光通过定义都难以理解这些框架是干什么用的,只能千里之行始于足下,一步步开始攻克这些知识点了。

初识SpringBoot

上面的框架中没有列出SpringBoot,是因为SpringBoot作为最基础的框架,是基石,任何微服务都要从搭建一个Spring Boot项目开始。

那么什么是Spring Boot呢?

打开Spring Boot官网,我们了解到
使用Spring Boot可以轻松地创建独立的,基于生产级别的基于Spring的应用程序,我们可以“运行”它们。也就是Spring Boot帮我们配置了Spring 项目中哪些繁琐的配置,而且内置了服务器,比如tomcat,我们可以直接运行它。

总之其Spring思想还是没有变,只是帮我们简单快速的搭建一个Spring 项目。

构建SpringCloud项目

接下来就是开始搭建SpringCloud项目了。首选我们要搭建Spring Cloud项目父工程。

工具准备

  • JDK : 1.8
  • Spring Boot:2.0
  • IntelliJ IDEA:ULTIMATE 2017.02
  • Mysql:5.6.24
  • Win10
  • Maven: 3.6

搭建步骤

创建父工程
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第1张图片
新建项目
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第2张图片
输入gav坐标
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第3张图片
选择项目路径.png

点击File - settings - Build Tools - Maven ,这里的Maven路径选择自己本地的maven路径。

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第4张图片
设置maven路径

设置自动导入依赖

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第5张图片
点击Enable Auto Import

Editor - File Types,末尾加上“.idea;.iml;”,设置隐藏impl文件和.idea文件

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第6张图片
image.png

File - settings - Build - Complier - Java Complier ,需要将编译版本设置为1.8

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第7张图片
设置编译的jdk版本

最终的项目结构

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第8张图片
项目结构

pom.xml加入依赖



    4.0.0

    com.elio.springcloud
    springcloudtest
    1.0-SNAPSHOT

    
    
        UTF-8
        4.12
        1.18.10
        1.2.17
        5.1.47
        1.1.16
        1.3.0
    

    
    
        
            
                org.apache.maven.plugins
                maven-project-info-reports-plugin
                3.0.0
            
            
            
                org.springframework.boot
                spring-boot-dependencies
                2.2.2.RELEASE
                pom
                import
            
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                Hoxton.SR1
                pom
                import
            
            
            
                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                2.1.0.RELEASE
                pom
                import
            
            
            
                mysql
                mysql-connector-java
                ${mysql.version}
                runtime
            
            
            
                com.alibaba
                druid
                ${druid.version}
            
            
            
                org.mybatis.spring.boot
                mybatis-spring-boot-starter
                ${mybatis.spring.boot.version}
            
            
            
                junit
                junit
                ${junit.version}
            
            
            
                log4j
                log4j
                ${log4j.version}
            
        
    
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    true
                    true
                
            
        
    

创建子工程

父工程完成后,我们接下来创建两个子项目,一个是商品服务的提供者,一个是商品服务的消费者。首先来创建商品服务的提供者

右键项目名,点击New - module

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第9张图片
新增子项目
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第10张图片
点击next

输入子项目名称 ”springcloud-product-provider-8100“,表示的商品的提供者,使用8100端口

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第11张图片
输入子项目名称
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第12张图片
点击next

点击finish后,我们可以看到构建成功的子项目

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第13张图片
商品服务提供者8100

添加商品服务提供者的pom.xml配置

右键商品服务提供者项目的resources文件夹,新增application.yml配置文件,新增之后application.yml前面有个绿色的小叶子标识

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第14张图片
新增yml配置文件

yml中的配置文件如下

server:
  port: 8100 #端口号

spring:
  application:
    name: springcloud-product-provider-8100
  datasource:
      url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&userSSL=false
      driverClassName: com.mysql.jdbc.Driver
      username: root
      password: 111111

mybatis:
  mapper-locations: classpath:mapping/*mapper.xml # Mybatis 映射文件位置
  type-aliases-package: com.elio.springcloud.entity  # 表对应的实体类包


右键java文件夹新增,实体类Product,这将是我们接下来的product表对应的实体类

package com.elio.springcloud.entity;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@NoArgsConstructor
@AllArgsConstructor
@Setter
@Getter
public class Product {

    private Long id; //自增id
    private String name;// 产品名称
    private int stock;// 库存

}

新增dao层接口ProductMapper

package com.elio.springcloud.dao;

import com.elio.springcloud.entity.Product;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductMapper {
    /**
     * 查询
     * @param id
     * @return
     */
    public Product selectById(@Param("id") Long id);


    /**
     * 删除
     * @param id
     * @return
     */
    public int deleteById(@Param("id") Long id);

    /**
     * 修改
     * @param id
     * @param name
     * @return
     */
    public int updateById(@Param("id") Long id, @Param("name") String name);

    /**
     * 新增
     * @param product
     * @return
     */
    public int insertOne(Product product);
}

右键resources文件,新增mapping\product_mapper.xml文件,这个是product表对应的sql文件,包含简单的增删改查





    
        
        
        
    

    
    

    
    
        delete from product where id = #{id}
    

    
    
        update product set name = #{name} where id = #{id}
    

    
    
       insert into product(name, stock) values (#{name}, #{stock})
    



新增ProductService.java文件

package com.elio.springcloud.service;

import com.elio.springcloud.entity.Product;
import org.apache.ibatis.annotations.Param;

/**
 * 商品服务类
 */
public interface ProductService {

    /**
     * 查询
     * @param id
     * @return
     */
    public Product selectById(Long id);


    /**
     * 删除
     * @param id
     * @return
     */
    public int deleteById(Long id);

    /**
     * 修改
     * @param id
     * @param name
     * @return
     */
    public int updateById(Long id, String name);

    /**
     * 新增
     * @param product
     * @return
     */
    public int insertOne(Product product);

}


新增ProductServiceImpl.java 类

package com.elio.springcloud.service.impl;

import com.elio.springcloud.dao.ProductMapper;
import com.elio.springcloud.entity.Product;
import com.elio.springcloud.service.ProductService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class ProductServiceImpl implements ProductService{

    @Resource
    private ProductMapper productMapper;

    public Product selectById(Long id) {
        return productMapper.selectById(id);
    }

    public int deleteById(Long id) {
        return productMapper.deleteById(id);
    }

    public int updateById(Long id, String name) {
        return productMapper.updateById(id, name);
    }

    public int insertOne(Product product) {
        return productMapper.insertOne(product);
    }
}


新增Result.java

package com.elio.springcloud.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class Result {

    private int code;
    private String message;
    private Object result;
}

新增ProductProviderController.java

package com.elio.springcloud.controller;

import com.elio.springcloud.dto.Result;
import com.elio.springcloud.entity.Product;
import com.elio.springcloud.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

@RestController
@Slf4j
@RequestMapping("/")
public class ProductProviderController {

    @Resource
    private ProductService productService;

    /**
     * 查询
     * @param id
     * @return
     */
    @GetMapping("product/provider/get/{id}")
    public Result selectById(@PathVariable("id") Long id){
        return new Result(200, "查询成功", productService.selectById(id));
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @GetMapping("product/provider/delete/{id}")
    public Result deleteById(@PathVariable("id") Long id){
        return new Result(200, "删除成功", productService.deleteById(id));
    }

    /**
     * 修改
     * @param product
     * @return
     */
    @PostMapping("product/provider/update")
    public Result updateById(@RequestBody Product product){
        return new Result(200, "修改成功", productService.updateById(product.getId(), product.getName()));

    }

    /**
     * 新增
     * @return
     */
    @PutMapping( "product/provider/add")
    public Result insertById(@RequestBody Product product){
        return new Result(200, "修改成功", productService.insertOne(product));
    }
}

右键java文件夹,新增主启动类ProductProvider8100

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第15张图片
新增主启动类

ProductProvider8100内容如下,加上@SpringBootApplication和MapperScan注解

package com.elio.springcloud;

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

@SpringBootApplication
@MapperScan("com.elio.springcloud.dao")
public class ProductProvider8100 {

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


创建表结构


-- ----------------------------
-- Table structure for product
-- ----------------------------
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `stock` int(10) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;


测试

至此微服务的商品提供者,我们已经创建成功,接下来就是测试该提供者了


SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第16张图片
右键主启动类DEBUG

启动成功后可以查看结果如下


SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第17张图片
启动成功

浏览器地址输入 http://localhost:8100/product/provider/get/1

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第18张图片
查询结果

创建商品服务消费者

右键父项目,点击next

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第19张图片
点击Next
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第20张图片
输入项目名
SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第21张图片
输入项目名

配置商品消费者的pom.xml文件



    
        springcloudtest
        com.elio.springcloud
        1.0-SNAPSHOT
    
    4.0.0

    springcloud-product-consumer-8200


    
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
        
            org.springframework.boot
            spring-boot-devtools
        
        
        
            org.projectlombok
            lombok
        
    

    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    true
                    true
                
            
        
    

resources文件夹下新增application.yml文件

server:
  port: 8200

spring:
  application:
    name: springcloud-product-consumer-8200

新增主启动类 ProductConsumer8200,因为消费者不需要连接数据库,所以pom.xml中也没有导入相关依赖,因此需要将自动注入数据源的的类过滤掉 @SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})

package com.elio.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication(exclude={DataSourceAutoConfiguration.class,HibernateJpaAutoConfiguration.class})
public class ProductConsumer8200 {

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

新增业务类 ProductConsumerController

package com.elio.springcloud.controller;

import com.elio.springcloud.dto.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;

@RestController
public class ProductConsumerController {

    @Resource
    RestTemplate restTemplate;

    public static String url = "http://localhost:8100/";

    /**
     * 查询
     * @param id
     * @return
     */
    @GetMapping("product/consumer/get/{id}")
    public Result selectById(@PathVariable("id") Long id){

        return new Result(200, "查询成功",
                restTemplate.getForObject(url+"product/provider/get/"+id, Result.class));
    }

}

**新增结果返回实体类Result **

package com.elio.springcloud.dto;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
public class Result {

    private int code;
    private String message;
    private Object result;
}

因为要调用消费者的api, 因此我们需要注入restTemplate对象,新增RestConfig

package com.elio.springcloud.config;

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

@Configuration
public class RestConfig {

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

至此,我们已经创建好了消费者项目,接下来就是测试了

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第22张图片
消费者项目架构

右键主启动类,启动成功后会显示如下结果

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第23张图片
启动日志

浏览器地址输入 http://localhost:8200/product/consumer/get/1
这是使用消费者的路径访问提供者的api,结果如下

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第24张图片
返回成功的结果

总结

我们至此创建了一个父项目springcloudtest,然后有一个商品服务提供者
springcloud-product-provider-8100 和一个商品服务消费者springcloud-product-consumer-8200 。然后这就是最简单的两个微服务了,实现了功能的解耦,但是这个简单的微服务存在着很多问题,比如都用公共的实体类Result,还有提供者地址在消费者里面写死了等等,这些问题,我们接下来会一一解决。如有问题,请在评论区指正。

SpringCloud(一)-手把手教你创建springcloud微服务父子项目_第25张图片
项目架构

你可能感兴趣的:(SpringCloud(一)-手把手教你创建springcloud微服务父子项目)