关于后端:Spring-Cloud-AlibabaNacos-Discovery-服务注册与发现

9次阅读

共计 10208 个字符,预计需要花费 26 分钟才能阅读完成。

Nacos Discovery 是什么?

服务发现是微服务架构体系中最要害的组件之一。

如果尝试着用手动的形式来给每一个客户端来配置所有服务提供者的服务列表是一件十分艰难的事,而且也不利于服务的动静扩缩容。Nacos Discovery 能够帮忙用户将服务主动注册到 Nacos 服务端并且可能动静感知和刷新某个服务实例的服务列表。

除此之外,Nacos Discovery 也将服务实例本身的一些元数据信息,例如 host,port,健康检查 URL,主页等 - 注册到 Nacos。
对于 Nacos 的装置及启动请查看文章:Spring Cloud Alibaba:Nacos 装置及应用
本篇将具体介绍 Nacos Discovery 服务注册与发现的一些技术实际。

疾速接入

增加依赖

启动好 Nacos 服务端。而后在我的项目中增加依赖。

<dependency>
 <groupId>com.alibaba.cloud</groupId>
 <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</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">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.xingtuai.example</groupId>
 <artifactId>nacos-discovery-test</artifactId>
 <version>1.0-SNAPSHOT</version>
 <name>nacos-discovery-test</name>
 <parent>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-parent</artifactId>
 <version>${spring.boot.version}</version>
 <relativePath/>
 </parent>
 <properties>
 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 <java.version>1.8</java.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>${spring.cloud.alibaba.version}</version>
 <type>pom</type>
 <scope>import</scope>
 </dependency>
 </dependencies>
 </dependencyManagement>
 <dependencies>
 <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>
 </dependencies>
 <build>
 <plugins>
 <plugin>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-maven-plugin</artifactId>
 </plugin>
 </plugins>
 </build>
</project>

注:在本我的项目的源代码中,依赖对立应用 dependencies 模块治理,且其中 dependencyManagement 节点也在 dependencies 模块中配置,上例仅演示必要的配置项,在我的项目源代码中有些许区别。

启动 Provider 服务提供者

Nacos Discovery 服务注册与发现中,个别有两个角色,一个是 Provider 服务提供者,一个是 Consumer 服务消费者。他们都须要将本身注册到 Naocs 中,这一步叫服务注册。服务提供者向外提供服务,服务消费者通过各种形式调用服务提供者实现业务性能。且一个服务,既能够作为提供者,同时也能够作为消费者。
1. 配置 application.yml
要应用 Nacos,须要在 application.yml 或者 bootstrap.yml 中配置一些基本参数。如下所示:

# Nacos 相干参数
nacos:
 server-addr: 192.168.9.17:8848 username: nacos password: nacos # 命名空间,用作环境隔离
 namespace: 904174a3-d51f-43ed-a456-c4fd7386ecb3  spring:
 application: name: nacos-discovery-provider main: allow-bean-definition-overriding: true cloud: nacos: # 权限认证,nacos.core.auth.enabled=true 时须要增加
 username: ${nacos.username} password: ${nacos.password} discovery: server-addr: ${nacos.server-addr} # 命名空间,用作环境隔离
 namespace: ${nacos.namespace} # 分组,个别依照我的项目进行分组
 group: SPRING_CLOUD_EXAMPLE_GROUP # 自定义元数据
 metadata: # 版本
 version: 1.0 # 地区
 region: hangzhou```
上述配置比较完善,如果须要简化配置,则如下所示:

spring:
application: name: nacos-discovery-provider cloud: nacos: discovery: server-addr: 192.168.9.17:8848 `
2. 开启服务发现
在我的项目启动类上增加注解 @EnableDiscoveryClient 即可。如下所示:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class NacosDiscoveryProviderApplication {public static void main(String[] args) {SpringApplication.run(NacosDiscoveryProviderApplication.class, args);
 }
}

3. 创立 REST 接口
服务提供者须要提供接口以供消费者进行调用,个别应用 RESTful 格调的 HTTP 接口。如下所示:

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;
@RestController
@RequestMapping
public class TestController {@GetMapping("/echo/{message}")
 public String echo(@PathVariable String message) {return "Hello Nacos Discovery" + message;}
}

4. 验证
启动 Provider 服务提供者后,关上 Nacos 控制台,能够看到服务曾经注册下来了,因为我应用的是 dev 开发环境的命名空间,所以服务注册在 dev 的命名空间内。

启动 Consumer 服务消费者

Consumer 服务消费者的依赖的配置根本与 Provider 服务提供者雷同,然而却要比它更简单一点。因为在 Consumer 端须要去调用 Provider 端的 REST 服务。而调用形式也有很多种。
1. RestTemplate 形式
依赖、配置与 Provider 统一。
而后创立 RestTemplate 配置类。如下所示:

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class RestTemplateConfig {@Bean public RestTemplate restTemplate(){return new RestTemplate();
 }
}

而后调用 Provider 服务提供者。如下所示:

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
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 javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping
public class BaseTestController {
 @Resource private LoadBalancerClient loadBalancerClient;
 @Resource private RestTemplate restTemplate;
 @Value("${spring.application.name}")
 private String appName;
 @GetMapping("/echo")
 public String echoAppName() {
 // 应用 LoadBalanceClient 和 RestTemplate 联合的形式来拜访
 // LoadBalanceClient 提供负载平衡的性能,并从 Nacos 中依据服务名获取服务实例
 ServiceInstance serviceInstance = loadBalancerClient.choose("nacos-discovery-provider");
 String url = String.format("http://%s:%s/echo/%s", serviceInstance.getHost(), serviceInstance.getPort(), appName);
 log.info("request url: {}", url);
 return restTemplate.getForObject(url, String.class);
 }
}

启动我的项目后,关上浏览器申请:http://localhost:8080/echo
查看返回后果进行验证。
2. Feign 形式
首先须要增加 Feign 的依赖,如下所示:

<!-- Spring Cloud Feign -->
<dependency>
 <groupId>org.springframework.cloud</groupId>
 <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

增加完依赖当前,须要在我的项目启动类中增加 @EnableFeignClients 注解以开启性能。如下所示:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class NacosDiscoveryConsumerApplication {public static void main(String[] args) {SpringApplication.run(NacosDiscoveryConsumerApplication.class, args);
 }
} ```
而后须要创立一个接口类 `FeignService`,在类中为 Provider 服务提供者提供的服务接口提供对应的拜访办法。如下所示:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**

  • nacos-discovery-provider 为服务提供者的服务名

*/@FeignClient(“nacos-discovery-provider”)
public interface FeignService {
/* 接口定义

  • Provider 服务提供者对应的 REST 接口
    • @param message
  • @return */ @GetMapping(“/echo/{message}”)

public String echo(@PathVariable String message);
}

在 Controller 中调用 `FeignService` 接口实现对 Provider 端的调用。代码如下:

import com.xingtuai.cloud.nacos.discovery.service.FeignService;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@Slf4j
@RestController
@RequestMapping(“feign”)
public class FeignTestController {
@Resource private FeignService feignService;
@Value(“${spring.application.name}”)
private String appName;
@GetMapping(“/echo”)
public String echoAppName() {
return feignService.echo(appName);
}
}

启动我的项目后,关上浏览器申请:[http://localhost:8080/feign/echo](http://localhost:8080/feign/echo)
查看返回后果进行验证。## 多环境隔离
`Nacos Discovery` 与 `Nacos Config` 的环境隔离是一样的,都是通过命名空间 `namespace` 进行辨别。具体请参考之前的文章:[Spring Cloud Alibaba:Nacos Config 配置核心](http://jemgeek.com/archives/2020/spring-cloud-nacos-config.html)
在理论开发中,通过这种形式能够十分好的对各种环境进行隔离辨别,防止服务治理的凌乱。## 联合 Sentinel 熔断
`Sentinel` 是阿里微服务生态中一个比拟重要的组件,性能也比拟多,在此仅简略介绍。后续会有专题对其进行具体的钻研实际。此处联合,次要是在 Feign 调用的时候,进行解决。在调用失败时,能够进行熔断。首先须要增加依赖,如下所示:

<!– Sentinel –>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

在 `application.yml` 中进行配置,如下所示:

nacos:
server-addr: 192.168.9.17:8848 username: nacos password: nacos namespace: 904174a3-d51f-43ed-a456-c4fd7386ecb3sentinel:
dashboard: 192.168.9.17:8883 spring:
application: name: nacos-discovery-sentinel main: allow-bean-definition-overriding: true cloud: nacos: # 权限认证,nacos.core.auth.enabled=true 时须要增加
username: ${nacos.username} password: ${nacos.password} # Nacos 服务注册与发现
discovery: server-addr: ${nacos.server-addr} namespace: ${nacos.namespace} group: SPRING_CLOUD_EXAMPLE_GROUP # Spring Cloud Alibaba Sentinel 配置
sentinel: transport: # Sentinel 控制台
dashboard: ${sentinel.dashboard}
feign:
# 开启 feign 对 sentinel 的反对
sentinel: enabled: true`
创立一个 FeignService 接口办法失败时的回调类 FeignServiceFallback,代码如下:

public class FeignServiceFallback implements FeignService {@Override public String echo(String message) {return "echo fallback, please try again.";}
}

当拜访 echo(String message) 办法失败时,将会进入此回调,返回你须要的数据格式。
除此之外还须要创立一个配置类 FeignConfig,代码如下:

import com.xingtuai.cloud.nacos.discovery.service.fallback.FeignServiceFallback;
import org.springframework.context.annotation.Bean;
public class FeignConfig {@Bean public FeignServiceFallback feignServiceFallback() {return new FeignServiceFallback();
 }
}

而后须要革新一下 FeignService 接口,将 FeignServiceFallbackFeignConfig 设置在注解 @FeignClient 中,革新如下:

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
 * nacos-discovery-provider 为服务提供者的服务名
 */@FeignClient(name = "nacos-discovery-provider", fallback = FeignServiceFallback.class, configuration = FeignConfig.class)
public interface FeignService {
 /** * 接口定义
 * Provider 服务提供者对应的 REST 接口
 * * @param message
 * @return */ @GetMapping("/echo/{message}")
 public String echo(@PathVariable String message);
}

失常拜访时,接口将返回失常的数据,然而当接口出现异常,比方服务提供者下线了,拜访失败的话。那么将会调用 FeignServiceFallback 中的 echo(String message) 办法并返回。这样就防止返回异样,而是返回一个可控的数据,能够用做服务熔断。
Sentinel 相干的常识与实际还有很多,后续会做专题分享,在此不再赘述。

我的项目源代码

GitHub – spring-cloud-example

更多技术文章欢送关注我的博客主页:http://JemGeek.com

点击浏览原文

正文完
 0