A simple example of spring cloud microservice implementation

Spring cloud integrates feign to implement microservice invocation, service registration uses consul, and build chooses maven.
The project directory structure mainly contains the following 3 modules:
kp-core provides public classes and public configuration (such as: feign)
kp-service-customer-back service provider
kp-service-customer-mid service caller
Insert picture description here

First, introduce dependency (PS: partly not used) in the pom.xml of the parent module (proj-hd-parent) to use dependencyManagement, so there is no need to specify the version tag under each submodule (version>${project.version }</version)

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.hd</groupId>
    <artifactId>proj-hd-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
        <module>kp-service-customer-back</module>
        <module>kp-service-customer-mid</module>
        <module>kp-core</module>
    </modules>
    <packaging>pom</packaging>

    <properties>
        <!-- Compile libs -->
        <fastjson.version>1.2.51</fastjson.version>

        <!-- Test libs -->
        <junit.version>4.12</junit.version>
        <mockito.version>2.21.0</mockito.version>

        <!-- Build -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.source.version>1.6</java.source.version>
        <java.target.version>1.6</java.target.version>
        <maven.compiler.version>3.8.0</maven.compiler.version>
        <maven.surefire.version>2.22.1</maven.surefire.version>
        <maven.source.version>3.0.1</maven.source.version>
        <maven.javadoc.version>3.0.1</maven.javadoc.version>
        <maven.deploy.version>2.8.2</maven.deploy.version>
        <maven.gpg.version>1.6</maven.gpg.version>
        <maven.jacoco.version>0.8.2</maven.jacoco.version>
        <maven.jar.version>3.1.0</maven.jar.version>


        <spring.boot.version>2.0.6.RELEASE</spring.boot.version>
        <spring.cloud.feign.version>2.0.2.RELEASE</spring.cloud.feign.version>
        <spring.cloud.consul.version>2.0.1.RELEASE</spring.cloud.consul.version>
        <spring.mybatis.version>1.3.2</spring.mybatis.version>
        <spring.redis.version>2.9.0</spring.redis.version>
        <guava.version>20.0</guava.version>


    </properties>


    <!-- maven依赖 -->
    <dependencyManagement>

        <dependencies>

            <dependency>
                <groupId>com.hd</groupId>
                <artifactId>kp-core</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.hd</groupId>
                <artifactId>kp-service-customer-back</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.hd</groupId>
                <artifactId>kp-service-customer-mid</artifactId>
                <version>${project.version}</version>
            </dependency>

            <!-- spring-boot -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-aop</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>${spring.cloud.feign.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-consul-discovery</artifactId>
                <version>${spring.cloud.consul.version}</version>
            </dependency>

            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${spring.mybatis.version}</version>
            </dependency>

            <dependency>
                <groupId>com.google.guava</groupId>
                <artifactId>guava</artifactId>
                <version>${guava.version}</version>
            </dependency>


            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j-web</artifactId>
                <version>2.10.0</version>
            </dependency>

            <dependency>
                <groupId>redis.clients</groupId>
                <artifactId>jedis</artifactId>
                <version>${spring.redis.version}</version>
            </dependency>


            <!-- hd -->
            <dependency>
                <groupId>com.hd</groupId>
                <artifactId>kp-service-customer-back</artifactId>
                <version>${project.version}</version>
            </dependency>


            <!-- Servlet -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.0.1</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
                <scope>provided</scope>
            </dependency>

            <!-- jstl -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <dependency>
                <groupId>taglibs</groupId>
                <artifactId>standard</artifactId>
                <version>1.1.2</version>
            </dependency>

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <dependencies>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>${spring.cloud.feign.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            <version>${spring.cloud.consul.version}</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>

    </dependencies>

</project>

spring-cloud-starter-openfeign, spring-cloud-starter-consul-discovery focus on introducing these two jars

Provider (kp-service-customer-back)
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>proj-hd-parent</artifactId>
        <groupId>com.hd</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>kp-service-customer-back</artifactId>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.hd</groupId>
            <artifactId>kp-core</artifactId>
        </dependency>

    </dependencies>





    <build>
        <finalName>sentinel-dashboard</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <mainClass>com.hd.pk.CustomerApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>${maven.deploy.version}</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>

            <resource>
                <directory>src/main/webapp/</directory>
                <excludes>
                    <exclude>resources/node_modules/**</exclude>
                </excludes>
            </resource>
        </resources>
    </build>

</project>
@SpringBootApplication
@EnableDiscoveryClient
public class CustomerApplication {
    public static void main(String[] args) {
        SpringApplication.run(CustomerApplication.class, args);
    }
}

yml file:

server:
  port: 10086

consul-server-ip-address: 192.168.x.xx    #consul服务地址

spring:
  application:
    name: kp-service-customer-back
  cloud:
    consul:
      host: ${consul-server-ip-address}
      port: 8500
      discovery:
        prefer-ip-address: true
        service-name: ${spring.application.name}
        # hostname: ${spring.cloud.client.ip-address}   #默认本机
        port: ${server.port}
        health-check-interval: 10s
        heartbeat:
          enabled: true

Controller

@RestController
@RequestMapping("/back")
public class BackController {

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public Response<String> getInfo(@RequestBody CustomerEntity customerEntity){
        Response<String> response = new Response<>();
        response.setCode(0);
        response.setData("hello world");
        return response;
    }

}

Caller (kp-service-customer-mid)
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>proj-hd-parent</artifactId>
        <groupId>com.hd</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>kp-service-customer-mid</artifactId>

    <name>kp-service-customer-mid</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.hd</groupId>
            <artifactId>kp-core</artifactId>
        </dependency>
    </dependencies>

    <build>
        <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
            <plugins>
                <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
                <plugin>
                    <artifactId>maven-clean-plugin</artifactId>
                    <version>3.1.0</version>
                </plugin>
                <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
                <plugin>
                    <artifactId>maven-resources-plugin</artifactId>
                    <version>3.0.2</version>
                </plugin>

            </plugins>
        </pluginManagement>
    </build>
</project>

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

fr:

server:
  port: 10087

consul-server-ip-address: 192.168.x.xx

spring:
  application:
    name: kp-service-customer-mid
  cloud:
    consul:
      host: ${consul-server-ip-address}
      port: 8500
      discovery:
        prefer-ip-address: true
        service-name: ${spring.application.name}
        hostname: ${spring.cloud.client.ip-address}
        port: ${server.port}
        health-check-interval: 10s
        heartbeat:
          enabled: true

Controller

@RestController
@RequestMapping("/mid")
public class MidController {

    @Resource
    private CustomerServiceFeign customerServiceFeign;

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public Response getInfo(){
        CustomerEntity customerEntity = new CustomerEntity();
        customerEntity.setAccountId(123344L);
        Response<String> customerEntity1 = customerServiceFeign.getCustomerEntity(customerEntity);
        return customerEntity1;
    }
}

The kp-core module can create new public classes and public configuration classes can be placed in this module for multiple modules to share.
CustomerServiceFeign class:

@FeignClient(value = "kp-service-customer-back", configuration = FeignConfig.class)
public interface CustomerServiceFeign {

    /**
     * 获取客户实体
     * @param customerEntity
     * @return
     */
    @RequestMapping(value = "/back/test", method = RequestMethod.POST)
    Response<String> getCustomerEntity(@RequestBody CustomerEntity customerEntity);
}

FeignConfig class Feign related configuration

@Configuration
public class FeignConfig {
    @Bean
    public Retryer feignRetryer() {
        return new Retryer.Default(100, TimeUnit.SECONDS.toMillis(1), 3);
    }

    @Bean
    public Request.Options feginOption() {
        Request.Options option = new Request.Options(3000, 5000);
        return option;
    }
}

After starting the service module and calling the module separately, request through the browser: http://localhost:10087/mid/test
Insert picture description here
Consul To register the service, you must first configure and start it. After starting, you will see that the service has been registered:
Insert picture description here

So far, the Spring Cloud implementation of microservices based on feign and consul registration center has been completed.

One thing to note here
is that a problem was discovered in the implementation process. When requesting the URL, it always reported:
java.lang.NoClassDefFoundError: com/google/common/reflect/TypeToken,
and then request to throw an exception
java.lang.NoClassDefFoundError: Could not initialize class com.netflix.client.config.CommonClientConfigKey

After investigation and combination of online information, it is because the dependency of com.google.guava is not introduced, and there is no problem after the introduction.

Guess you like

Origin blog.csdn.net/huangdi1309/article/details/87078162