二、Nacos服务注册与发现

前言

本文是根据蚂蚁课堂余胜军老师的课程所做笔记,记录的要点,部分自己的理解可能有所偏差,不当之处会进行修改。

微服务服务治理核心概念

在微服务架构通讯中,服务之间依赖关系非常大,如果通过传统的方式管理服务url地址,一旦地址发生变化,还需要人工修改rpc远程调用地址。

所以采用服务url治理技术,治理的技术可以实现对我们的整个实现动态服务注册与发现,本地负载均衡、容错等。

分布式注册中心实现原理

注册中心实际上就是管理我们服务的url信息,能够实现动态感知。

有Dubbo依赖Zookeeper、Eureka、Consul、Nacos

注册中心就是将一个服务的服务id和其IP与端口号作为键值对存放到注册中心,通过服务id可以找到IP地址和端口号。

另一个服务通过注册中心获取到该服务的ip和端口号后,在本地实现rpc调用。

服务名对应的ip地址是一个列表,通过负载均衡算法取出一个地址调用。

Nacos基本介绍

Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。

下载nacos,解压后直接运行bin目录下的start脚本即可

在Linux下使用下面命令代表非集群运行

sh startup.sh -m standalone

默认用8848端口启动,在ip:8848/nacos进入管理面板,默认账号密码都是nacos

服务注册

创建一个会员项目

导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2.0.0.RELEASE</version>
    </dependency>

</dependencies>

配置文件

spring:
  application:
    name: member-nacos #服务名
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848 #注册中心地址

创建一个服务

@RestController
public class UserService {

    @GetMapping("/user")
    public String getUser() {
        return "alibaba-nacos-test";
    }
}

启动项目

如果使用的是eureka,还需要使用注解@EnableEurekaServer开启服务注册,但是使用nacos,直接启动项目就能注册服务。

使用discoveryClient从注册中心获取接口地址

创建一个订单项目

配置文件与会员项目相同,更改一下端口号。

创建服务调用会员服务

@RestController
public class OrderService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("/orderToMember")
    public Object orderToMember() {
        //通过服务名获取接口地址
        List<ServiceInstance> instances = discoveryClient.getInstances("member-nacos");
        return instances.get(0);
    }
}

使用restTemplate实现RPC远程调用

项目中并没有注册restTemplate,需要手动注册一个。

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

实现调用

@RestController
public class OrderService {

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/orderToMember")
    public Object orderToMember() {
        //通过服务名获取接口地址
        List<ServiceInstance> instances = discoveryClient.getInstances("member-nacos");
        ServiceInstance serviceInstance = instances.get(0);
		//通过服务地址加上方法名调用,String.class为方法返回值类型
        String object = restTemplate.getForObject(serviceInstance.getUri() + "/user", String.class);
        return "调用返回结果"+object;


    }
}

手写负载均衡轮询算法

通常从注册中心获取到的服务是集群列表,使用负载均衡来选择一个服务调用。

负载均衡的算法有:一致性hash计算、轮询、权重、随机

可以用策略模式,来实现不同的算法。这里我们实现轮询算法

创建一个接口

public interface LoadBalancer {
    ServiceInstance getOneService(List<ServiceInstance> serviceInstances);
}

实现轮询算法

@Component
public class RotationLoadBalancer implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public ServiceInstance getOneService(List<ServiceInstance> serviceInstances) {
        int index = atomicInteger.incrementAndGet()%serviceInstances.size();
        return serviceInstances.get(index);
    }
}
原文地址:https://www.cnblogs.com/ylcc-zyq/p/13131612.html