微服务的注册中心

优先我们来看下为什么要使用注册中心?以及注册中心的作用是什么?还有怎么使用注册中心?

为什么使用注册中心

引出:

我们在将单体架构拆分为微服务的过程中,由于单体架构之间各个模块功能能够直接互相调用。但是当我们拆分模块后,如果A功能模块需要使用B功能模块的功能,但现在拆分后不再能直接互相调用,此时我们还是需要使用B功能模块的功能,这时可以使用网络访问的方式调用B功能模块获取返回的数据。也就是我们称之为远程调用

远程调用:

及能够使服务器发出客户端发出的各种Get、Post、Delete等请求,在Java中使用RestTemplate来实现这一功能,下面来简述如何使用

1、配置Configuration

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

这一步的目的是将RestTemplate交给IOC容器管理,之后使用restTemplate对象时可以使用自动注入

2、调用API

public <T> ResponseEntity<T> exchange(
    String url,  //请求地址
    HttpMethos method,  //请求方式
    @Nullable HttpEntity<?> requestEntity, //请求体,可以为空
    Class<T> responseType, //返回数据类型
    Map<String,?> urlVariables //请求携带参数
)

例子

 private void handleCartItems(List<CartVO> vos) {
        // 1.获取商品id
        Set<Long> itemIds = vos.stream().map(CartVO::getItemId).collect(Collectors.toSet());
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                "http://localhost:8081/items?ids={ids}",//请求路径
                HttpMethod.GET, //请求方式
                null,//请求体(可以为空)
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },//返回值类型
                Map.of("ids", StringUtils.join(itemIds, ","))//请求参数
        );
        List<ItemDTO> items = response.getBody();

        if(CollUtils.isEmpty(items)){
            return ;
        }
        // 3.转为 id 到 item的map
        Map<Long, ItemDTO> itemMap = items.stream().collect(Collectors.toMap(ItemDTO::getId, Function.identity()));
        // 4.写入vo
        for (CartVO v : vos) {
            ItemDTO item = itemMap.get(v.getItemId());
            if (item == null) {
                continue;
            }
            v.setNewPrice(item.getPrice());
            v.setStatus(item.getStatus());
            v.setStock(item.getStock());
        }
    }

说明:

上述例子是向本机的8081端口下的items以Get方式发送请求并携带请求参数map集合其中存放key = ids,value = {id1,id2,id3...},返回数据类型是List<ItemDTO>

那么上述方式restTemplate的远程调用方式存在什么问题呢?

  1. 请求地址写死了,如果不知道请求地址和端口则无法实现功能
  2. 如果该地址对应的服务器挂掉了,则整个功能直接失效

上述问题在微服务中是常存在的问题

因此针对上述问题,提出了“注册中心”的解决方式

注册中心

首先来看什么是注册中心:

简述就是一个中间商

比如如果A需要某个服务但是却不知道找谁提供,而B能提供这个服务但不知道提供给谁,那么这时候就需要一个中间商。

这个中间商让所有的B都到自己这里来注册信息,这样就集中管理了能提供服务的服务器。当A需要找B功能的服务时,直接连接这个中间商,中间商通过负载均衡自动分配一个能满足A要求的B服务器连接URI地址给A。A再自己连接B

使用:注册

以Alibaba的nacos为例,简述注册中心的使用,之后再说下其中关键的功能和概念

0、使用docker启动nacos容器

这里只简述在docker下如果启动一个nacos的容器

  1. 在数据库中创建好nacos需要的数据库和数据
  2. 使用docker拉取nacos镜像
  3. 创建nacos文件夹并创建一个custom.env的配置文件,编写好配置信息
  4. 使用docker run命令启动nacos容器

1、引入依赖

<dependency>
    <groupId>com.alibaba.could</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>选择需要的版本</version>
</dependency>

2、配置地址

spring:
  cloud:
    nacos:
      server-addr: 服务器地址:对应的端口
  application:
     name: 微服务的名字

3、启动服务

启动服务后,可以通过访问 nacos服务的地址:端口/nacos 查看到启动服务的信息

如果要多实例启动,则复制一个启动类配置其中的端口不要重复即可

使用:发现

1、添加依赖

2、配置nacos的地址

3、编写服务代码

这里前两步和注册的步骤一样就不多赘述,来看获取服务的代码

private final DiscoveryClient discoveryClient
private void handleCartItems(List<CartVO> vos){
    //根据服务名,拉取服务实例
    List<ServiceInstance> instances = discoveryClient.getInstances("服务名");
    //随机负载均衡,挑选实例
    ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));
    //获取实例的IP和端口
    URI uri = instance.getUri();
     ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                uri + "/items?ids={ids}",//请求路径
                HttpMethod.GET, //请求方式
                null,//请求体(可以为空)
                new ParameterizedTypeReference<List<ItemDTO>>() {
                },//返回值类型
                Map.of("ids", StringUtils.join(itemIds, ","))//请求参数
        );
}

此时再使用远程调用就不需要写死地址,而是动态的随机获取一个服务,也就解决了原始远程调用存在的问题

功能

  • 服务提供者在注册中心中注册服务信息,并建立心跳检测来检测服务是否正常运行

  • 注册中心中记录并将监控服务的状态,如果服务调用者选择的服务提供者挂掉,则推送服务变更信息给服务调用者并从注册中心中将挂掉的服务剔除并重新分配正常的服务给调用者

  • 服务调用者通过注册中心订阅服务提供者的信息,通过负载均衡选择使用哪个服务

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值