通过Nacos注册中心结合OpenFeign实现基础的微服务通信

概述

在前几篇文章中我记录了通过Netty基于WebSocket实现的即时通信APP项目,目前做到了个人对个人的聊天和附近的人(通过Redis GeoHash实现)功能。其他的功能设计无非是对数据库的增删改查,但这样的项目并不算是一个有趣的项目。

因此我打算将其拆分为微服务,顺便应用一下好早好早以前学习过的一些知识,巩固一下。

开始

拆分项目与配置依赖

首先,在之前的项目中大概分为三个模块:

  • 基于Netty的聊天服务
  • 基于FastDFS的文件存储服务
  • 基于SpringDataJPA的数据存储服务

很显然,我可以直接将其抽离出来,将其独立起来。步骤是,对我们的项目右键——新建——模块。这样就可以基于本项目创建一个模块。

但值得注意的是,拆出来之后我们需要为其加入独立的启动类与配置类
1.png

其后,我们需要迁移各个模块所需要的pom依赖。然后在主项目pom文件中加入以下依赖。这些依赖中,主要规定了我们本项目对应的SpringCloud环境中所对应的依赖的版本号。因此我们之后子模块的依赖项一般就不用写上版本号了。因为我们本次引入的依赖项已经为我们规定好了。

         <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.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Hoxton.SR3</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>2.2.5.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

注册中心

安装客户端

如标题所示,此次项目使用了Nacos作为注册中心。第一步需要先下载它的客户端。
下载地址: https://gitee.com/myzhhc/nacos/blob/master/nacos-server-1.3.2.zip

解压后进入/bin目录,执行一下命令。目的是将其启动,其后参数 「-m standalone」是以单例形式运行,否则默认为集群式启动。

sh startup.sh -m standalone

2.png

其后可以根据终端输出的内容「/logs/start.out」查看运行日志,一般我们直接访问http://127.0.0.1:8848/nacos/index.htm」就可以登入Nacos的后台了。账号和密码默认都是「nacos」。

注册服务

首先我们需要引入以下依赖。

    <!--注册中心-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

然后加入以下配置。「server-addr」中是你的nacos地址。

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

其后在启动器之上加入「@EnableDiscoveryClient」注解就好了。当项目启动后,我们在Nacos后台的服务列表中就可以看到我们的服务了。

微服务之间的通讯

之前了解过,一般情况下微服务目前有两种通讯的形式,一中是SpringCloud提倡的网络请求式(restful)和dubbo的rpc协议。

简单的来说,restful形式就是通过从注册中心中获取对应的服务列表,然后直接通过它所提供的接口地址发起网络访问请求。但我们并不习惯于这种形式,很是麻烦。

所以我们可以通过OpenFeign这个库来帮助我们实现具体的请求,我们编写一个接口对应一下服务的接口,这样写起来会很舒服。

使用

首先我们需要引入依赖。

    <!--服务方法映射-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>

然后在启动类之上加入「@EnableFeignClients」注解。

其后我们就可以编写对应的映射类了。代码如下。

首先需要在映射类上加入「@FeignClient」注解,并声明是要请求哪一个服务,一定要确保这个服务是开启状态。

其后编写对应的接口就好了。

@FeignClient(name = "nonsense-file-service")
public interface FileService {

    @PostMapping(value = "/file/upload/user-face-image",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    AjaxResult uploadUserFaceImage(@RequestPart(value = "file",required = false) MultipartFile file);

    @GetMapping("/file/delete/{path}")
    @ApiOperation(value = "删除存储服务器文件")
    AjaxResult delete(@PathVariable(value = "path",required = false) String path);

}

值得注意的是,每一个参数注解之后我们都要设置「required」属性为诶false。因为我们当前的服务在启动的时候需要初始化这个接口,但并不能提供参数,因此会产生报错。

其后如果参数是文件流形式的数据,就会出现问题。

拥有文件流参数的接口映射

上述说了,一般情况一个接口中如果拥有文件流类型的参数,那么就会导致我们对应的服务无法解析这个参数,因为openfeign在做映射操作的时候所发送的数据包的content-type并不是「form-data」形式,因此我们需要主动进行更改。

配置类。

public class FeignMultipartSupportConfig {
    @Bean
    @Primary
    @Scope("prototype")
    public Encoder multipartFormEncoder() {
        return new SpringFormEncoder();
    }

    @Bean
    public feign.Logger.Level multipartLoggerLevel() {
        return feign.Logger.Level.FULL;
    }
}

接口。在上述的代码中你应该已经看到了,我们在「@PostMapping」的注解添加了「consumes」参数,目的就是声明这个请求的类型是基于「form-data」形式的。

    @PostMapping(value = "/file/upload/user-face-image",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
AjaxResult uploadUserFaceImage(@RequestPart(value = "file",required = false) MultipartFile file);