【微服务】- Nacos - 注册中心

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到这里,当服务需要调用其它服务时,就到这里找到服务的地址,进行调用。
😄生命不息,写作不止
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 一个有梦有戏的人 @怒放吧德德
🌝分享学习心得,欢迎指正,大家一起学习成长!

上一次介绍了Nacos的简介以及简要理解,这次就来使用Nacos整合SpringCloud Alibaba。
努力克制自己,拒绝摆烂!

在这里插入图片描述

什么是服务注册

服务注册表是注册中心的核心,它用来记录各个微服务实例的信息,例如微服务的名称、IP、端口等。服务注册表提供查询API和管理API,查询API用于查询可用的微服务实例,管理API用于服务的注册与注销。提供者将服务注册到注册中心,注册中心会对服务进行实例健康监控,消费者通过注册中心进行服务发现,在进行服务调用。通常服务调用会使用负载均衡,常见负载均衡有ribbon或者feign。
image

对于注册中心的理解,可以看一下 CSDN10分钟带你彻底搞懂注册中心_Apple_Web的博客-CSDN博客_什么是注册中心

什么是服务发现

在微服务架构中,整个系统会按职责能力划分为多个服务,通过服务之间协作来实现业务目标。这样在我们的代码中免不了要进行服务间的远程调用,服务的消费方要调用服务的生产方,为了完成一次请求,消费方需要知道服务生产方的网络位置(IP地址和端口号)。
image
再看这图,将每个服务集群都注册到注册中心,由其统一管理。在服务中心就会有服务注册表,在服务实例本身并不记录服务生产方的网络地址,所有服务实例内部都会包含服务发现客户端。

1)、在每个服务启动的时候,服务会向注册中心(Nacos)注册服务,上报自己的网络地址(服务名,端口号等)信息。服务中心就会形成服务注册表,这是服务发现的核心。它是存储了所有服务实例的数据库。
2)、客户端会定期从服务中心拉取服务注册表,缓存在客户端。
3)、如果一个服务有许多实例集群,那就需要设置负载均衡策略,从中选出一个来。

在微服务环境中,由于服务运行实例的网络地址是不断动态变化的,服务实例数量的动态变化 ,因此无法使用固定的配置文件来记录服务提供方的网络地址,必须使用动态的服务发现机制用于实现微服务间的相互感知。各服务实例会上报自己的网络地址,这样服务中心就形成了一个完整的服务注册表,各服务实例会通过服务发现中心来获取访问目标服务的网络地址,从而实现服务发现的机制。

实例

在之前已经更新了一篇 【微服务】Nacos初体验,里面介绍了Nacos的基础使用,现在来通过SpringCloud实现一个实例。

创建父工程

创建父级springcloud工程,pom.xml文件如下,这里需要注意的是版本问题,可以在springcloud-alibaba的开源项目中查看具体地址:版本说明
image

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>service-goods</module>
        <module>service-store</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.lyd</groupId>
    <artifactId>spring-cloud-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-cloud-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2020.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    </dependencies>
    <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>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

创建服务

创建一个maven模块,编写启动类和bootstrap.yml配置文件
需要在pom添加以下依赖坐标:

  • spring-cloud-starter-alibaba-nacos-discovery:将 Nacos 作为注册中心,并实现对它的自动配置与服务发现
  • spring-boot-starter-web:web启动器,为我们提供了嵌入的 Servlet 容器以及 SpringMVC 的依赖,并为 Spring MVC 提供了大量自动配置,可以适用于大多数 Web 开发场景。
<dependencies>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

启动器类需要添加注解
@EnableDiscoveryClient: 将微服务注册到服务发现组件上,能够让注册中心能够发现,扫描到改服务。

package com.lyd.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
 * @author: lyd
 * @description: 启动类
 * @Date: 2022/9/20
 */
@EnableDiscoveryClient
@SpringBootApplication
public class GoodsApplication {
    public static void main(String[] args) {
        SpringApplication.run(GoodsApplication.class, args);
    }
}

在bootstrap.yml文件上编写一些配置
修改端口号,服务名字等。ephemeral:表示注册的实例的属性,默认是true

server:
  port: 8000
spring:
  application:
    name: service-goods
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        ephemeral: false # false为永久实例,true表示临时实例开启,注册为临时实例

在View/Tool Windows 下面有个services可以打开查看服务,有时候会有提示打开,在添加springboot就行。
image
通过右键copy Configuration 可以赋值多个实例,在VM-options中写 -Dserver.port=????来配置新的实例的端口号
image
运行启动,就会吧服务注册到nacos注册中,此时可以在nacos网页中查看。
image
这里能够显示服务的集群、状态等信息,也可以进行其他操作。
接下来编写服务的一些具体模拟业务,在让服务之间相互调用。

编写模拟api

在service-store中有这么一个控制类,通过/api/store/id返回访问的端口和一个integer数值

package com.lyd.demo.controller;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
 * @author: lyd
 * @description: api
 * @Date: 2022/9/21
 */
@RestController
@RequestMapping("/api/store")
public class StoreController {
    @Value("${server.port}")
    private String currentPort;
    @GetMapping("/{id}")
    public Map<String, Object> getStoreNum(@PathVariable String id) {
        Map<String, Object> map = new HashMap<>();
        map.put("port", currentPort);
        map.put("num", 10);
        return map;
    }
}

在server-goods服务中需要有一个实体类,模拟请求的数据实体。

package com.lyd.demo.entity;
import lombok.Data;
/**
 * @author: lyd
 * @description: 商品实体类
 * @Date: 2022/9/21
 */
@Data
public class GoodsDto {
    private Long uid;
    private Integer number;
    private String name;
    private String code;
    private String size;
    private Double price;
    private String currentPort;
    private String serverPort;
}

编写控制类,暴露api接口,等下就是调用这个接口,并且通过RestTemplate.getForObject来进行服务间的调用,在此需要导入负载均衡策略的坐标。并且可以在启动器中注入bean,开启负载均衡。

<!--负载均衡-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

在启动类中去注入bean并且加上注解@LoadBalanced

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

具体控制类代码如下:
注意URL是http://service-store/api/store/通过服务名来的,这样restTemplate就能使用负载均衡策略。

package com.lyd.demo.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lyd.demo.entity.GoodsDto;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
/**
 * @author: lyd
 * @description: api
 * @Date: 2022/9/21
 */
@RestController
@RequestMapping("/api")
public class GoodsController {
    @Autowired
    private RestTemplate restTemplate;
    @Value("${server.port}")
    private String currentPort;
    @GetMapping("/{uid}")
    public GoodsDto getGoodsNum(@PathVariable String uid) throws JsonProcessingException {
        GoodsDto goodsDto = new GoodsDto();
        goodsDto.setUid(1L);
        goodsDto.setName("笔记本");
        goodsDto.setCode("note:1");
        goodsDto.setSize("A6");
        goodsDto.setPrice(5.88);
        // 向service-store服务请求数据
        String object = restTemplate.getForObject("http://service-store/api/store/" + uid, String.class);
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.readValue(object, Map.class);
        Integer number = (Integer) map.get("num");
        String port = (String) map.get("port");
        goodsDto.setNumber(number);
        goodsDto.setCurrentPort("请求的端口:" + port);
        goodsDto.setServerPort("当前的端口:" + currentPort);
        return goodsDto;
    }
}

启动Nacos服务器后就可以启动这些服务,为了模拟负载均衡的效果,store服务实例就复制了两个
image

启动之后访问:http://localhost:8000/api/1 就可以看到输出的结果,每次输出的请求端口都不一样。
image
image

今天算是挺坎坷的,之前用来启动若依框架的nacos服务器不知为什么就不能用了,于是搞了好久干脆重新安装一个Nacos服务器,最后才成功。

👍创作不易,可能有些语言不是很通畅,如有错误请指正,感谢观看!记得点赞哦!👍

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
4月前
|
Cloud Native Java Nacos
微服务时代的新宠儿!Spring Cloud Nacos实战指南,带你玩转服务发现与配置管理,拥抱云原生潮流!
【8月更文挑战第29天】Spring Cloud Nacos作为微服务架构中的新兴之星,凭借其轻量、高效的特点,迅速成为服务发现、配置管理和治理的首选方案。Nacos(命名和配置服务)由阿里巴巴开源,为云原生应用提供了动态服务发现及配置管理等功能,简化了服务间的调用与依赖管理。本文将指导你通过五个步骤在Spring Boot项目中集成Nacos,实现服务注册、发现及配置动态管理,从而轻松搭建出高效的微服务环境。
274 0
|
20天前
|
存储 缓存 负载均衡
Nacos注册中心
Nacos注册中心
46 1
Nacos注册中心
|
20天前
|
网络安全 Nacos 开发者
Nacos作为流行的微服务注册与配置中心,“节点提示暂时不可用”是常见的问题之一
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,“节点提示暂时不可用”是常见的问题之一。本文将探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务的正常运行。通过检查服务实例状态、网络连接、Nacos配置、调整健康检查策略等步骤,可以有效解决这一问题。
31 4
|
20天前
|
Java 网络安全 Nacos
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。
Nacos作为流行的微服务注册与配置中心,其稳定性和易用性备受青睐。然而,实际使用中常遇到“客户端不发送心跳检测”的问题。本文深入探讨该问题的原因及解决方案,帮助开发者快速定位并解决问题,确保服务正常运行。通过检查客户端配置、网络连接、日志、版本兼容性、心跳策略、注册状态、重启应用和环境变量等步骤,系统地排查和解决这一问题。
40 3
|
20天前
|
安全 Nacos 数据库
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改
Nacos是一款流行的微服务注册与配置中心,但直接暴露在公网中可能导致非法访问和数据库篡改。本文详细探讨了这一问题的原因及解决方案,包括限制公网访问、使用HTTPS、强化数据库安全、启用访问控制、监控和审计等步骤,帮助开发者确保服务的安全运行。
29 3
|
2月前
|
Java Nacos 微服务
微服务中间件之Nacos
Nacos是阿里巴巴开源的动态服务发现、配置管理和服务管理平台,支持服务注册与发现、配置管理及服务健康监测。采用Spring Cloud、Spring Boot、Raft算法等技术,适用于微服务架构和云原生应用,提供简单易用的安装部署方式和丰富的应用场景。
175 2
|
3月前
|
Kubernetes Nacos 容器
nacos注册不上
我正在使用开源的Nacos,并已在Kubernetes中部署了Nacos服务,通过端口映射可在集群外访问Nacos控制台。Kubernetes使用NodePort类型暴露了8848、9848、9849、7848和9555端口,但在尝试注册时遇到问题,出现“Client not connected, current status: STARTING”的错误,导致启动失败。
|
2月前
|
负载均衡 算法 Nacos
SpringCloud 微服务nacos和eureka
SpringCloud 微服务nacos和eureka
64 0
|
3月前
|
负载均衡 Java Nacos
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
微服务介绍、SpringCloud、服务拆分和远程调用、Eureka注册中心、Ribbon负载均衡、Nacos注册中心
SpringCloud基础1——远程调用、Eureka,Nacos注册中心、Ribbon负载均衡
|
4月前
|
存储 供应链 Nacos
Nacos Stream 引领微服务异步消息潮流,为数字化转型保驾护航,你跟上了吗?
【8月更文挑战第29天】在微服务架构中,异步消息处理框架至关重要。Nacos Stream 通过可靠的消息传递机制、优秀的扩展性及灵活的消息过滤与路由功能,在电商系统等场景下展现了巨大价值。其简化了开发过程,支持高并发消息处理,确保了微服务系统的稳定运行与平滑扩展,为复杂系统的构建提供了强有力的消息通信保障。
37 0
下一篇
无影云桌面