搭一个Gradle多模块管理的 Spring Cloud Finchley 分布式微服务项目

Posted Acmen-zym

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了搭一个Gradle多模块管理的 Spring Cloud Finchley 分布式微服务项目相关的知识,希望对你有一定的参考价值。

Spring Cloud 是在 Spring Boot 基础上构建的,用于快速构建分布式系统的通用模式的工具集。

别的理论、使用场景、历史之类的也不说了,直接切入主题。
这里,我就来架构一个简单 Spring Cloud 的应用。

既然要用,当然要与时俱进,我这里选择的是基于Spring Boot 2.0.x 的Spring Cloud Finchley。
开发工具: IDEA
JDK version: 1.8
具体的框架版本号: Spring Boot 2.0.5 RELEASE、Spring Cloud Finchley.SR3
项目管理工具: gradle ( 9102年了,maven这xml配置实在是够恶心的了

目前只是最原始的初版,使用RestTemplate简单的调用一下别的服务接口。 至于服务注册、发现、跟踪、容错、微服务网关、负载均衡之类的。之后也会慢慢写出文章的。
先把项目给搭起来。之后再要添加新的依赖增加新的功能就就简单许多了。

build.gradle文件:

group 'com.skypyb.sc'
version = '0.0.1-SNAPSHOT'
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
buildscript {
    ext {
        springBootVersion = '2.0.5.RELEASE'
        springCloudVersion = 'Finchley.SR3'
    }
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
        mavenCentral()
    }
    dependencies {//用来打包
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
allprojects {
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
        mavenCentral()
    }
    //指定编码格式
    tasks.withType(JavaCompile) {
        options.encoding = "UTF-8"
    }
}
//设定子模块的通用配置
subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    //spring boot 插件
    apply plugin: 'org.springframework.boot'
    //Gradle插件,提供类似Maven的依赖关系管理功能
    apply plugin: 'io.spring.dependency-management'
    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web')
        //Actuator提供服务监控与管理的功能,路径: /actuator/{端点}
        compile('org.springframework.boot:spring-boot-starter-actuator')
        compile('org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2')
        compile('mysql:mysql-connector-java')
        testCompile('org.springframework.boot:spring-boot-starter-test')
    }
    dependencyManagement {
        imports {
            //spring bom帮助我们在不指定版本号的情况下声明依赖项。
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
    jar {
        manifest.attributes provider: 'gradle'
    }
}

可以看到我给所有的子模块添加了web、mysql、mybatis、Actuator的依赖。
Actuator这个东西是用于服务监控和管理的,这里不表,具体的可以看这个文章

gradle加载完毕后这个父模块就创建好了。gradle会自动给你生成一个src文件夹,删掉就行,也可以不删。反正父模块里边是不会放代码的。

然后就是建立子 module 了,子module 的创建是直接在父 module 上边右键 –> new Module 来进行创建的。当然,也是Gradle项目。
建好后将子 module 的 build.gradle文件里的东西全删掉
只留这个:

dependencies {
}

这个是用来添加该模块独有的依赖的。我这暂时为空。

我创建了一个用户微服务、一个电影微服务。里边都有具体的Dao、Service、Entity,这里就不贴了,太占位置。
我这里实现的RPC是通过Spring提供的RestTemplate,链接都是写死的,之后当然会优化。这里只是把项目运转起来。
两边的Controller层:
用户:

package com.skypyb.sc.controller;
import com.skypyb.sc.entity.User;
import com.skypyb.sc.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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 {
    private Logger logger = LoggerFactory.getLogger(UserController.class);
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        logger.info("access getUser method.");
        return userService.getUser(id);
    }
}

电影:

package com.skypyb.sc.controller;
import com.skypyb.sc.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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("/movie")
public class MovieController {
    private Logger logger = LoggerFactory.getLogger(MovieController.class);
    @Autowired
    private RestTemplate restTemplate;
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        logger.info("access getUser method.");
        return restTemplate.getForObject("http://localhost:8088/user/" + id, User.class);
    }
}

这样子配好,启动服务时先启动 User 服务,然后启动 Movie 服务,然后通过浏览器输入 Movie 服务的接口获得数据。
最后结果是如愿以偿的得到了数据。而这份数据是 Movie 服务通过 rest 请求 User 服务所得来的。

yml文件都一样的所以只放了一个

server:
  port: 8089
spring:
  application:
    name: sc-demo-microservice-movie #这个名字会注册到 Eureka 里去
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://192.168.8.113:3306/scdemo?serverTimezone=Asia/Shanghai
    username: root
    password: 614
#mybatis实体类名
mybatis:
  type-aliases-package: com.skypyb.sc.entity
  configuration:
  #到下划线的表字段自动映射成驼峰命名法
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mybatis/mapper/*.xml
#Actuato 配置
management:
  endpoint:
# 暴露shutdown功能
#    shutdown:
#      enabled: true
  endpoints:
    web:
      exposure:
        include: '*'  #暴露哪些端点
        exclude:      #隐藏哪些端点
#Eureka client端配置
eureka:
  client:
    service-url:
        defaultZone: http://localhost:8080/eureka/
  instance:
    prefer-ip-address: true #将自己ip注册到Eureka Server

以上是关于搭一个Gradle多模块管理的 Spring Cloud Finchley 分布式微服务项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在多模块spring boot应用程序gradle中只访问不同模块的一个类?

Spring Boot gradle 多模块项目未解决的引用错误

多模块 Spring Boot 项目中的 Gradle 依赖插件

Spring boot 和 Gradle 多模块项目,无法正确加载依赖项

无法集成测试 gradle 多模块 Spring-Boot-Application

多模块 Gradle 项目 - 从 Spring-Boot 1.5 迁移到 2.1