服务负载均衡设计及实现(补)
@LoadBalanced
当RestTemplate进行远程调用时,会被LoadBalancerInterceptor拦截,实现负载均衡后将代码封装交给loadBalancer。
第一步,构建RestTemplate方法
@Bean
@LoadBalanced
public RestTemplate loadBalancedRestTemplate(){
return new RestTemplate();
}
第二步,在实现方法中进行依赖注入并使用
@Autowired
private RestTemplate loadBalancedRestTemplate;
@GetMapping("/consumer/doRestEcho3")
public String doRestEcho03(){
String url=String.format("http://%s/provider/echo/%s","sca-provider",appName);
//向服务提供方发起http请求,获取响应数据
return loadBalancedRestTemplate.getForObject(
url,//要请求的服务的地址
String.class);//String.class为请求服务的响应结果类型
}
Ribbon负载均衡策略
什么是负载均衡?
将服务按照一定的策略分布到多个服务器上,以次来提高系统的并发能力和增强系统的性能和可靠性。
为什么要用负载均衡?
提高系统并发处理服务的能力
常见的负载均衡方式?
DNS负载均衡,HTTP负载均衡,IP负载均衡,反向代理负载均衡
常见负载均衡策略?
轮训策略,随机策略,hash策略,时间策略(时间短的优先调用)
Ribbon是什么,基于Ribbon可以解决什么问题?
一个负载均衡组件,这个组件中提供一套负载均衡算法(8种负载策略)
基于Feign的远程服务调用
Feign是什么
feign可以实现远程调用和负载均衡,是一种声明是的远程调用,会在进行代码底层实现,并为接口自动生成实现类。
第一步:在服务消费方,添加项目依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:在启动类上添加@EnableFeignClients注解
@EnableFeignClients
@SpringBootApplication
public class ConsumerApplication {…}
第三步:定义feign接口,并在接口内部进行熔断处理
熔断处理时需要在配置类中进行配置
package com.jt.consumer.service;
import feign.hystrix.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @FeignClient 注解描述的接口为[远程服务]调用接口,
* 此接口中我们应该定义这些元素?
* 1)你要调用的服务?一般用服务名进行标识
* 2)访问服务中的什么资源?(数据,资源标识是什么?-url)
* 3)对服务中的资源进行什么操作?(Get,Post,Put,Delete)
* 4)资源访问不到怎么办?操作资源的过程中出现异常怎么办? (预案)
* 此接口是否需要我们自己写实现类?(不需要,由底层创建接口实现类,我们只做声明即可)
* 此接口对应的对象会交给spring管理吗?(会,这个对象是一个代理对象)
* 此对象默认的bean名称是什么?(假如没有指定,默认使用name或value属性的值,
* 推荐基于contextId手动指定一个Bean名字)
*/
@FeignClient(name="sca-provider",
contextId = "remoteProviderService",
fallbackFactory = ProviderFallbackFactory.class)
public interface RemoteProviderService {//明修栈道暗度陈仓
//Rest风格:通过URI定义资源,通过请求动作操作资源
@GetMapping("/provider/echo/{string}")
String echoMessage(@PathVariable("string") String msg);
}
package com.jt.consumer.service;
import feign.hystrix.FallbackFactory;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* Feign回调接口工厂对象,基于此对象创建Feign接口实现类对象.
* 这个实现类对象,用于做容错处理?(有备无患,这里做熔断处理.)
*/
@Slf4j
@Component
public class ProviderFallbackFactory implements FallbackFactory<RemoteProviderService> {
//创建日志对象
//private static final Logger log=
//LoggerFactory.getLogger(ProviderFallbackFactory.class);
@Override
public RemoteProviderService create(Throwable throwable) {
// return new RemoteProviderService() {//匿名内部类
// @Override
// public String echoMessage(String msg) {
// //...报警...(发短信,email,日志.....)
// return "服务暂时不可用,稍等片刻再访问";
// }
// };
//如上return语句的简单写法,可采用如下方式:
return msg -> {//lambda表达式 (JDK8中的语法)
//...报警...(发短信,email,日志.....)
log.error("error: {} ","sca-provider服务调用失败");
return "服务暂时不可用,稍等片刻再访问";
};
}
}
feign:
hystrix:
enabled: true #默认值为false
【拓展】
通过idea启动nacos
通过idea连接数据库
修改nacos端口号