服务负载均衡问题
服务负载均衡
当只有一个服务实例时,不需要考虑负载均衡的问题,当服务并发访问需求很大时,就需要启动创建多个服务实例,从而提高执行效率,因此会采用一些均衡策略(轮询,权重,随机,hash)的处理并发请求
LoadBalancerClient
作用:LoadBalancerClient对象可以从nacos中基于服务名获取服务实例,然后在工程中基于算法实现负载均衡的调用,LoadBalancerClient为springcloud提供负载均衡器客户端
应用:
LoadBalancerClient继承了ServiceInstanceChooser
RibbonLoadBalancerClient实现了LoadBalancerClient
当调用choose方法时使用的是RibbonLoadBalancerClient中的方法
方法一:
在消费者的controller类中注入LoadBalancerClient,在调用另一个服务的方法中,使用loadBalancerClient.run("服务名");获取服务对象,默认为轮询,最后再使用restTemplate.getForObject(url,String.class);调用远程服务
方法二:
在配置类或启动类对RestTemplate对象构建时,在将其@Bean交给Spring容器管理基础上,加入@LoadBalanced注解,当添加此注解后,在Spring启动容器的时候就会设置一个LoadBalancerInterceptor的拦截器,当此RestTemplate对象发送请求时会被拦截,他的作用就是负载均衡,底层执行完负载均衡的业务(核心逻辑在loadBalancer)后放行,实现对其的负载均衡逻辑
Feign
为啥要有他:服务消费方基于rest请求服务提供方的服务时,直接方式是自己拼接url,拼接参数然后实现服务调用,代码复杂,并且不容易维护,此时feign诞生
他是啥:Feign是一种声明式Web服务客户端(只需要给我参数,我在底层进行业务操作,并返回结果),Fegin是靠近Consumer的,Consumer调用Fegin,让其封装了消费者的request,之后发给provider,返回组装response,最后响应到Consumer
好处:直接封装了Ribbon,默认负载机制为轮询
Feign应用
第一步:首先在pom.xml文件进行openfegin的依赖注入(feign --》 openfeign springCloud开发)
要在消费者服务添加!
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
第二步:在消费者的启动类上添加注解 @EnableFeignClients
@EnableFeignClients //使用Fegin远程调用时就要加这个注解,才能扫描到对应的feign
@SpringBootApplication //标识其是一个springBoot的启动类
public class Capplication {
public static void main(String[] args) {
SpringApplication.run(Capplication.class, args);
}
第三步:定义消费者服务中Controller 要调用的 Sever 接口(因为使用了@FeignClient描述接口,底层会为其自动创建实现类) 借助 OpenFeign 实现远端服务的调用
@FeignClient(name = "sca-provider") // sca-provider 是服务提供者的名称
@Service
public interface Cservice {
@GetMapping("/provider/echo/{string}") // 成功运行的前提是在远端要有这个服务
public String echoMessage(@PathVariable("string") String string);
}
第四步:创建FeignConsumerController并添加fegin访问
@RestController
@RequestMapping("/consumer")
public class FeginConsumerController {
@Autowired //注入设置好feign的server对象
private Cservice cservice;
@GetMapping("/echo/{msg}") //消费方的条件
public String doFeignEcho(@PathVariable String msg){
return cservice.echoMessage(msg); //可以直接调用其serice层进行
}
}
第五步:启动提供者服务、消费者服务,在浏览器通过消费者的controller层中定义好的请求方式,访问()