Nacos 两大组件
组件 | 描述 | 功能 |
Nacos Server | Nacos 服务端,与 Eureka Server 不同,Nacos Server 由阿里巴巴团队使用 Java 语言编写并将 Nacos Server 的下载地址给用户,用户只需要直接下载并运行即可。 |
|
Nacos Client | Nacos 客户端,通常指的是微服务架构中的各个服务,由用户自己搭建,可以使用多种语言编写。 |
|
Nacos注册中心
Nacos 作为服务注册中心可以实现服务的注册与发现,流程如下图。
服务注册中心(Register Service):它是一个 Nacos Server,可以为服务提供者和服务消费者提供服务注册和发现功能。
服务提供者(Provider Service):它是一个 Nacos Client,用于对外服务。它将自己提供的服务注册到服务注册中心,以供服务消费者发现和调用。
服务消费者(Consumer Service):它是一个 Nacos Client,用于消费服务。它可以从服务注册中心获取服务列表,调用所需的服务。
Nacos 实现服务注册与发现的流程如下:
从 Nacos 官方提供的下载页面中,下载 Nacos Server 并运行。
服务提供者 Nacos Client 启动时,会把服务以服务名(spring.application.name)的方式注册到服务注册中心(Nacos Server);
服务消费者 Nacos Client 启动时,也会将自己的服务注册到服务注册中心;
服务消费者在注册服务的同时,它还会从服务注册中心获取一份服务注册列表信息,该列表中包含了所有注册到服务注册中心上的服务的信息(包括服务提供者和自身的信息);
在获取了服务提供者的信息后,服务消费者通过 HTTP 或消息中间件远程调用服务提供者提供的服务。
添加以下依赖(小结:加入springCloud依赖,bootstrap文件才能正常使用)
<!--Spring Cloud 的版本信息-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.4</version>
</dependency>
<!-- nacos 服务注册和发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
在bootstrap.yml配置文件中加入以下配置(加载优先级:bootstrap>application)
server:
servlet:
context-path: /content
port: 63040
#微服务配置
spring:
application:
name: content-service # nacos默认会把服务名作为dataID前缀
cloud:
nacos:
discovery:
server-addr: 175.178.67.236:8848 # 服务器的地址 + 端口号(Nacos默认端口号8848)
namespace: 6666 # 命令空间ID
group: xuecheng # 一般用来区分项目,如果没有配置Group,则默认值为DEFAULT_GROUP
profiles:
active: dev # 环境标识
在启动类里使用 @EnableDiscoveryClient 注解开启 Nacos 服务发现功能
package com.xuecheng.content;
import com.spring4all.swagger.EnableSwagger2Doc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@EnableSwagger2Doc
@EnableDiscoveryClient
@SpringBootApplication
public class ContentApplication {
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(ContentApplication.class);
DefaultProfileUtil.addDefaultProfile(app);
Environment env = app.run(args).getEnvironment();
String protocol = "http";
if (env.getProperty("server.ssl.key-store") != null) {
protocol = "https";
}
log.info("\n----------------------------------------------------------\n\t" +
"Application '{}' is running! Access URLs:\n\t" +
"Local: \t\t{}://localhost:{}\n\t" +
"External: \t{}://{}:{}\n\t" +
"Profile(s): \t{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"),
protocol,
env.getProperty("server.port"),
protocol,
InetAddress.getLocalHost().getHostAddress(),
env.getProperty("server.port"),
DefaultProfileUtil.getActiveProfiles(env));
String configServerStatus = env.getProperty("configserver.status");
log.info("\n----------------------------------------------------------\n\t" +
"Config Server: \t{}\n----------------------------------------------------------",
configServerStatus == null ? "Not found or not setup for this application" : configServerStatus);
}
}
final class DefaultProfileUtil {
private static final String SPRING_PROFILE_DEFAULT = "spring.profiles.default";
private DefaultProfileUtil() {
}
public static void addDefaultProfile(SpringApplication app) {
Map<String, Object> defProperties = new HashMap();
defProperties.put(SPRING_PROFILE_DEFAULT, "dev");
app.setDefaultProperties(defProperties);
}
public static String[] getActiveProfiles(Environment env) {
String[] profiles = env.getActiveProfiles();
return profiles.length == 0 ? env.getDefaultProfiles() : profiles;
}
}
在controller层添加一个接口测试
package net.biancheng.c.controller;
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.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class DeptController {
@Value("${server.port}")
private String serverPort;
@GetMapping(value = "/dept/nacos/{id}")
public String getPayment(@PathVariable("id") Integer id) {
return "<h2>服务访问成功!</h2>服务名:content-service <br /> 端口号: " + serverPort + "<br /> 传入的参数:" + id;
}
}
创建一个名为 ApplicationContextBean 的配置类,并使用 @LoadBalanced 注解与 Ribbon 进行集成开启负载均衡功能
package com.xuecheng.content.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextBean {
@Bean
@LoadBalanced //与 Ribbon 集成,并开启负载均衡功能
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}