Come on,搭一个Gradle多模块管理的 Spring Cloud Finchley 分布式微服务项目
Spring Cloud 是在 Spring Boot 基础上构建的,用于快速构建分布式系统的通用模式的工具集。
别的理论、使用场景、历史之类的也不说了,直接切入主题。
这里,我就来架构一个简单 Spring Cloud 的应用。
既然要用,都9102年了,当然要与时俱进,我这里选择的是基于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简单的调用一下别的服务接口。 至于服务注册、发现、跟踪、容错、微服务网关、负载均衡之类的。之后也会慢慢写出文章的。
先把项目给搭起来。之后再要添加新的依赖增加新的功能就就简单许多了。
OK,进入正题。
先打开 IDEA 创建一个 Gradle 的Module。我创建的模块名字叫做 sc-demo-microservice
这个是根/父模块, 用于管理一个个的微服务。他可以在 ‘subprojects’ 这个代码块中配置所有子模块通用的配置。
我的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
我的项目地址: github
里边sql语句、配置文件啥的都有。是个完整的项目。
结构如下:
下一篇文章是Eureka
3 COMMENTS