4.2 RestTemplate 详解
4.2.1 GET 请求
在 RestTemplate 中,对GET请求可以通过如下两个方法进行调用实现。
1.getForEntity函数。
该方法返回的是ResponseEntity,该对象是Spring对HTTP请求响应的封装,其中主要存储了HTTP的几个重要元素,比如HTTP请求状态码的枚举对象Httpstatus(也就是我们常说的404、500这些错误码)、在它的父类HttpEntity中还存储着HTTP请求的头信息对象HttpHeaders 以及泛型类型的请求体对象。
ResponseEntity responseEntity = restTemplate.getForEntity(“http://HELLO-SERVICE/hello?userName={1}”,
String.class, “didi”);
String body = responseEntity.getBody();
ResponseEntity responseEntity = restTemplate.getForEntity(“http://HELLO-SERVICE/hello?userName={1}”,
User.class, “didi”);
User body = responseEntity.getBody();
2.getFor0bject函数。
String result = restTemplate.getForObject(“http://HELLO-SERVICE/hello?userName={1}”,
String.class, “dodo”);
User user=restTemplate.getForObject(“http://HELLO-SERVICE/hello?userName={1}”,
User.class, “dodo”);
4.2.2 POST 请求
有一个最简单有效的办法:postFprObject
User param = new User();
param.setUserName(“ninesun”);
param.setAge(12);
User user1 = (User) restTemplate.postForObject(“http://HELLO-SERVICE/hello”,
param, Object.class);
下面解释一下上面的代码:
param是我们在发送post请求时所携带的参数,Object是我们返回的结果类型
4.3 负载均衡策略
4.3.1 AbstractLoadBalancerRule
负载均衡策略的抽象类,在该抽象类中定义了负载均衡器工LoadBalancer对象,该对象能够在具体实现选择服务策略时,获取到一些负载均衡器中维护的信息来作为分配依据,并以此设计一些算法来实现针对特定场景的高效策略。
首先引入ribbon的两个核心依赖
com.netflix.ribbon
ribbon-loadbalancer
2.3.0
com.netflix.ribbon
ribbon-core
2.3.0
import com.netflix.client.IClientConfigAware;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
public class AbstractLoadBalancerRule implements IRule, IClientConfigAware {
private ILoadBalancer lb;
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
return null;
}
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.lb = lb;
}
@Override
public ILoadBalancer getLoadBalancer() {
return lb;
}
}
4.3.2 RandomRule
该策略实现了从服务实例清单中随机选择个服务实例的功能。它的具体实现如下,可以看到IRule接口的choose 0bject key)函数实现,委托给了该类中的choose(ILoadBalancer lb,object key),该方法增加了一个负载均衡器对象的参数。
从具体的实现上看,它会使用传入的负载均衡器来获得可用实例列表upList和所有实例列表 allList,并通过rand.nextInt (serverCount)函数来获取一个随机数,并将该随机数作为upList的索引值来返回具体实例。
同时,具体的选择逻辑在一个while(server == null)循环之内,而根据选择逻辑的实现,正常情况下每次选择都应该选出一个服务实例,如果出现死循环获取不到服务实例时,则很有可能存在并发的Bug。
import com.netflix.client.IClientConfigAware;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
import java.util.Random;
public class RandomRule implements IRule, IClientConfigAware {
private ILoadBalancer lb;
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
public Server choose(ILoadBalancer lb, Object key) {
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List upList = lb.getReachableServers();
List allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
Random random = new Random();
int index = random.nextInt(serverCount);
server = upList.get(index);
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
return server;
}
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.lb = lb;
}
@Override
public ILoadBalancer getLoadBalancer() {
return lb;
}
}
4.3.3 RoundRobinRule
该策略实现了按照线性轮询的方式依次选择每个服务实例的功能。它的具体实现如下,其详细结构与RandomRule非常类似。除了循环条件不同外,就是从可用列表中获取所谓的逻辑不同。从循环条件中,我们可以看到增加了一个count计数变量,该变量会在每次循环之后累加,也就是说,如果一直选择不到server超过10次,那么就会结束尝试,并打印一个警告信息No available alive servers after 10 tries from load balancer: …。
import com.netflix.client.IClientConfigAware;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
@Slf4j
public class RoundRobinRule implements IRule, IClientConfigAware {
private ILoadBalancer lb;
private AtomicInteger nextServerCyclicCounter;
public RoundRobinRule() {
nextServerCyclicCounter = new AtomicInteger(0);
}
public RoundRobinRule(ILoadBalancer lb) {
this();
setLoadBalancer(lb);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
public Server choose(ILoadBalancer lb, Object key) {
Server server = null;
int count = 0;
while (server == null && count++ < 10) {
List reachableServers = lb.getReachableServers();
List allServers = lb.getAllServers();
int upCount = reachableServers.size();
int serverCount = allServers.size();
if (upCount == 0 || serverCount == 0) {
log.warn(“No available alive servers after 10 tries from load balancer:” + lb);
return null;
}
int nextServerIndex = incrementAndGetModulo(serverCount);
server = allServers.get(nextServerIndex);
if (server == null) {
Thread.yield();
continue;
}
if (server.isAlive() && server.isReadyToServe()) {
return server;
}
server = null;
}
if (count >= 10) {
log.warn(“No available alive servers after 10 tries from load balancer:” + lb);
}
return server;
}
@Override
public void setLoadBalancer(ILoadBalancer lb) {
this.lb = lb;
}
@Override
public ILoadBalancer getLoadBalancer() {
return lb;
}
private int incrementAndGetModulo(int modulo) {
int current;
int next;
do {
current = this.nextServerCyclicCounter.get(); //nextServerCyclicCounter是AtomicInteger对象,默认值0,可保证线程安全性
next = (current + 1) % modulo; //每次往后移一位,取集合中的下一个server。这里要注意的是从1开始,即数组中的第二个server会被第一个调用。
} while (!this.nextServerCyclicCounter.compareAndSet(current, next)); //操作完成后用CAS操作将next赋值给nextServerCyclicCounter
return next;
}
}
4.3.4 RetryRule
该策略实现了一个具备重试机制的实例选择功能。从下面的实现中我们可以看到,在其内部还定义了一个IRule对象,默认使用了RoundRobinRule实例。而在choose方法中则实现了对内部定义的策略进行反复尝试的策略,若期间能够选择到具体的服务实例就返回,若选择不到就根据设置的尝试结束时间为阈值(maxRetryMillis参数定义的值+ choose方法开始执行的时间戳),当超过该阈值后就返回null。
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.InterruptTask;
import com.netflix.loadbalancer.Server;
public class RetryRule extends AbstractLoadBalancerRule {
IRule iRule = new RoundRobinRule();
long maxRetryMillis = 500;
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
public Server choose(ILoadBalancer lb, Object key) {
long requestTime = System.currentTimeMillis();
long deadline = requestTime + maxRetryMillis;
Server answer = null;
answer = iRule.choose(key);
if ((answer == null || !answer.isAlive()) && (System.currentTimeMillis() < deadline)) {
InterruptTask task = new InterruptTask(deadline - System.currentTimeMillis());
while (!Thread.interrupted()) {
answer = iRule.choose(key);
if ((answer == null || !answer.isAlive()) && (System.currentTimeMillis() < deadline)) {
Thread.yield();
} else {
break;
}
}
task.cancel();
}
if (answer == null || !answer.isAlive()) {
return null;
} else {
return answer;
}
}
}
4.3.4 WeightedResponseTimeRule
该策略是对RoundRobinRule 的扩展,增加了根据实例的运行情况来计算权重,并根据权重来挑选实例,以达到更优的分配效果,它的实现主要有三个核心内容。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分
yMS-1711789589719)] [外链图片转存中…(img-MYpR2fMx-1711789589720)] [外链图片转存中…(img-IV4z0JVi-1711789589721)] [外链图片转存中…(img-CVUowYPC-1711789589721)] [外链图片转存中…(img-cKHJXGDF-1711789589722)] [外链图片转存中…(img-icH195LM-1711789589722)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java) [外链图片转存中…(img-VHwUHxv0-1711789589723)]
[外链图片转存中…(img-pxnkOEkx-1711789589723)]
最近我根据上述的技术体系图搜集了几十套腾讯、头条、阿里、美团等公司21年的面试题,把技术点整理成了视频(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分
[外链图片转存中…(img-T8fjwLxR-1711789589724)]
好文阅读
发表评论