• Spring Cloud Alibaba Nacos 服务发现


    1.Nacos 简介

    发音: /nɑ:kəʊs/
    全称:Name and Config Service,nacos 是其首字母的拼写。
    Nacos 的核心功能 = 服务注册 + 动态配置
    可以理解为 Nacos = SpringCloud Eureka + SpringCloud Config

    2.什么是服务发现

    服务消费者怎么找到服务提供者的机制就是服务发现。

    3.实现服务发现机制需要解决很多的问题

    健康检查:
    问题:服务实例故障了,无法主动注销自己的信息怎么办?
    方案:通过心跳机制进行健康检查,注册中心删除无心跳的实例信息

    本地缓存:
    问题:每次服务调用之前都查询注册中心,性能差、不可靠,怎么办?
    方案:本地缓存、定时更新(定时查询服务列表、服务注册中心主动推送)

    数据同步:
    问题:注册中心集群中各个节点的数据如何同步?
    方案:强一致性,例如 ZooKeeper。弱一致性,例如 Eureka。

    4.Nacos 特征与优势

     5.Nacos环境搭建

    官网文档:https://nacos.io/zh-cn/docs/quick-start.html

    下载地址:https://gitee.com/mirrors/Nacos、https://github.com/alibaba/nacos/releases

    Spring Boot 2.3.x:https://github.com/alibaba/nacos/releases/tag/1.4.1

    windows安装方式

    选择 nacos-server-1.4.1.zip 进行下载

    解压进入到 C:Software acos-server-1.4.1in 目录

    双击 startup.cmd 一闪而过代表失败,注意Java环境是否安装和配置。

    浏览器访问:http://127.0.0.1:8848/nacos

    用户名和密码都是nacos

    服务注册(linux)

    curl -X POST 'http://127.0.0.1:8848/nacos/v1/ns/instance?serviceName=nacos.naming.serviceName&ip=20.18.7.10&port=8080'

    服务发现(linux)

    curl -X GET 'http://127.0.0.1:8848/nacos/v1/ns/instance/list?serviceName=nacos.naming.serviceName'

    使用 Postman

    File => Import => Raw test

    粘贴curl命令

    6.服务提供者和消费者整合Nacos

    6.1 provider(服务提供者)

    6.1.1 加依赖

    <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    6.1.2 加注解

    package com.example.serviceprovider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    // 加注解(开启服务发现)
    @EnableDiscoveryClient
    public class ServiceProviderApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceProviderApplication.class, args);
        }
    
    }

    6.1.3 改配置

    server:
      port: 8081
    spring:
      application:
        name: service-provider
    # 添加 nacos 地址 cloud: nacos: discovery: server
    -addr: localhost:8848 namespace: 23ffbc32-5bde-4451-9683-c346220fa282 group: g1 cluster-name: beijing

    6.1.4 创建测试接口

    package com.example.serviceprovider;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
        @GetMapping("hello")
        public String hello(@RequestParam String name){
            return "hello " + name;
        }
    }

    6.2 consumer(消费者)

    6.2.1 加依赖

    <dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>

    6.2.2 加注解

    package com.example.serviceprovider;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
    @SpringBootApplication
    // 加注解(开启服务发现)
    @EnableDiscoveryClient
    public class ServiceConsumerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServiceConsumerApplication.class, args);
        }
    
    }

    6.2.3 改配置

    server:
      port: 8082
    spring:
      application:
        name: service-consumer
      cloud:
        nacos:
          discovery:
            server-addr: localhost:8848

    6.2.4  配置 RestTemplate

    package com.example.serviceprovider;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.client.RestTemplate;
    
    @Configuration
    public class ConsumerConfig {
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    }

    6.2.5 发起服务调用

    package com.example.serviceprovider;
    
    import org.springframework.beans.factory.annotation.Autowired;
    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.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import java.net.URI;
    
    
    @RestController
    public class TestController {
        // 引入 RestTemplate
        @Autowired
        RestTemplate restTemplate;
    
        // 引入 LoadBalancerClient
        @Autowired
        LoadBalancerClient loadBalancerClient;
    
        @GetMapping("hello")
        public String hello(@RequestParam String name) {
            String result = "";
    
            // 根据服务名获取服务实例
            ServiceInstance serviceInstance = loadBalancerClient.choose("service-provider");
    
            // 发起调用
            URI uri = serviceInstance.getUri();
            result = restTemplate.getForObject(uri + "/hello?name=test", String.class);
    
            // 返回结果
            return result;
        }
    }

     7.Nacos 服务领域模型

    namespace :命名空间ID

    group:组

    cluster-name:集群

    Nacos 三层数据模型:NameSpace, Group, Service

    Nacos 服务领域模型:NameSpace, Group, Service,Cluster, Instance
    8.负载均衡与权重

    负载均衡的类型 

    服务端负载均衡:如nginx 根据负载均衡策略选择某个实例转发请求

    客服端负载均衡:根据自己实现的负载均衡策略选择

    8.1 provider(服务提供者),使用配置的服务端口号

    package com.example.serviceprovider;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
        @Value("${server.port}")
        Integer port;
    
        @GetMapping("hello")
        public String hello(@RequestParam String name){
            return "hello " + name + " " + port;
        }
    }

    8.2 consumer(消费者),使用负载均衡注解

    package com.example.serviceprovider;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    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 ConsumerConfig {
        // 使用负载均衡注解
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
    }

    服务调用

    package com.example.serviceprovider;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    public class TestLBController {
        @Autowired
        RestTemplate restTemplate;
    
        @GetMapping("/testlb")
        public String testlb(@RequestParam String name){
            String  result = "";
    result = restTemplate.getForObject("http://service-provider/hello?name=" + name, String.class); return result; } }

    负载均衡策略

      SpringBoot 配置文件修改负载均衡策略

    package com.example.serviceprovider;
    
    import com.netflix.loadbalancer.IRule;
    import com.netflix.loadbalancer.RandomRule;
    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 ConsumerConfig {
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
       // 负载均衡策略
        @Bean
        public IRule iRule(){
    return new RandomRule();
      } }

    8.3 自定义基于权重的负载均衡策略的方法

     服务消费者中实现基于权重的负载均衡策略

    package com.example.serviceprovider;
    
    import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
    import com.alibaba.cloud.nacos.ribbon.NacosServer;
    import com.alibaba.nacos.api.naming.NamingService;
    import com.alibaba.nacos.api.naming.pojo.Instance;
    import com.netflix.client.config.IClientConfig;
    import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    import com.netflix.loadbalancer.BaseLoadBalancer;
    import com.netflix.loadbalancer.Server;
    import org.springframework.beans.factory.annotation.Autowired;
    
    public class NacosWeightRule extends AbstractLoadBalancerRule {
        // 引入 NacosDiscoveryProperties
        @Autowired
        private NacosDiscoveryProperties nacosDiscoveryProperties;
    
        // 重写 choose 方法
        @Override
        public Server choose(Object o) {
            // 获取服务提供者的名字
            // 拿到 nacos 的命名服务对象
            // 通过 nacos 的命名服务根据权重获取实例
            // 封装 server 对象,返回
    
            BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
            String name = loadBalancer.getName();
    NamingService namingService
    = nacosDiscoveryProperties.namingServiceInstance(); try { Instance instance = namingService.selectOneHealthyInstance(name); return new NacosServer(instance); }catch (Exception e){ e.printStackTrace(); } return null; } @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } }

    Nacos配置修改权重配置

    @Configuration
    public class ConsumerConfig {
        @LoadBalanced
        @Bean
        public RestTemplate restTemplate(){
            return new RestTemplate();
        }
    
        @Bean
        public IRule iRule(){
           //根据权重的负载均衡策略
            return new NacosWeightRule();
        }
    
    }

    9.Nacos集群部署

    9.1 创建数据库和表

    使用sql脚本创建数据库

    nacos-server => conf  => nacos-mysql.sql

    9.2 配置MySQL连接

    nacos-server => conf  =>  application.properties

    # 表明用MySQL作为后端存储
    spring.datasource.platform=mysql
    # 有几个数据库实例
    db.num=1
    # 第1个实例的地址
    db.url.0=jdbc:mysql://[mysqlIP]/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout
    =3000&autoReconnect=true
    db.user=[数据库用户名]
    db.password=[数据库密码]

    9.3 配置集群节点IP端口

    nacos-server => conf  =>  application.properties

     

    # nacos01
    server.port=8841


    # nacos02
    server.port=8842


    # nacos03
    server.port=8843

    nacos-server => conf  =>  cluster.conf.example 复制一份 去掉后缀example ,每个集群实例配置,相同配置文件。

    server 127.0.0.1:8841;
    server 127.0.0.1:8842;
    server 127.0.0.1:8843;

    启动各个nacos 

    9.4 配置Nginx

    nginx.conf 配置文件 include servers/* 意思是加载servers文件夹下所以配置文件,所以进入到servers文件夹 创建 nocos.conf 配置文件,以下是nocos.conf 内容

    upstream nacos {
     server 127.0.0.1:8841;
     server 127.0.0.1:8842;
     server 127.0.0.1:8843;
    }
    server { listen
    9090; server_name localhost; location /nacos/ { proxy_pass http://nacos; } }
  • 相关阅读:
    前端开发者应该知道的 CSS 小技巧
    css3制作六边形图片
    css3 绘制优惠券
    flex css 布局
    js 微信分享
    JS判断移动设备最佳方法 并实现跳转至手机版网页
    ajax 提交成功页面跳转问题
    css相关tips
    无阻塞加载和defer、async
    常用排序算法
  • 原文地址:https://www.cnblogs.com/lilb/p/14408065.html
Copyright © 2020-2023  润新知