Ribbon 是一个独立的组件,是用来进行远程接口调用的
我们这里不需要添加Ribbon的依赖,因为Eureka Client包里面帮我们引入Ribbon相关的依赖,代码如下:
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
@Bean
//负载均衡注解
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
使用示例,web调用order的服务:
package com.micro.web.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
@Service
@Scope(proxyMode = ScopedProxyMode.INTERFACES)
public class UserServiceImpl implements UserService {
private AtomicInteger s = new AtomicInteger();
private AtomicInteger f = new AtomicInteger();
public static String SERVIER_NAME = "micro-order";
@Autowired
private RestTemplate restTemplate;
@Override
public String queryContents() {
s.incrementAndGet();
String results = restTemplate.getForObject("http://"
+ SERVIER_NAME + "/queryUser", String.class);
return results;
}
}
通过 getForObject 方法可以掉到用 micro-order 服务的,queryUser 接口。然后在调用期间会 存在负载均衡,micro-order 服务对应有几个服务实例就会根据负载均衡算法选择某一个去 调用
Get 请求 getForEntity:此方法有三种重载形式,分别为:
getForEntity(String url, Class responseType)
getForEntity(String url, Class responseType, Object... uriVariables)
getForEntity(String url, Class responseType, Map uriVariables)
getForEntity(URI url, Class responseType)
注意:此方法返回的是一个包装对象 ResponseEntity其中 T 为 responseType 传入类型, 想拿到返回类型需要使用这个包装类对象的 getBody()方法
getForObject:此方法也有三种重载形式,这点与 getForEntity 方法相同:
getForObject(String url, Class responseType)
getForObject(String url, Class responseType, Object... uriVariables)
getForObject(String url, Class responseType, Map uriVariables)
getForObject(URI url, Class responseType)
注意:此方法返回的对象类型为 responseType 传入类型
Post 请求 post 请求和 get 请求都有*ForEntity 和*ForObject 方法,其中参数列表有些不同,除了这两个 方法外,还有一个 postForLocation 方法,其中 postForLocation 以 post 请求提交资源,并返 回新资源的 URI
postForEntity:此方法有三种重载形式,分别为:
postForEntity(String url, Object request, Class responseType, Object... uriVariables) postForEntity(String url, Object request, Class responseType, Map uriVariables) postForEntity(URI url, Object request, Class responseType)
注意:此方法返回的是一个包装对象 ResponseEntity其中 T 为 responseType 传入类型, 想拿到返回类型需要使用这个包装类对象的 getBody()方法
postForObject:此方法也有三种重载形式,这点与 postForEntity 方法相同:
postForObject(String url, Object request, Class responseType, Object... uriVariables) postForObject(String url, Object request, Class responseType, Map uriVariables) postForObject(URI url, Object request, Class responseType)
注意:此方法返回的对象类型为 responseType 传入类型
postForLocation:此方法中同样有三种重载形式,分别为:
postForLocation(String url, Object request, Object... uriVariables)
postForLocation(String url, Object request, Map uriVariables)
postForLocation(URI url, Object request)
注意:此方法返回的是新资源的 URI,相比 getForEntity、getForObject、postForEntity、 postForObject 方法不同的是这个方法中无需指定返回类型,因为返回类型就是 URI,通过 Object... uriVariables、Map uriVariables 进行传参依旧需要占位符,参考postForEntity 部分代码
负载均衡算法
package com.micro.web.ribbon.config;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.*;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RibbonLoadBalanceMicroOrderConfig {
// @RibbonClientName
private String name = "micro-order";
@Bean
@ConditionalOnClass
public IClientConfig defaultClientConfigImpl() {
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
config.loadProperties(name);
config.set(CommonClientConfigKey.MaxAutoRetries,2);
config.set(CommonClientConfigKey.MaxAutoRetriesNextServer,2);
config.set(CommonClientConfigKey.ConnectTimeout,2000);
config.set(CommonClientConfigKey.ReadTimeout,4000);
config.set(CommonClientConfigKey.OkToRetryOnAllOperations,true);
return config;
}
// @Bean
public IPing iPing() {
//这个实现类会去调用服务来判断服务是否存活
return new PingUrl();
}
@Bean
public IRule ribbonRule() {
//线性轮训
new RoundRobinRule();
//可以重试的轮训
new RetryRule();
//根据运行情况来计算权重
new WeightedResponseTimeRule();
//过滤掉故障实例,选择请求数最小的实例
new BestAvailableRule();
return new RandomRule();
}
}
Ribbon 配置
#点对点直连测试配置 # 关闭 ribbon 访问注册中心 Eureka Server 发现服务,但是服务依旧会注 册。 #true 使用 eureka false 不使用 ribbon.eureka.enabled=true spring.cloud.loadbalancer.retry.enabled=true #指定调用的节点 micro-order.ribbon.listOfServers=localhost:8001 #单位 ms ,请求连接超时时间 micro-order.ribbon.ConnectTimeout=1000 #单位 ms ,请求处理的超时时间 micro-order.ribbon.ReadTimeout=2000 micro-order.ribbon.OkToRetryonAllOperations=true #切换实例的重试次数 micro-order.ribbon.MaxAutoRetriesNextServer=2 #对当前实例的重试次数 当 Eureka 中可以找到服务,但是服务连不上时将会 重试 micro-order.ribbon.MaxAutoRetries=2 #负载均衡算法RandomRule配置 micro-order.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule #负载均衡算法PingUrl配置 micro-order.ribbon.NFLoadBalancerPingClassName=com.netflix.loadbalancer.PingUrl
也可以在代码里面配置,这样粒度更小
代码配置 使用@RibbonClients 加载配置
这个配置类只针对 micro-order 服务,微服务系统里面有很多服务,这就可以区别化配置。 配置 configuration 配置类的时候,一定要注意,配置类不能陪@ComponentScan 注解扫描到, 如果被扫描到了则该配置类就是所有服务共用的配置了。
Ribbon 单独使用



