乐趣区

关于springcloud:一个实例轻松演示Spring-Cloud集成Nacos实例

前言

学习一个技术框架,最疾速的伎俩就是将其集成到我的项目中,体验一下它的性能。在这个过程中,你还踩到很多坑。而排坑的过程,又是一次能力的晋升。

后面咱们写了一些列 Nacos 的文章,通过《学习 Nacos?咱先把服务搞起来,实战教程》的介绍,咱们曾经能够把 Nacos Server 给启动起来了。

这篇文章,咱们就来学习一下如何将 Nacos 集成到 Spring Cloud 我的项目中,同时实例演示一下,基于 Nacos 的微服务之间的两种调用模式。

集成与版本

为了演示这个案例,大家首先要将 Nacos Server 跑起来。同时会构建两个微服务:服务提供方(Provider)和服务生产方(Consumer)。而后,通过两个服务之间的调用及配合查看 Nacos Server 中的注册信息来进行验证。

咱们晓得,Nacos 隶属于 Spring Cloud Alibaba 系列中的组件。所以,在进行集成之前,有一件事肯定要留神,那就是要确保 Spring Cloud、Spring Boot、Spring Cloud Alibaba 版本的统一。不然产生一些莫名其妙的异样。

对于版本信息能够在 https://spring.io/projects/sp…

这里采纳 Spring Boot 的版本为 2.4.2,Spring Cloud 采纳 2020.0.0、Spring Cloud Alibaba 采纳 2021.1。如你采纳其余版本,肯定确保对照关系。

Nacos 服务提供者

依赖配置

创立我的项目 Spring Boot 的我的项目 spring-cloud-alibaba-nacos-provider1,在 pom 文件中增加定义依赖的版本限度:

<properties>
    <java.version>1.8</java.version>
    <spring-boot.version>2.4.2</spring-boot.version>
    <spring-cloud.version>2020.0.0</spring-cloud.version>
    <cloud-alibaba.version>2021.1</cloud-alibaba.version>
</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>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${cloud-alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

而后增加依赖:

<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>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

其中 actuator 为健康检查依赖包,nacos-discovery 为服务发现的依赖包。

配置文件

提供者增加配置(application.yml)

server:
  port: 8081

spring:
  application:
    name: user-service-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

其中 Nacos Server 的地址和端口号默认是 127.0.0.1:8848。name 用来指定此服务的名称,消费者可通过注册的这个名称来进行申请。

业务代码

在编写业务代码之前,咱们先来看一下提供者的启动类:

// 版本不同,低版本须要明确应用 @EnableDiscoveryClient 注解
//@EnableDiscoveryClient
@SpringBootApplication
public class NacosProviderApplication {public static void main(String[] args) {SpringApplication.run(NacosProviderApplication.class, args);
    }
}

留神下面的正文局部,此版本曾经不须要 @EnableDiscoveryClient 注解了,而较低的版本须要增加对应的注解。

上面新建一个 UserController 服务:

@RestController
@RequestMapping("/user")
public class UserController {private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @GetMapping("/getUserById")
    public UserDetail getUserById(Integer userId) {logger.info("查问用户信息,userId={}", userId);
        UserDetail detail = new UserDetail();
        if (userId == 1) {detail.setUserId(1);
            detail.setUsername("Tom");
        } else {detail.setUserId(2);
            detail.setUsername("Other");
        }
        return detail;
    }
}

其中用到的实体类 UserDetail 为:

public class UserDetail {

    private Integer userId;

    private String username;

    // 省略 getter/setter
}

而后启动服务,查看 Nacos Server,会发现曾经胜利注册。

Nacos 服务消费者

消费者的创立与提供者基本一致,惟一不同的是调用相干的性能。

创我的项目

创立 Spring Boot 我的项目 spring-cloud-alibaba-nacos-consumer1,pom 中的依赖与提供者基本一致,但还须要在它的根底上减少两个依赖:

<!-- consumer 须要额定增加负载平衡的依赖 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
<!-- 基于 Feign 框架进行调用 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

其中 loadbalancer 是用来做服务调用负载平衡的,如果不增加此依赖,在调用的过程中会呈现如下一次:

java.net.UnknownHostException: user-provider
    at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:196) ~[na:1.8.0_271]
    at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:394) ~[na:1.8.0_271]
    at java.net.Socket.connect(Socket.java:606) ~[na:1.8.0_271]
    at java.net.Socket.connect(Socket.java:555) ~[na:1.8.0_271]

而 openfeign 是用来实现基于 feign 框架的微服务调用,也就是让服务之间的调用更加不便。这个框架是可选的,如果你想基于 RestTemplate 形式进行调用,则不须要此框架的依赖。

配置文件

消费者增加配置(application.yml):

spring:
  application:
    name: user-service-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

# 消费者将要去拜访的微服务名称(注册胜利进 nacos 的微服务提供者)service-url:
  nacos-user-service: http://user-service-provider

同样 server-addr 指定注册 Nacos Server 的地址和端口。而配置中定义的 service-url 中便用到了服务提供者的服务名称 user-service-provider。

业务代码

对于启动类上的注解,与提供者一样,如果依据应用的版本决定是否应用 @EnableDiscoveryClient 注解。

创立 UserController:

@RestController
@RequestMapping("/order")
public class UserController {

    @Resource
    private UserFeignService userFeignService;

    @Resource
    private RestTemplate restTemplate;

    @Value("${service-url.nacos-user-service}")
    private String userProvider;

    @GetMapping("getUserInfo")
    public UserDetail getUserInfo() {
        int userId = 1;
        ResponseEntity<UserDetail> result = restTemplate.getForEntity(userProvider + "/user/getUserById?userId=" + userId, UserDetail.class);
        return result.getBody();}

    @GetMapping("getUserInfo1")
    public UserDetail getUserInfoByFeign() {return userFeignService.getUserById(2);
    }

}

上述代码中展现了两种形式的申请,其中注入的 RestTemplate 和 getUserInfo 办法是一组,注入的 UserFeignService 和 getUserInfoByFeign 办法是一组。前者是基于 RestTemplate 形式申请,后者是基于 Feign 框架的模式进行申请的。

先来看基于 RestTemplate 形式的配置,须要先来实例化一下 RestTemplate:

@Configuration
public class RestTemplateConfig {

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

}

留神,这里应用了 @LoadBalanced 注解,RestTemplateCustomizer 会给标有 @LoadBalance 的 RestTemplate 增加一个拦截器,拦截器的作用就是对申请的 URI 进行转换获取到具体应该申请哪个服务实例 ServiceInstance。如果短少这个注解,也会报下面提到的异样。

基于 Feign 的模式对应的 UserFeignService 如下:

@FeignClient(name = "user-service-provider")
public interface UserFeignService {

    /**
     * 基于 Feign 的接口调用
     *
     * @param userId 用户 ID
     * @return UserDetail
     */
    @GetMapping(value = "/user/getUserById")
    UserDetail getUserById(@RequestParam Integer userId);
}

其中 @FeignClient 通过 name 属性指定调用微服务的名称,上面定义的办法则对应提供者的接口。

启动服务,查看 Nacos Server 的注册状况。

后果验证

此时,本地别离申请两个 URL 地址:

http://localhost:8080/order/getUserInfo
http://localhost:8080/order/getUserInfo1

拜访一下,能够胜利的返回后果:

// getUserInfo 对应后果
{
"userId": 1,
"username": "Tom"
}
// getUserInfo1 对应后果
{
"userId": 2,
"username": "Other"
}

至此,Spring Cloud 集成 Nacos 实例演示结束,残缺的源代码地址:https://github.com/secbr/spri…。

小结

通过上述实例,咱们胜利的将 Nacos 集成到了 Spring Cloud 当中。相对来说,整个过程还是比较简单的,在实际时,大家惟一须要留神的就是版本问题。Spring Cloud 的不同版本,内容和用法调整较大,多参考官网文档的阐明。

退出移动版