Build a Spring Cloud Finchley distributed microservice project managed by Gradle multi module

Posted by Rebel7284 on Tue, 08 Feb 2022 15:53:22 +0100

Spring Cloud is a tool set built on the basis of Spring Boot to quickly build a general pattern of distributed systems.

Let's not talk about other theories, usage scenarios, history and so on, but directly cut into the theme.
Here, I'll build a simple Spring Cloud application.

Since it has been used for 9102, of course, it should keep pace with the times. My choice here is based on spring boot 2.0 X's Spring Cloud Finchley.
Development tool: IDEA
JDK version: 1.8
Specific framework version numbers: Spring Boot 2.0.5 RELEASE, spring cloud Finchley SR3
Project management tool: gradle (9, 102 years old, maven xml configuration is disgusting enough

At present, it is only the first version. Use RestTemplate to simply call other service interfaces. As for service registration, discovery, tracking, fault tolerance, microservice gateway, load balancing and so on. After that, I will write the article slowly.
Set up the project first. After that, it is much easier to add new dependencies and new functions.

build.gradle file:

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 {//For packing
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}
allprojects {
    repositories {
        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
        jcenter()
        mavenCentral()
    }
    //Specify encoding format
    tasks.withType(JavaCompile) {
        options.encoding = "UTF-8"
    }
}
//General configuration of stator module
subprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    //spring boot plug-in
    apply plugin: 'org.springframework.boot'
    //Gradle plug-in provides Maven like dependency management functions
    apply plugin: 'io.spring.dependency-management'
    dependencies {
        compile('org.springframework.boot:spring-boot-starter-web')
        //Actor provides the function of service monitoring and management. Path: / Actor / {endpoint}
        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 helps us declare dependencies without specifying a version number.
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
    jar {
        manifest.attributes provider: 'gradle'
    }
}

You can see that I have added web, mysql, mybatis and actor dependencies to all sub modules.
Activator is used for service monitoring and management. It is not shown here. For details, please refer to this article

After gradle is loaded, the parent module is created. Gradle will automatically generate an src folder for you. You can delete it or not. Anyway, there will be no code in the parent module.

Then you can create a child module. The child module is created directly by right clicking – > new module on the parent module. Of course, it's also the Gradle project.
After completion, the build. Of the sub module will be Delete everything from the gradle file
Just this:

dependencies {
}

This is used to add dependencies unique to the module. I'm empty for the time being.

I created a user micro Service and a movie micro Service. There are specific Dao, Service and Entity in it. It doesn't stick here. It takes up too much space.
The RPC I implement here is through the RestTemplate provided by Spring. The links are written dead and will be optimized later. It's just running the project.
Controller layers on both sides:
User:

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);
    }
}

film:

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);
    }
}

In this way, when starting the service, first start the User service, then start the Movie service, and then enter the interface of the Movie service through the browser to obtain data.
In the end, we got the data. This data is obtained by the Movie service through the rest request to the User service.

yml files are the same, so only one is put

server:
  port: 8089
spring:
  application:
    name: sc-demo-microservice-movie #This name will be registered in 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 entity class name
mybatis:
  type-aliases-package: com.skypyb.sc.entity
  configuration:
  #Table fields to underscores are automatically mapped into hump nomenclature
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mybatis/mapper/*.xml
#Actuato configuration
management:
  endpoint:
# Expose shutdown function
#    shutdown:
#      enabled: true
  endpoints:
    web:
      exposure:
        include: '*'  #Which endpoints are exposed
        exclude:      #Which endpoints are hidden
#Eureka client side configuration
eureka:
  client:
    service-url:
        defaultZone: http://localhost:8080/eureka/
  instance:
    prefer-ip-address: true #Register your ip with Eureka Server

Topics: Java Spring