【SpringCloud】1.一文带你入门SpringCloud微服务

1. 搭建父工程

最近打算使用 springcloud 搭建微服务玩一下,用到的东西大致有以下这些:

  • jdk 1.8
  • idea 2019
  • maven 3.6.3
  • springcloud 2021.0.3
  • springboot 2.6.14
  • mysql 8.0
  • mybatis-plus 3.5.1

这里需要注意的是,springcloud 的版本和 springboot 的版本要能匹配,不然会出现问题,没法使用。由于我这里已经搭建好了开发环境,所以我们直接开始父工程的搭建。

第一步,非常简单,打开 idea ,新建一个 maven 项目,配置什么的一切默认,项目名字改为自己定义的就好,我这里直接把项目名字写为 springcloud ,这就是我们的父工程了。

第二步,将项目中的 src 这个包删除掉,仅保留 .idea 、pom.xml、springcloud.iml 这三个文件。

第三步,在 pom.xml 文件中,加入依赖,将我们需要的包导入进来,下面是整个 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.yuhuofei</groupId>
    <artifactId>springcloud</artifactId>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springcloud-eureka</module>
        <module>springcloud-service-provider</module>
        <module>springcloud-service-consumer</module>
    </modules>

    <!--打包方式-->
    <packaging>pom</packaging>

    <!--版本号配置-->
    <properties>
        <spring-boot.version>2.6.14</spring-boot.version>
        <spring-cloud.version>2021.0.3</spring-cloud.version>
        <java.version>1.8</java.version>
        <mybatis-plus-spring-boot.version>3.5.1</mybatis-plus-spring-boot.version>
        <mysql.version>8.0.11</mysql.version>
        <druid.version>1.2.11</druid.version>
        <lombok.version>1.18.22</lombok.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

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

            <!--springboot依赖-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--mybatisPlus依赖-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-spring-boot.version}</version>
            </dependency>

            <!--mysql驱动依赖 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>

            <!--druid依赖-->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>

            <!-- lombok依赖 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <!-- test依赖,用于测试 -->
            <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>

    <!-- springboot打包插件,将代码打包成一个jar包 -->
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <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>

至此,整个父工程的搭建工作大致就完成了,下图是我已经搭建完服务消费者的项目结构,供参考。

在这里插入图片描述

2. 搭建注册中心

注册中心,我这里采用 eureka ,其它可以作为注册中心的组件还有 zookeeper、consul、nacos 等。

在前面的父工程里面,新建一个 module ,类型选择 Maven,名字写为 springcloud-eureka ,其它配置一切默认直至完成,这就是我们注册中心所在的服务了。

第一步,在自己的 pom.xml 文件中,引入依赖,整个 pom.xml 文件的内容如下所示,由于这个 module 只是作为注册中心,所以引入 eureka 服务端的依赖就可以了,版本选择的是 3.1.3 ,需要和前面选择的 springcloud 版本相匹配。

<?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>springcloud</artifactId>
        <groupId>com.yuhuofei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>springcloud-eureka</artifactId>

    <dependencies>
        <!--注册中心eureka服务端的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>3.1.3</version>
        </dependency>
        <!--以下是springboot相关依赖-->
        <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>
    </dependencies>

    <!--打包时,指定包名-->
    <build>
        <finalName>springcloud-eureka</finalName>
    </build>
</project>

第二步,新增一个启动类,我这里新建了一个 com.yuhuofei 的包,并将启动类 SpringCloudEurekaApplication.java 写在了这个包下,内容如下所示,注意需要加上注解 @EnableEurekaServer 以开启 eureka 服务端的使用。

package com.yuhuofei;

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

/**
 * @Description
 * @ClassName SpringCloudEurekaApplication
 * @Author yuhuofei
 * @Date 2023/5/22 18:56
 * @Version 1.0
 */
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaApplication.class, args);
    }
}

第三步,增加配置文件,在 resource 目录下,新建一个 application.properties 文件,内容如下所示。

#服务启动端口
server.port=8000
#服务名称
spring.application.name=springcloud-eureka

#========下面是eureka配置========#
#eureka服务端实例名称
eureka.instance.hostname=eureka-server
#不向注册中心注册当前服务
eureka.client.register-with-eureka=false
#当前服务是注册中心所在服务,负责维护所有服务实例,不需要检查服务
eureka.client.fetch-registry=false
#注册中心地址,当其它微服务连接注册中心时,需要这个地址
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/

到这里,注册中心的搭建,我们就完成了,整个 module 的结构如下图所示,非常简单,不复杂。

在这里插入图片描述
下面,我们启动一下启动类,并在浏览器访问 http://localhost:8000/ 看看结果,可以看到,一切如我们所料。

在这里插入图片描述

3. 搭建一个服务提供者

在父工程的基础上,新建一个 module ,类型选择 Maven,名字写为 springcloud-service-provider ,其它配置一切默认直至完成。

由于需要用到数据库,因此需要自己建立一个数据库以及数据库表,我这里随便建了一个 user 表,内容如下:

CREATE TABLE `user` (
  `id` int(20) NOT NULL,
  `name` varchar(30) COLLATE utf8_bin DEFAULT NULL,
  `password` varchar(30) COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

在这里插入图片描述
在自身的 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>springcloud</artifactId>
        <groupId>com.yuhuofei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-service-provider</artifactId>
    <dependencies>
        <!--eureka客户端的依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>3.1.3</version>
        </dependency>

        <!--加入mysql依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--druid依赖-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <!-- lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--mybatisPlus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!--以下是springboot相关依赖-->
        <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>
    </dependencies>

    <build>
        <finalName>springcloud-service-provider</finalName>
    </build>

</project>

新建一个包 com.yuhuofei,然后在这个包下新建一个启动类 SpringCloudServiceProviderApplication.java,内容如下所示,这里要注意开启 Eureka 客户端的支持。

package com.yuhuofei;

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

/**
 * @Description
 * @ClassName SpringCloudServiceProviderApplication
 * @Author yuhuofei
 * @Date 2023/5/22 18:56
 * @Version 1.0
 */
@SpringBootApplication
@EnableEurekaClient
public class SpringCloudServiceProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudServiceProviderApplication.class, args);
    }
}

后面就是依次新建 controller 、entity、mapper、service 相关的东西了,这里我直接贴出来各个类或者接口的内容。

  • UserController.java
package com.yuhuofei.controller;

import com.yuhuofei.entity.User;
import com.yuhuofei.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Description
 * @ClassName UserController
 * @Author yuhuofei
 * @Date 2023/5/22 19:56
 * @Version 1.0
 */
@RestController
@RequestMapping("/provider/user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/list")
    public List<User> queryAllUser() {
        return userService.queryUserList();
    }
}

  • User.java
package com.yuhuofei.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * @Description
 * @ClassName User
 * @Author yuhuofei
 * @Date 2023/5/22 19:49
 * @Version 1.0
 */
@Data
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    private String passWord;
}

  • UserMapper.java
package com.yuhuofei.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yuhuofei.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * @Description
 * @InterfaceName UserMapper
 * @Author yuhuofei
 * @Date 2023/5/22 19:55
 * @Version 1.0
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {

    List<User> queryUserList();
}

  • userMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.yuhuofei.mapper.UserMapper">
    <resultMap id="userResultMap" type="com.yuhuofei.entity.User">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="password" property="passWord"/>
    </resultMap>

    <sql id="Base_Column_List">
        id,name,password
    </sql>

    <select id="queryUserList" resultType="com.yuhuofei.entity.User">
        select id,name,password
        from user
        where id is not null;
    </select>

</mapper>

  • UserService.java
package com.yuhuofei.service;

import com.yuhuofei.entity.User;

import java.util.List;

/**
 * @Description
 * @InterfaceName UserService
 * @Author yuhuofei
 * @Date 2023/5/22 19:57
 * @Version 1.0
 */
public interface UserService {

    List<User> queryUserList();
}

  • UserServiceImpl.java
package com.yuhuofei.service.impl;

import com.yuhuofei.entity.User;
import com.yuhuofei.mapper.UserMapper;
import com.yuhuofei.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description
 * @ClassName UserServiceImpl
 * @Author yuhuofei
 * @Date 2023/5/22 19:58
 * @Version 1.0
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public List<User> queryUserList() {
        return userMapper.queryUserList();
    }
}

最后在 resource 目录下,新建一个 application.properties 文件,写入配置信息,内容如下:

#服务启动端口
server.port=8001
#服务名称
spring.application.name=springcloud-service-provider
#数据库连接配置
spring.datasource.username=root
spring.datasource.password=pan
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?allowPublicKeyRetrieval=true&useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#MybatisPlus配置
mybatis-plus.type-aliases-package=com.yuhuofei.entity
mybatis-plus.mapper-locations=classpath:mapper/*.xml
mybatis-plus.configuration.map-underscore-to-camel-case=true
#========下面是eureka配置========#
#向注册中心注册当前服务
eureka.client.register-with-eureka=true
#当前服务需要获取注册中心已经存在的注册信息,所以需要检查服务
eureka.client.fetch-registry=true
#注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/

整个服务提供者的目录结构如下图所示,到这里服务提供者的搭建就完成了。

在这里插入图片描述

4. 搭建一个服务消费者

服务消费者的搭建,和前面服务提供者的搭建类似,我这里搭建一个名为 springcloud-service-consumer 的服务消费者,整个 module 的结构如下图所示。

在这里插入图片描述
由于这个服务里面没有用到数据库的东西,所以不用整合 MybatisPlus 以及 MySQL 相关的东西,下面是各个相关的文件信息。

  • 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>springcloud</artifactId>
        <groupId>com.yuhuofei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-service-consumer</artifactId>

    <dependencies>
        <!--eureka客户端的依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>3.1.3</version>
        </dependency>
        <!-- lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--以下是springboot相关依赖-->
        <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>
    </dependencies>
    <build>
        <finalName>springcloud-service-consumer</finalName>
    </build>
</project>
  • SpringCloudServiceConsumerApplication.java
package com.yuhuofei;

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

/**
 * @Description
 * @ClassName SpringCloudServiceConsumerApplication
 * @Author yuhuofei
 * @Date 2023/5/22 18:59
 * @Version 1.0
 */
@SpringBootApplication
@EnableEurekaClient
public class SpringCloudServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudServiceConsumerApplication.class, args);
    }
}

  • application.properties
#服务启动端口
server.port=8002
#服务名称
spring.application.name=springcloud-service-consumer

#========下面是eureka配置========#
#向注册中心注册当前服务
eureka.client.register-with-eureka=true
#当前服务需要获取注册中心已经存在的注册信息,所以需要检查服务
eureka.client.fetch-registry=true
#注册中心地址
eureka.client.service-url.defaultZone=http://localhost:8000/eureka/
  • PersonInfo.java
package com.yuhuofei.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * @Description
 * @ClassName PersonInfo
 * @Author yuhuofei
 * @Date 2023/5/23 18:54
 * @Version 1.0
 */
@Data
public class PersonInfo implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    private String name;

    private String passWord;
}

  • RestTemplateConfig.java

这个类主要是提供一个 RestTemplate 的 bean 并交给 Spring 去托管

package com.yuhuofei.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * @Description
 * @ClassName RestTemplateConfig
 * @Author yuhuofei
 * @Date 2023/5/23 18:45
 * @Version 1.0
 */
@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

  • ConsumerController.java

这个类里面用到 RestTemplate 来实现 http 接口的调用,在当前这个服务消费者里面调用服务提供者的接口。

package com.yuhuofei.controller;

import com.yuhuofei.entity.PersonInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Description
 * @ClassName ConsumerController
 * @Author yuhuofei
 * @Date 2023/5/23 18:55
 * @Version 1.0
 */
@RestController
@RequestMapping("/consumer/person")
public class ConsumerController {

    public static final String PROVIDER_URL = "http://localhost:8001/";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/list")
    public List<PersonInfo> getPersonList() {
        return restTemplate.getForObject(PROVIDER_URL + "provider/user/list", List.class);
    }
}

到这里,我们就可以启动前面的服务提供者,然后再启动当前的服务消费者,接着在浏览器中访问 http://localhost:8002/consumer/person/list ,看看有没有数据出现,如果有,说明目前一切都是 OK 的。

至于目录中的 api 这个包,是后面整合 feign 客户端用的,这里暂时不用理会。

5. 整合OpenFeign实现服务之间的调用

前面我们已经实现了服务消费者调用服务提供者的接口,但是是通过 RestTemplate 这种方式来调用的,这是类似于单体服务的调用,并没有和我们说的微服务、注册中心等东西关联上,现在我们来改造一下,用 OpenFeign 实现微服务间的调用,与注册中心关联上。

在上面的服务消费者中,我们已经建了一个 api 的包,包里面后面要写一个接口 FeignServiceApi.java ,它的作用就是用来关联服务提供者的各个接口的。

下面我们在服务消费者 springcloud-service-consumer 的基础上,整合一下 OpenFeign 。

第一步,在 pom.xml 中引入下面的依赖

<!-- 增加openfeign依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>3.0.2</version>
</dependency>

完整的 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>springcloud</artifactId>
        <groupId>com.yuhuofei</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-service-consumer</artifactId>

    <dependencies>
        <!--eureka客户端的依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>3.1.3</version>
        </dependency>
        <!-- lombok依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--以下是springboot相关依赖-->
        <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>
        <!-- 增加openfeign依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.2</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>springcloud-service-consumer</finalName>
    </build>
</project>

第二步,在启动类 SpringCloudServiceConsumerApplication.java 上,加上注解 @EnableFeignClients ,开启 feign 客户端支持。

package com.yuhuofei;

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

/**
 * @Description
 * @ClassName SpringCloudServiceConsumerApplication
 * @Author yuhuofei
 * @Date 2023/5/22 18:59
 * @Version 1.0
 */
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringCloudServiceConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudServiceConsumerApplication.class, args);
    }
}

第三步,在接口 FeignServiceApi.java 中,加上注解 @FeignClient ,并指定要调用的服务提供者名称为 springcloud-service-provider ,接着就是在里面写上要调用的接口信息,内容如下:

package com.yuhuofei.api;

import com.yuhuofei.entity.PersonInfo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

/**
 * @Description feign调用服务提供者的接口
 * @InterfaceName FeignServiceApi
 * @Author yuhuofei
 * @Date 2023/5/23 19:26
 * @Version 1.0
 */
@Service
@FeignClient("springcloud-service-provider")
public interface FeignServiceApi {

    //调用服务提供者的接口
    @GetMapping("/provider/user/list")
    List<PersonInfo> queryAllUser();
}

第四步,为了和前面做出区分,我们在 ConsumerController.java 中,新增一个方法 getPersonListUseOpenFeign ,这个方法就通过 openfeign 来实现服务间的接口调用,为了更好地跟踪,我们加上日志打印。

package com.yuhuofei.controller;

import com.yuhuofei.api.FeignServiceApi;
import com.yuhuofei.entity.PersonInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * @Description
 * @ClassName ConsumerController
 * @Author yuhuofei
 * @Date 2023/5/23 18:55
 * @Version 1.0
 */
@RestController
@RequestMapping("/consumer/person")
@Slf4j
public class ConsumerController {

    public static final String PROVIDER_URL = "http://localhost:8001/";

    @Autowired
    private FeignServiceApi feignServiceApi;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/list")
    public List<PersonInfo> getPersonList() {
        return restTemplate.getForObject(PROVIDER_URL + "provider/user/list", List.class);
    }

    @GetMapping("/list-by-openfeign")
    public List<PersonInfo> getPersonListUseOpenFeign() {
        log.info("通过openfeign调用");
        List<PersonInfo>  list = feignServiceApi.queryAllUser();
        log.info("得到的列表:{}",list);
        return list;
    }
}

到这里,就改造完了,下面需要测试一下,验证我们的改造结果。首先把注册中心 springcloud-eureka 启动起来,接着再启动服务提供者 springcloud-service-provider ,最后再启动 springcloud-service-consumer。

都启动之后,在浏览器中访问 http://localhost:8000/ ,可以看到两个服务都注册到注册中心了。

请添加图片描述

接着,我们在浏览器新的标签页访问 http://localhost:8002/consumer/person/list-by-openfeign ,可以看到,有结果返回,同时日志也正常打印出来,这说明整合 OpenFeign 是没问题的。

在这里插入图片描述
在这里插入图片描述
通过这种方式调用服务提供者的接口,我们不再需要配置服务提供者的域名或者 IP ,只需要指定它在注册中心的服务名称便可,这样就实现了前面提到的微服务间的调用与注册中心关联上的目的。

入门篇暂时到这里结束,后面还有服务的熔断及降级、增加网关、增加配置中心等等,留待后面的博客再介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
# springcloud-zone #### 项目介绍 项目为学习用途搭建,主要包括以下模块: springcloud-register:服务注册中心 (eureka-server),提供服务注册与发现功能。 springcloud-config:远程配置中心,分为git与native两个版本,为producer提供远程配置。 springcloud-connect:数据连接中心,包含DB、Redis、MQ、Mail等组件的配置入口,只需其他模块在pom中添加依赖并提供相关配置即可快速接入。 springcloud-producer:服务提供者,包含具体的业务逻辑实现等。 springcloud-consumer:服务消费者,从eureka server中获取producer提供的服务。 springcloud-gateway:网关接口,暴露给调用方调用,包含负载均衡、重试、熔断等功能。 springcloud-zipkin:链路跟踪工具,监控并就持久化微服务集群中调用链路的通畅情况,采用rabbitmq异步传输、elasticsearch负责持久化的方式集成。 #### 软件架构 1、JDK:jdk-8u181-windows-x64。 2、MAVEN:apache-maven-3.5.4 3、IDE:spring-tool-suite-3.9.3.RELEASE-e4.7.3-win32-x86_64 4、springboot:1.5.10.RELEASE。 5、springcloud:Edgware.SR2版本 #### 安装教程 需要提前安装如下程序: 1、ActiveMQ。 2、RabbitMQ。 3、Redis 4、Elasticsearch。 5、Elasticsearch-head。 6、MYSQL(执行springcloud-producer目录src/main/resources/templates/datasource.text中的建表语句) #### 使用说明 项目运行顺序: 1、 springcloud-register, 2、 springcloud-config-native或者springcloud-config-git: 启动git远程配置中心需要修改springcloud-producer项目的bootstrap.yml配置文件,并将配置配件上传到git上。 3、springcloud-zipkin。 4、 springcloud-producer。 5、springcloud-consumer。 6、springcloud-gateway. 注: 在测试gateway负载均衡时可以启动单个项目的多个实例,具体方式如下: 1、项目启动类右键run as->run configurations..,打开配置框。 2、java application右键new,打开新建窗口。 3、顶部tab选中Main,在name中填写启动类名称,project中填写项目名称,main class中填写启动类详细路径+类名。 4、顶部tab选中Arguments,在VM arguments中填写-Dserver.port=端口号,比如-Dserver.port=8080 5、点击run即可以配置的端口号启动多个项目实例了。 #### 参与贡献 ningchongqing
Spring Cloud中常用的负载均衡组件有Ribbon和OpenFegin。在Spring Cloud H版及之前的版本中,主要使用的是Ribbon和OpenFegin作为负载均衡的方案。然而,在Spring Cloud 2020版本之后,官方宣布剔除了除了eureka-server和eureka-client以外的所有Netflix组件,并推荐使用Spring Cloud Loadbalancer替代。尽管如此,Ribbon和OpenFegin仍然是目前主流的负载均衡解决方案。因此,在介绍负载均衡组件时,通常会涉及到Ribbon和OpenFegin。 Ribbon作为负载均衡器在分布式网络中扮演着非常重要的角色。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [一文详解 Spring Cloud 负载均衡!](https://blog.csdn.net/m0_71777195/article/details/128913837)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [SpringCloud之负载均衡详解](https://blog.csdn.net/weixin_45717638/article/details/120111957)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值