- RestTemplate的创建
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
创建好的RestTemplate对象就会在applicationcont上下文中出现,可以直接使用@Autowired注解来使用。
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test")
public String test() {
String result = restTemplate.getForObject("http://alibaba-nacos-discovery-server/hello?name=didi", String.class);
return "Return : " + result;
}
-
LoadBalancerAutoConfiguration为实现客户端负载均衡器的自动化配置类。
Ribbon实现的负载均衡自动化配置需要满足下面两个条件:
1.有RestTemplate类
2.springbean中有被@LoadBalancerClient注解的对象 -
LoadBalancerInterceptor拦截器是如何将一个普通的RestTemplate变成客户端负载均衡
-
ILoadBalancer作为ribbon的入口,底层默认是ZoneAwareLoadBalancer来实现负载均衡器。
可以配置使用另一个DynamicServerListLoadBalancer来作负载均衡,不过一般不这么干。 -
ribbon通过RestTemplate来实现服务与服务之间的通信,默认使用的是httpurlconnect进行通信。
-
feign
feign是对ribbon进行了封装。restful的请求
@EnableFeignClients
一般使用接口的通信方式restful
http client
okhttp
httpurl
feign默认对使用的是jdk远程的url长链接通信方式,消耗性能比较大,因此feign集成了http client 和okhttp的通信方式。
被@EnableFeignClients注解的类会自动扫描该类所在包下被@feignclient注解的类。
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] defaultConfiguration() default {};
Class<?>[] clients() default {};
}
该类找到后,会根据@quarter这个注解,向下寻找合适的注解bean,其实就是实现负载均衡,然后使用okhttp进行服务于服务之间的通信。
因为feign是将ribbon的包、okhttp的包、gttpclient的包进行了集成,所以可以直接使用波。
```yaml
#请求处理的超时时间
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
# feign 配置
feign:
sentinel:
enabled: true
okhttp:
enabled: true
httpclient:
enabled: false
client:
config:
default:
connectTimeout: 10000
readTimeout: 10000
compression:
request:
enabled: true
response:
enabled: true
这里分别是ribbon的过期实际时间
开启okthhp的关闭httpclient的链接
使用gzip进行通信,节省通信时间
feign:
sentinel:
enabled: true
feign集成sentinel
在往下是这样的,feign集成sentinel之后要进行服务与服务之间调用的时候进行熔断处理,放置出现雪崩导致整个服务宕机。
@FeignClient(value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class)
public interface RemoteUserService
{
/**
* 通过用户名查询用户信息
*
* @param username 用户名
* @return 结果
*/
@GetMapping(value = "/user/info/{username}")
public R<UserInfo> getUserInfo(@PathVariable("username") String username);
}
/**
* 用户服务降级处理
*
* @author poem
*/
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
{
private static final Logger log = LoggerFactory.getLogger(RemoteUserFallbackFactory.class);
@Override
public RemoteUserService create(Throwable throwable)
{
log.error("用户服务调用失败:{}", throwable.getMessage());
return new RemoteUserService()
{
@Override
public R<UserInfo> getUserInfo(String username)
{
return null;
}
};
}
}
这就是直接用出现异常之后的实际处理类。
主意:如果是2个服务之间的调用,建议搞一个公共的模块来存储2个或多个模块用到的对象, 只有用相同的对象才可以读取A服务和B服务之间的信息并传递给C服务,他们要用同一个对象接受。