04-搭建微服务-服务注册与发现(Nacos)和远程调用(openfeign)

0、说明

版本:版本选择

SpringBoot版本:2.3.2.RELEASE

spring-cloud版本:Hoxton.SR9

spring-cloud-alibaba版本:2.2.6.RELEASE

服务注册与发现:

Nacos

远程调用:

openfeign,SpringCloud的子项目之一,是一种声明式、模块化的Http客户端,通过集成Ribbon实现负载均衡,代替RestTemplete组件,实现远程调用。


1、搭建父工程:shiory-cloud

1、建项目 

新建一个maven工程,新建完父工程后,删除src目录,父工程结构

2、改pom.xml文件

pom.xml文件中锁定SpringBoot、SpringCloud、SpringCloud Alibaba的版本,加入以下内容。dependencyManagement标签是锁定版本,并不是真正的依赖。

    <!-- SpringBoot版本-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <!--JDK版本-->
        <java.version>1.8</java.version>
        <!--字符集编码-->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <!--spring-cloud版本-->
        <spring.cloud-version>Hoxton.SR9</spring.cloud-version>
        <!--spring-cloud-alibaba版本-->
        <spring.cloud.alibaba-version>2.2.6.RELEASE</spring.cloud.alibaba-version>
    </properties>

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

    <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun Repository</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

2、提取公共模块:cloud-common

因为微服务项目中,会有很多服务,所以抽取公共部分建成一个模块Module

1、建Module

右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish

2、改pom.xml文件

添加如下依赖

    <dependencies>
        <!--web场景依赖-->
        <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>
        <!--Nacos场景依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--openfeign场景依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

3、新建application.yml文件

resources目录下新建application.yml文件,添加公共配置(nacos连接信息,用于服务注册与发现)

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos-server的地址
        username: nacos # nacos-server用户名
        password: nacos # nacos-server密码

4、新建主启动类

src/main/java中新建一个启动类,添加@EnableDiscoveryClient注解,开启服务注册与发现

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * =====================================================
 * 服务公共模块
 * @author 汐小旅Shiory
 * @date 2021/12/5 13:46
 * =====================================================
 */
@SpringBootApplication
@EnableDiscoveryClient // 服务注册与发现
public class CommonApplication {
    public static void main(String[] args) {
        SpringApplication.run(CommonApplication.class, args);
    }

}

5、项目结构


3、 搭建服务提供者:cloud-demo1

 1、建Module

右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish

2、改pom.xml文件

添加刚才新建的公共模块依赖

    <dependencies>
        <!--公共模块依赖-->
        <dependency>
            <groupId>com.shiory</groupId>
            <artifactId>cloud-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

3、新建application.yml文件

resources目录下新建application.yml文件,并且添加服务名端口,每个模块的服务名和端口必须保证唯一

server:
  port: 7001 # 服务端口号,必须配置,保证唯一
spring:
  application:
    name: cloud-demo1 # 服务名称,必须配置,保证唯一

4、新建主启动类

src/main/java中新建一个启动类,和cloud-common一样,把启动类建在同一级目录一下,比如cloud-common的在com.shiory包下,那这个启动类就建在cloud-demo1的com.shiory包下

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * =====================================================
 * 服务提供者
 * @author 汐小旅Shiory
 * @date 2021/12/5 13:55
 * =====================================================
 */
@SpringBootApplication
public class Demo1Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo1Application.class, args);
    }
}

5、编写对外暴露的接口

也就是要被远程调用的接口:“/demo1/api/callTest

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * =====================================================
 * 服务提供者:对外暴露的接口
 * @author 汐小旅Shiory
 * @date 2021/12/5 14:31
 * =====================================================
 */
@RestController
@RequestMapping("/demo1/api")
public class Demo1ApiController {

    @GetMapping("/callTest")
    public String callTest(@RequestParam(name = "serverName") String serverName) {
        String result = "我是服务提供者,我被服务" + serverName + "调用了!";
        return result;
    }
}

6、项目结构


4、 抽取公共声明式接口模块:cloud-api

因为暴露的接口不可能只会被一个服务调用,也不可能只有一个暴露接口,所以抽取出来,供其他服务调用与使用。

  

1、建Module

右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish

2、改pom.xml文件

添加刚才新建的公共模块依赖

    <dependencies>
        <!--公共模块依赖-->
        <dependency>
            <groupId>com.shiory</groupId>
            <artifactId>cloud-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

3、编写声明式接口

新建一个接口,加上注解@FeignClient(contextId = "上下文Id", value = "服务提供者服务名称")

注意:

1、方法上加请求方式和接口完整路径(例如此处的@GetMapping("/demo1/api/callTest"))。

2、形参一定要加注解(例如此处的@RequestParam注解)

3、声明式接口与服务提供者暴露的接口必须一致


/**
 * =====================================================
 * 声明式接口开发
 * @author 汐小旅Shiory
 * @date 2021/12/5 22:38
 * =====================================================
 */
@Component
@FeignClient(
        contextId = "demo1Api", // 上下文Id,保证唯一
        value = ServiceNameConstants.CLOUD_DEMO1_SERVICE) // 服务名称(服务提供者的服务名称)
public interface Demo1API {

    @GetMapping("/demo1/api/callTest")
    public String callTest(@RequestParam(name = "serverName") String serverName);
}

如果请求路径有共同部分,也可以将共有路径抽取出来,在接口上加上@RequestMapping("/demo1/api")注解。可以写成如下形式

import com.shiory.common.constants.ServiceNameConstants;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * =====================================================
 * 声明式接口开发
 * @author 汐小旅Shiory
 * @date 2021/12/5 22:38
 * =====================================================
 */
@Component
@FeignClient(
        contextId = "demo1Api", // 上下文Id,保证唯一
        value = ServiceNameConstants.CLOUD_DEMO1_SERVICE) // 服务名称(服务提供者的服务名称)
@RequestMapping("/demo1/api")
public interface Demo1API {

    @GetMapping("/callTest")
    public String callTest(@RequestParam(name = "serverName") String serverName);
}

 其中服务名称常量ServiceNameConstants如下

/**
 * =====================================================
 * 服务名称常量
 * @author 汐小旅Shiory
 * @date 2021/12/5 22:43
 * =====================================================
 */
public interface ServiceNameConstants {

    /**
     * cloud-demo1服务名称
     */
    String CLOUD_DEMO1_SERVICE = "cloud-demo1";
}

声明式接口与服务提供者暴露的接口必须一致

4、项目结构


5、 搭建服务消费者:cloud-demo3

 1、建Module

右键项目--New--Module,选择Maven项目,点击Next,选择父工程,输入模块名称,点击Finish

2、改pom.xml文件

添加刚才新建的公共模块依赖,公共声明式接口模块依赖

    <dependencies>
        <!--公共模块依赖-->
        <dependency>
            <groupId>com.shiory</groupId>
            <artifactId>cloud-common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--公共声明式接口模块依赖-->
        <dependency>
            <groupId>com.shiory</groupId>
            <artifactId>cloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

3、新建application.yml文件

resources目录下新建application.yml文件,并且添加服务名端口,每个模块的服务名和端口必须保证唯一

server:
  port: 7003 # 服务端口号,必须配置,保证唯一
spring:
  application:
    name: cloud-demo3 # 服务名称,必须配置,保证唯一

4、新建主启动类

src/main/java中新建一个启动类,添加注解@EnableFeignClients(basePackages = "声明式接口包(cloud-api模块)"),和cloud-common一样,把启动类建在同一级目录一下,比如cloud-common的在com.shiory包下,那这个启动类就建在cloud-demo3的com.shiory包下

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

/**
 * =====================================================
 * 服务消费者
 * @author 汐小旅Shiory
 * @date 2021/12/5 23:13
 * =====================================================
 */
@SpringBootApplication
@EnableFeignClients(basePackages = "com.shiory.api") // 开启openfeign,并扫描声明式接口包
public class Demo3Application {
    public static void main(String[] args) {
        SpringApplication.run(Demo3Application.class, args);
    }
}

5、编写Controller

编写controller,并注入声明式接口,就可以像普通接口调用一样进行远程调用

import com.shiory.api.Demo1API;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * =====================================================
 *
 * @author 汐小旅Shiory
 * @date 2021/12/5 23:14
 * =====================================================
 */
@RestController
@RequestMapping("/demo3")
public class Demo3Controller {

    // 注入声明式接口
    @Autowired
    private Demo1API demo1API;

    @Value("${spring.application.name}")
    private String serverName;

    /**
     * 使用openfeign发起远程调用
     * @return
     */
    @GetMapping("/remoteCall")
    public Map<String,Object> remoteCall() {

        // 发起远程调用
        String remoteResult = demo1API.callTest(serverName);

        Map<String, Object> map = new HashMap<>();
        map.put("remarks", "我是" + serverName + "服务,正在使用openfeign调用!");
        map.put("remoteResult", remoteResult);

        return map;
    }
}

6、项目结构


6、 测试

1、启动Nacos

2、启动服务提供者cloud-demo1,以及服务消费者cloud-demo3

3、查看服务是否注册到Nacos

4、发起请求(请求cloud-demo3中的接口,cloud-demo3接口中远程调用cloud-demo1中的接口)

http://localhost:7003/demo3/remoteCall


7、 小结

1、服务注册与发现(Nacos)

1.1、搭建nacos服务:Windows下搭建Nacos服务

1.2、pom.xml中添加依赖

        <!--Nacos场景依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

1.3、application.yml中配置nacos连接信息 

spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848 # nacos-server的地址
        username: nacos # nacos-server用户名
        password: nacos # nacos-server密码

1.4、启动类上加注解,开启服务注册与发现

@EnableDiscoveryClient // 服务注册与发现

2、远程调用(openfeign)

2.1、pom.xml中添加依赖

        <!--openfeign场景依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2.2、服务提供者

2.2.1、暴露接口

2.2.2、声明式接口开发,接口上使用注解:@FeignClient(contextId = "上下文Id", value = "服务提供者服务名称")

2.3、服务消费者

2.3.1、启动类上加注解:@EnableFeignClients(basePackages = "声明式接口包")

2.3.2、注入声明式接口,发起远程调用

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值