spring:
application:
name: gorit-member
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 8080
- 导入父依赖 xml
<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
- 编写 消费类
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”;
}
}
- 编写主类 (前提保证 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
- 编写配置
spring:
application:
name: gorit-order
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
server:
port: 8081
- 编写服务层
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);
}
}
- 运行类和上面一致,区别一下名称
2.3.4 使用 rest 实现 RPC 远程调用
RestTemplate 不是 Spring Cloud Alibaba写的,本身 Spring 支持 Http 调用,实现 Http 调用
RPC 远程调用设计到本地的负载均衡算法【后期会在第七章专门介绍负载均衡算法】
-
从中心获取服务集群的列表
-
从列表中选择一个 负载均衡的算法:
-
一致性 hash 计算
-
轮训、权重
-
随机
采用 设计模式。策略模式
-
将 RestTemplate 类使用 Bean 注解,注入到 Spring 中
-
在 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;
}
}
在上面代码中,我们获取集群列表地址的时候,默认获取的是第一个,如果是在集群环境下,负载均衡就会失效,这里我们手写实现一个负载均衡实现的策略 —— 轮询
我们启动两个相同的 member 服务,来测试负载均衡。
在 gorit-member 的app 设置
并在 application.yml 中设置启动端口为 8082
启动项目
在 nacos 中,我们就可以看到 member 启动了两个,也就是说我们可以使用集群了
编写负载均衡轮询算法
- 创建 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);
}
- 创建轮询实现类
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);
}
}
- 修改 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开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/e686be0afdbc885f2787dd62ec6f50d7.jpeg)
写在最后
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://img-blog.csdnimg.cn/img_convert/e686be0afdbc885f2787dd62ec6f50d7.jpeg)
写在最后
很多人感叹“学习无用”,实际上之所以产生无用论,是因为自己想要的与自己所学的匹配不上,这也就意味着自己学得远远不够。无论是学习还是工作,都应该有主动性,所以如果拥有大厂梦,那么就要自己努力去实现它。
最后祝愿各位身体健康,顺利拿到心仪的offer!
由于文章的篇幅有限,所以这次的蚂蚁金服和京东面试题答案整理在了PDF文档里
[外链图片转存中…(img-eXQ6PYaB-1712685676628)]
[外链图片转存中…(img-EvAGB6EV-1712685676628)]
[外链图片转存中…(img-r0UYj4cX-1712685676628)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!