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

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. 创建轮询实现类

package cn.gorit.localbalance;

import org.springframework.cloud.client.ServiceInstance;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.stereotype.Component;

import java.util.List;

import java.util.concurrent.atomic.AtomicInteger;

/**

  • @Classname RotationLoadBalancer

  • @Description TODO

  • @Date 2021/1/11 17:46

  • @Created by CodingGorit

  • @Version 1.0

*/

@Component

public class RotationLoadBalancer implements LoadBalancer {

// 从 0 开始去计数

private AtomicInteger atomicInteger = new AtomicInteger(0);

/**

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

  • 轮询算法:

  • 1%2 = 1

  • 2%2 = 0

  • 3%2 = 1

  • 4%2 = 0

  • 1%1 = 0

  • @param serviceInstanceList

  • @return

*/

@Override

public ServiceInstance getSingleAddress(List serviceInstanceList) {

int index = atomicInteger.incrementAndGet()%serviceInstanceList.size();

return serviceInstanceList.get(index);

}

}

  1. 修改 memberService 的接口为如下,以及 yml 配置,分别启动 8080 和 8082 端口

@GetMapping(“/user”)

public String getUser() {

return “user+ 8082”;

}

@GetMapping(“/user”)

public String getUser() {

return “user+ 8080”;

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer

蚂蚁、京东Java岗4面:原理+索引+底层+分布式+优化等,已拿offer
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。

最后祝愿各位身体健康,顺利拿到心仪的offer!

由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里

[外链图片转存中…(img-eXQ6PYaB-1712685676628)]

[外链图片转存中…(img-EvAGB6EV-1712685676628)]

[外链图片转存中…(img-r0UYj4cX-1712685676628)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值