SpringCloud Alibaba学习笔记 ——(二、基于 Nacos 实现服务注册 与 服务发现)

【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】

**开源地址:https://docs.qq.com/doc/DSmxTbFJ1cmN1R2dB **

2.2 服务注册实现原理


2.2.1 服务注册相关名词

服务注册:提供服务接口地址信息存放

生产者:提供我们接口被其他服务调用

消费者:调用接口实现消费

2.2.2 服务注册原理实现

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

  2. 注册中心存放地址列表类型:key 唯一,列表是 list 集合

Map<Key,List>

  1. 我们的消费者会从注册中心上根据服务名称查询服务地址列表(集合)

  2. 消费者获取到集群列表之后,采用负载均衡选择一个 rpc 远程调用

2.3 Nacos 的基本介绍


Nacos 实现

  • 注册中心

  • 分布式配置中心

2.3.1 配置 nacos

Nacos 官方文档

下载 Nacos(1.3.2 版本)

初始化数据库

运行 Nacos:startup.cmd -m standalone

账号密码均是:nacos

输入:127.0.0.1:8848/nacos 可以看到内容

2.3.2 编写 nacos 服务注册

  1. 配置 maven 项目,创建一个名为 gorit-member-8080 的 module,并创建 application.yml 并编写配置

spring:

application:

name: gorit-member

cloud:

nacos:

discovery:

server-addr: 127.0.0.1:8848

server:

port: 8080

  1. 导入父依赖 xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns=“http://maven.apache.org/POM/4.0.0”

xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”

xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>

4.0.0

cn.gorit

AlibabaNacos

pom

1.0-SNAPSHOT

gorit-member-8080

org.springframework.boot

spring-boot-starter-parent

2.3.4.RELEASE

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

2.2.3.RELEASE

  1. 编写 消费类

package cn.gorit.service;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RestController;

/**

  • @Classname MemberService

  • @Description TODO

  • @Date 2020/12/11 1:42

  • @Created by CodingGorit

  • @Version 1.0

*/

@RestController

public class MemberService {

// 这个借口在下面的 rpc 远程调用会使用到

@GetMapping(“/user”)

public String getUser() {

return “user”;

}

@GetMapping(“/user/{id}”)

public String getUser(@PathVariable(“userId”) Integer userId) {

return “xxx”;

}

}

  1. 编写主类 (前提保证 nacos 必须运行)

package cn.gorit;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

/**

  • @Classname App

  • @Description TODO

  • @Date 2020/12/11 1:52

  • @Created by CodingGorit

  • @Version 1.0

*/

// 服务注册不需要自己加进去

@SpringBootApplication

public class App {

public static void main(String[] args) {

SpringApplication.run(App.class);

}

}

可以看到服务自动被注册了

2.3.3 使用 DiscoverClient 实现 RPC 远程调用

编写第二个 module

  1. 编写配置

spring:

application:

name: gorit-order

cloud:

nacos:

discovery:

server-addr: 127.0.0.1:8848

server:

port: 8081

  1. 编写服务层

package cn.gorit.service;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.discovery.DiscoveryClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**

  • @Classname OrderService

  • @Description 消费者调用生产者的服务

  • @Date 2020/12/11 2:26

  • @Created by CodingGorit

  • @Version 1.0

*/

@RestController

public class OrderService {

@Autowired

private DiscoveryClient discoveryClient;

@GetMapping(“/order”)

public Object getOrderToUser() {

// 1. 根据服务名称从 注册中心获取集群列表地址,得到的是集群列表

List instances = discoveryClient.getInstances(“gorit-member”);

// 2. 列表任意选择一个实现 rpc 调用,远程 rpc 调用 gorit-member 的服务

return instances.get(0);

}

}

  1. 运行类和上面一致,区别一下名称

2.3.4 使用 rest 实现 RPC 远程调用

RestTemplate 不是 Spring Cloud Alibaba写的,本身 Spring 支持 Http 调用,实现 Http 调用

RPC 远程调用设计到本地的负载均衡算法【后期会在第七章专门介绍负载均衡算法】

  1. 从中心获取服务集群的列表

  2. 从列表中选择一个 负载均衡的算法:

  3. 一致性 hash 计算

  4. 轮训、权重

  5. 随机

采用 设计模式。策略模式

  1. 将 RestTemplate 类使用 Bean 注解,注入到 Spring 中

  2. 在 orderService 引入它。

package cn.gorit.service;

import cn.gorit.localbalance.LoadBalancer;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.discovery.DiscoveryClient;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

import java.util.List;

/**

  • @Classname OrderService

  • @Description 消费者调用生产者的服务

  • @Date 2020/12/11 2:26

  • @Created by CodingGorit

  • @Version 1.0

*/

@RestController

public class OrderService {

@Autowired

private DiscoveryClient discoveryClient;

@Autowired

private RestTemplate restTemplate;

@GetMapping(“/order”)

public Object getOrderToUser() {

// 1. 根据服务名称从 注册中心获取集群列表地址,得到的是集群列表

List instances = discoveryClient.getInstances(“gorit-member”);

// 2. 列表任意选择一个实现 rpc 调用,这里拿到地址,本地实现远程 rpc 调用 gorit-member 的服务

ServiceInstance serviceInstance = instances.get(0); // 一个问题,这里写死了,集群就没办法应用到负载均衡了。

// ip + 端口 + 调用加上接口名称

String result = restTemplate.getForObject(rpcMemberUrl.getUri()+“/user”, String.class);

return “订单调用会员返回结果:”+result;

}

}

2.4 手写负载均衡轮训算法


在上面代码中,我们获取集群列表地址的时候,默认获取的是第一个,如果是在集群环境下,负载均衡就会失效,这里我们手写实现一个负载均衡实现的策略 —— 轮询

我们启动两个相同的 member 服务,来测试负载均衡。

在 gorit-member 的app 设置

并在 application.yml 中设置启动端口为 8082

启动项目

在 nacos 中,我们就可以看到 member 启动了两个,也就是说我们可以使用集群了

编写负载均衡轮询算法

  1. 创建 LoadBalancer 接口d

package cn.gorit.localbalance;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

/**

  • @Classname LoadBalancer

  • @Description TODO

  • @Date 2021/1/11 17:42

  • @Created by CodingGorit

  • @Version 1.0

*/

public interface LoadBalancer {

/**

  • 从注册中心集群列表获得单个地址

  • @param serviceInstanceList

  • @return

*/

ServiceInstance getSingleAddress(List serviceInstanceList);

}

  1. 创建轮询实现类
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值