SpringCloud Eureka测试项目--一个最简单的订单获取功能

本文实战演示SpringCloud中Eureka服务发现组件的使用方法,包括Eureka Server搭建、Client集成及服务调用流程。

本文档是为了演练SpringCload的Eureka。

本文档演示EurekaServer开发、EurekaClient开发。

本文档演示EurekaClient的调度。

本文档为了更集中于SpringCloud的功能演示,没有集成MyBatis相关的功能。

本文档开发了一个SpringCloud项目,该项目中包括3个子项目:

  1 Eureka Server项目,是注册中心,用于服务发现和调度,并实现了负载均衡功能。

  2 订单提供者项目, 提供了订单的服务,其实就是提供了一个API,调用可以返回订单信息。

  3 订单消费者项目, 消费订单的服务,其实就是调用 订单提供者项目 的API,该项目其实没必要注册到注册中心。

创建SpringCloud父项目

SpringCloud项目是依赖于 SpringBoot的

在idea下创建 maven 项目。项目命名为 test-springcloud 

该项目是父项目,并不提供任何功能,仅仅提供公共的依赖

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

    <groupId>com.pingbu</groupId>
    <artifactId>test-springcloud</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <!-- 三个模块  -->
    <modules>
        <!--  注册中心模块  -->
        <module>test-springcloud-eureka-server8761</module>
        <!-- 消费者模块  -->
        <module>test-springcloud-consumer-order8000</module>
        <!-- 提供者模块 -->
        <module>test-springcloud-provider-order8001</module>
    </modules>

    <!-- 各依赖的版本 -->
    <properties>
        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
        <mybatis-spring-boot.version>2.1.2</mybatis-spring-boot.version>
        <mysql.version>8.0.12</mysql.version>
        <druid.version>1.1.21</druid.version>
        <lombok.version>1.18.12</lombok.version>
        <java.version>1.8</java.version>

        <!-- 项目内置的两个参数,设置后编译的时候会使用这两个参数  -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

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

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring-boot.version}</version>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>


        </dependencies>
    </dependencyManagement>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>

    </build>

</project>

该 文件加入了mybatis的依赖,其实本演示项目并没有操作数据库,这个完全可以省略。

注册中心模块,即eureka服务模块

该模块很简单,提供了注册中心的功能,即服务都注册在它上面,从而实现服务的发现。

该模块的父项目为 test-springcloud ,即上一节的项目。

该模块命名为 test-springcloud-eureka-server8761 

该模块的 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">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.pingbu</groupId>
        <artifactId>test-springcloud</artifactId>
        <version>1.0.0</version>
    </parent>

    <groupId>com.pingbu</groupId>
    <artifactId>test-springcloud-eureka-server8761</artifactId>
    <version>1.0.0</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>

    <build>
        <finalName>test-springcloud-eureka-server8761</finalName>
    </build>


</project>

该文件引入了 eureka-server的依赖。

其实,如果考虑到高可用,应该将注册中心做成集群,本文档不考虑这个功能,后面的我会单独写这样的文章。

springboot的 application.yml 文件如下

# 端口
server:
  port: 8761

spring:
  application:
    name: cloud-eureka-server

# Eureka配置
eureka:
  instance:
    # eureka服务端的实例名称
    hostname: localhost
    # eureka 注册中心的端口
    port: 8761

  server:
    enable-self-preservation: false
  client:
    # false表示不向注册中心注册自己
    register-with-eureka: false
    # false表示自己端就是注册中心,职责就是维护服务实例,并不需要去检查服务
    fetch-registry: false
    # 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${eureka.instance.port}/eureka

该模块的 Spring Main类文件如下

package com.wanshi.eureka;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

// Eureka服务端
@EnableEurekaServer
@SpringBootApplication
public class EurekaMain8761 {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMain8761.class, args);
    }
}

该模块到这里就结束了,也没什么需要讲解的。

该模块启动后,可以在浏览器输入 http://ip:port/ 访问,访问页面如下

提供者模块,订单服务提供者

该模块命名为  test-springcloud-provider-order8001 

该模块提供了一个RESTFul的API,对!只提供了一个API,因为本文档是一个演示项目,所以,越简单越好。大家明白的,真实的项目,提供者不可能只有一个API。

这个 API 是基于RESTful的。

这个API的请求地址为: http://ip:port/consumer/order/get/{id} ,请求方式为 get

根据地址可以看出,这就是一个普通的RESTful 接口,参数为 path参数,可接收一个 id 参数。

该api自然可以正常调用,但我们写的是SpringCloud分布式项目,因此,我们目标是通过eureka注册中心发现服务并调用。

该模块的 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">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.pingbu</groupId>
        <artifactId>test-springcloud</artifactId>
        <version>1.0.0</version>
    </parent>

    <groupId>com.pingbu</groupId>
    <artifactId>test-springcloud-provider-order8001</artifactId>
    <version>1.0.0</version>

    <dependencies>

        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- spring boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>

    <build>
        <finalName>test-springcloud-provider-payment8001</finalName>
    </build>

</project>

可以看到,该模块引入了eureka client依赖。

该模块的 application.yml 文件如下

server:
  port: 8001

spring:
  application:
    name: provider-order

eureka:
  serverInstance:
    hostname: 127.0.0.1
    port: 8761
  client:
    # 表示将自己注册进Eureka Server默认为true
    register-with-eureka: true
    # 是否从Eureka Server抓去已有的注册信息,默认是true
    fetch-registry: true
    # 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
    service-url:
      defaultZone: http://${eureka.serverInstance.hostname}:${eureka.serverInstance.port}/eureka

可以看到,这个项目定义了一个 application 的 name,这个名字就是注册到 eureka server 的名字,最终也是要发现该名字。

该模块的 SpringBoot Main类文件代码如下

package com.wanshi.provider.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

// Eureka客户端
@EnableEurekaClient
@SpringBootApplication
public class ProviderOrderMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(ProviderOrderMain8001.class, args);
    }
}

注解上声明,这是一个eureka 客户端 

我们现在看看该模块提供的API,很简单的一个RestController接口,代码如下。

package com.wanshi.provider.order.controller;

import com.wanshi.provider.order.bean.Order;
import com.wanshi.provider.order.bean.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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;

@Slf4j
@RestController
@RequestMapping("/provider/order/")
public class OrderController {


    @Value("${server.port}")
    private String serverPort;


    @GetMapping("/get/{id}")
    public ResultBean<Order> getOrderById(@PathVariable("id") Long id) {
        Order result = new Order();
        result.setId(1L);
        result.setSerial("测试序列");

        log.info("====== 查询结果:" + result);
        if(result != null) {
            return new ResultBean(0, "查询成功,服务端口:" + serverPort, result);
        }else {
            return new ResultBean(500, "查询失败");
        }

    }

}

不做过多的解释,该接口用到了两个自定义类,如下。

订单bean类 Order.java 如下:

package com.wanshi.provider.order.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {

    private Long id;
    private String serial;

}

由于项目使用了 lombok ,所以,该Bean 类没有 get 和 set 方法。 

公共返回类,这个类也不多解释,代码如下:

package com.wanshi.provider.order.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultBean<T> {

    private int code;
    private String msg;
    private T data;

    public ResultBean(int _code , String _msg){
        code = _code;
        msg = _msg;
    }

}

该模块就是这些了,没有其他的东西需要说明的。

该项目启动后,我们可以看到 eureka server中多了一个注册的项目。

消费者模块,订单消费模块

该模块调用提供者模块的API

这模块不需要注册到注册中心。

该模块的 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">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.pingbu</groupId>
        <artifactId>test-springcloud</artifactId>
        <version>1.0.0</version>
    </parent>

    <groupId>com.pingbu</groupId>
    <artifactId>test-springcloud-consumer-order8000</artifactId>
    <version>1.0.0</version>



    <dependencies>
        <!-- eureka client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <!-- spring boot -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <finalName>test-springcloud-order8000</finalName>
    </build>

    
</project>

该模块的 application.yml 文件如下:

server:
  port: 8001

spring:
  application:
    name: provider-order

eureka:
  serverInstance:
    hostname: 127.0.0.1
    port: 8761
  client:
    # 表示将自己注册进Eureka Server默认为true
    register-with-eureka: true
    # 是否从Eureka Server抓去已有的注册信息,默认是true
    fetch-registry: true
    # 设置与Eureka Server交互的地址查询服务和注册服务都需要依赖这个地址
    service-url:
      defaultZone: http://${eureka.serverInstance.hostname}:${eureka.serverInstance.port}/eureka

该项目的 SpringBoot Main类文件如下

package com.wanshi.provider.order;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

// Eureka客户端
@EnableEurekaClient
@SpringBootApplication
public class ProviderOrderMain8001 {
    public static void main(String[] args) {
        SpringApplication.run(ProviderOrderMain8001.class, args);
    }
}

该项目的调用 提供者的 API的代码如下。

package com.wanshi.provider.order.controller;

import com.wanshi.provider.order.bean.Order;
import com.wanshi.provider.order.bean.ResultBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
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;

@Slf4j
@RestController
@RequestMapping("/provider/order/")
public class OrderController {


    @Value("${server.port}")
    private String serverPort;


    @GetMapping("/get/{id}")
    public ResultBean<Order> getOrderById(@PathVariable("id") Long id) {
        Order result = new Order();
        result.setId(1L);
        result.setSerial("测试序列");

        log.info("====== 查询结果:" + result);
        if(result != null) {
            return new ResultBean(0, "查询成功,服务端口:" + serverPort, result);
        }else {
            return new ResultBean(500, "查询失败");
        }

    }

}

该模块不多做解释,缺少的 Bean 可自行完善。

该项目启动后,可以在浏览器下 访问 地址  http://ip:port/consumer/order/get/1  访问。  

返回结果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小崔爱读书

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值