springcloud-alibaba(二.nacos-服务注册与发现)

注册中心,提供者,消费者

在微服务中有很多模块, 一个微服务(使用者)要怎么去调用另一个微服务(提供者)?

  • 原始: 把url[域名,端口号,方法名]存放在数据库中, 调用的时候访问数据库
  • 现在: 使用注册中心

注册中心实际上就是存储服务的地址信息

  • Zookeeper, Eureka, Consul, Nacos
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f3kWnrGn-1644028560350)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220117141659483.png)]

注册与发现

  1. 生产者启动的时候将key=服务的名称, value=ip和端口号注册到我们的微服务注册中心上

    • Mayikt-member 192.168.212.110:8080
    • Mayikt-member 192.168.212.110:8081
  2. 注册中心存放地主列表地址, key唯一, 列表是list集合: Map<Key, List <String>>.

    • Mayikt-member: [“192.168.212.110:8080”“192,168.212.110:8081”]
  3. 消费者从我们注册中心上根据服务名称查询服务地址列表(集合)

    • Mayikt-member ===[“192.168.212.110:8080”, “192.168.212.110:8081”].
  4. 消费者使用负载均衡算法选取其中一个地址, 然后使用rpc调用该服务

搭建Nacos环境

首先在github官网需要下载nacos服务器(类似下载zookeeper那样)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fMVc8beu-1644028716937)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118111131032.png)]

双击startup.cmd启动

在这里插入图片描述

如果报错可以启动单机模型, 而非集群模型(没有配置集群)

startup.cmd -m standalone

使用http://127.0.0.1:8848/nacos 访问nacos注册与配置中心网页版

需要登录, 默认用户名和密码都是nacos

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sbUa2cF3-1644028560351)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118111326301.png)]

Nacos常用api接口

服务注册(post)

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

服务发现(get)

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

发布配置(post)

curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test&content=HelloWorld"

获取配置(get)

curl -X GET "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=nacos.cfg.dataId&group=test"

在postman测试

  • 注册

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xY8bE9iL-1644028560351)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118121048475.png)]

  • 发现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4xaG8VBU-1644028560352)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118121205040.png)]
host中发现了两个以上服务,说明是一个集群

版本说明

组件版本对应关系
在这里插入图片描述

与springboot和springcloud版本对应

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p64geVXE-1644028560353)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118132128448.png)]

在项目中整合Nacos

父工程maven依赖

nacos服务器端已经启动成功, 新建一个maven项目,添加依赖(版本非常重要):

nacos依赖名为 spring-cloud-starter-alibaba-nacos-discovery

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring.boot.version>2.3.12.RELEASE</spring.boot.version>
        <spring.cloud.version>Hoxton.SR12</spring.cloud.version>
        <spring.cloud.alibaba.version>2.2.7.RELEASE</spring.cloud.alibaba.version>
    </properties>

    <dependencies>

<!--        springboot依赖-->
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring.boot.version}</version>
        <type>pom</type>
        <scope>provided</scope>
      </dependency>

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>${spring.boot.version}</version>
      </dependency>

<!--        springcloud依赖-->
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring.cloud.version}</version>
        <type>pom</type>
        <scope>runtime</scope>
      </dependency>

      <!--        springcloud-alibaba依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
        </dependency>

<!--        nacos依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
        </dependency>

    </dependencies>

服务提供者

maven: 仅需要继承父工程

yaml文件:

server:
  port: 8001

spring:
  application:
    name: nacos-provider

  cloud:
    nacos:
      server-addr: http://127.0.0.1:8848
      # nacos的服务器地址

服务名spring.application.name一定要有, 而且名称中只能使用中划线不能使用下划线

启动主程序, 在nacos页面中的服务列表看到有新增的服务, 说明注册成功
在这里插入图片描述

暴露的接口服务

@RestController
public class ProviderService{

    @Value(value="${server.port}")
    private String port;

    @GetMapping("/provider/get")
    public String get(){
        return "蚂蚁课堂 " + port;
    }
}

服务消费者

maven: 一样只需要继承父工程

yaml: 除了端口号和应用名其他都和提供者一样

server:
  port: 7001

spring:
  application:
    name: nacos-consumer

  cloud:
    nacos:
      server-addr: http://127.0.0.1:8848
      # nacos服务器的地址

调用提供者的接口

@RestController
public class ConsumerService{

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource(name = "myRestTemplate")
    private RestTemplate restTemplate;

    @GetMapping("/consumer/get")
    public String get(){
        List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
        ServiceInstance serviceInstance = instances.get(0);
        return restTemplate.getForObject(serviceInstance.getUri() + "/get", String.class);
    }

    @Bean(name = "myRestTemplate")
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

第二个服务提供者

除了端口号, 其他的都和第一个服务提供者一模一样

服务名称, 方法名称一定要一样, 这样才能和第一个提供者构成一个集群

运行成功后, 这时候就能在服务列表里看到两个提供者一个消费者
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5iX2WSXc-1644028560353)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118140639648.png)]

手写负载均衡算法

有两个服务名和方法完全相同的提供者, 所以说消费者调用时(根据服务名调用)时会调用哪一个呢?

这就取决于负载均衡算法, 常用的算法有

  • hash一致性
  • 轮询
  • 随机
  • 权重

现在我们自己实现一个负载均衡器 , 并注入到spring容器

采用设计模式, 首先写主接口

@Component
public interface MyLoadBalancer{

    ServiceInstance getSingleService(List<ServiceInstance> instances);
}

然后写实现类, 例如使用轮询算法

@Component
public class RotationLoadBalancer implements MyLoadBalancer{

    private static Integer num = 0;

    /**
     * 轮询算法
     * @param instances 服务列表
     * @return 选出的服务
     */
    public ServiceInstance getSingleService(List<ServiceInstance> instances){
        num ++;
        System.out.println("共有" + instances.size() + "个地址, 选择第" + (num % instances.size() + 1) + "个地址");
        return instances.get(num % instances.size());
    }
}

然后在消费者的调用服务方法中引用它

@Resource
private RotationLoadBalancer loadBalancer;
// 注入

@GetMapping("/consumer/get")
public String get(){
    List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
    ServiceInstance instance = loadBalancer.getSingleService(instances);
    // 调用自己写的负载均衡算法
    System.out.println("服务id: " + instance.getServiceId());
    System.out.println("Uri:" + instance.getUri());
    System.out.println("端口号:" + instance.getPort());
    return restTemplate.getForObject(instance.getUri() + "/provider/get", String.class);
}

服务的上线和下线

进行服务的详情, 可以选择对服务进行上线下线

下线之后的服务会被负载均衡算法忽略

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fLuN24Mi-1644028560355)(C:\Users\hp\AppData\Roaming\Typora\typora-user-images\image-20220118163424420.png)]

手动下线的之后的服务, 如果不手动上线, 即使下次重启也不会再次上线

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值