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


微服务 - 注册中心 - Nacos

??生命不息,写作不止
?? 继续踏上学习之路,学之分享笔记
?? 总有一天我也能像各位大佬一样
?? 一个有梦有戏的人 @怒放吧德德
??分享学习心得,欢迎指正,大家一起学习成长!

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

在这里插入图片描述

目录
  • 10分钟带你彻底搞懂注册中心_Apple_Web的博客-CSDN博客_什么是注册中心

    什么是服务发现

    在微服务架构中,整个系统会按职责能力划分为多个服务,通过服务之间协作来实现业务目标。这样在我们的代码中免不了要进行服务间的远程调用,服务的消费方要调用服务的生产方,为了完成一次请求,消费方需要知道服务生产方的网络位置(IP地址和端口号)。

    再看这图,将每个服务集群都注册到注册中心,由其统一管理。在服务中心就会有服务注册表,在服务实例本身并不记录服务生产方的网络地址,所有服务实例内部都会包含服务发现客户端。

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

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

    实例

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

    创建父工程

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

    <?xml version="1.0" encoding="UTF-8"?>
    
        4.0.0
        pom
        
            service-goods
            service-store
        
        
            org.springframework.boot
            spring-boot-starter-parent
            2.4.2
             
        
        com.lyd
        spring-cloud-demo
        0.0.1-SNAPSHOT
        spring-cloud-demo
        Demo project for Spring Boot
        
            1.8
            2020.0.1
            2021.1
        
        
            
                org.springframework.cloud
                spring-cloud-starter
            
    
            
                org.projectlombok
                lombok
                true
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
            
                org.springframework.cloud
                spring-cloud-starter-bootstrap
            
        
        
            
                
                    org.springframework.cloud
                    spring-cloud-dependencies
                    ${spring-cloud.version}
                    pom
                    import
                
                
                    com.alibaba.cloud
                    spring-cloud-alibaba-dependencies
                    ${spring-cloud-alibaba.version}
                    pom
                    import
                
            
        
        
            
                
                    org.springframework.boot
                    spring-boot-maven-plugin
                    
                        
                            
                                org.projectlombok
                                lombok
                            
                        
                    
                
            
        
    
    

    创建服务

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

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

    启动器类需要添加注解
    @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就行。

    通过右键copy Configuration 可以赋值多个实例,在VM-options中写 -Dserver.port=????来配置新的实例的端口号

    运行启动,就会吧服务注册到nacos注册中,此时可以在nacos网页中查看。

    这里能够显示服务的集群、状态等信息,也可以进行其他操作。
    接下来编写服务的一些具体模拟业务,在让服务之间相互调用。

    编写模拟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 getStoreNum(@PathVariable String id) {
            Map 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,开启负载均衡。

    
    
        org.springframework.cloud
        spring-cloud-starter-loadbalancer
    
    

    在启动类中去注入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服务实例就复制了两个

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

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

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