SpringCloud 微服务负载均衡设计及实现

这里多个实例并发提供服务的方式为负载均衡,这里的负载均衡实现默认是因为Nacos集成了Ribbon来实现的,Ribbon配合RestTemplate,可以非常容易的实现服务之间的访问。Ribbon是Spring Cloud核心组件之一,它提供的最重要的功能就是客户端的负载均衡(客户端可以采用一定算法,例如轮询访问,访问服务端实例信息),这个功能可以让我们轻松地将面向服务的REST模版请求自动转换成客户端负载均衡方式的服务调用。
@LoadBalanced注解是属于Spring,而不是Ribbon的,Spring在初始化容器的时候,如果检测到Bean被@LoadBalanced注解修饰,Spring会为其设置LoadBalancerInterceptor的拦截器。

1.1 修改sca-provider的配置文件端口,分别以8081,8082端口方式进行启动。

server:
  port: 8081
spring:
  application:
    name: sca-provider
  cloud:
    nacos:
      server-addr: localhost:8848

1.2 修改ConsumerController文件

package com.jt;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.activation.MailcapCommandMap;
import java.util.Random;

/**
 * @author 小新
 * @date 2021/08/17 10:49
 */
@SpringBootApplication
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
    }

    /**创建RestTemplate对象,然后基于此对象进行远程服务调用 */
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    @LoadBalanced//这个注解描述RestTemplate对象时,系统底层会对RestTemplate对象的请求进行拦截
    public RestTemplate loadBanlancerRestTemplate(){
        return new RestTemplate();
    }

    @RestController
    public class ConsumerController{
        @Autowired
        private RestTemplate restTemplate;
        @Autowired
        private RestTemplate loadBanlancerRestTemplate;

        //负载均衡客户端对象(基于此对象可以从nacos中获取服务列表,并且可以基于一定的算法
        //从列表中获取一个服务实例)
        @Autowired
        private LoadBalancerClient loadBalancerClient;

        @Value("${spring.application.name}")
        private String appName;

        /**
         * 负载均衡方式的调用1
         * http://localhost:8090/consumer/ech1
         * //1.手动负载均衡调用provider服务,url写死了,不灵活
         * @return
         */
        @GetMapping("/consumer/echo1")
        public String doRestEcho1() {

            //调用谁? sca-provider中的一个url
            String url1 = "http://localhost:8081/provider/echo/"+appName;
            String url2 = "http://localhost:8080/provider/echo/"+appName;
            String urls[] = new  String[]{url1,url2};
            //随机获取一个小于urls数组长度的整数
            int n = new Random().nextInt(urls.length);
            System.out.println("n="+n);
            //如何调用
            return restTemplate.getForObject(urls[n],String.class);

        }

        /**
         * 负载均衡方式的调用2
         * http://localhost:8090/consumer/echo2
         * //2.基于loadBanlancerClient方式获取服务实例
         * @return
         */
        @GetMapping("/consumer/echo2")
        public String doRestEcho2(){
            //2.基于loadBanlancerClient方式获取服务实例
            String serviceId = "sca-provider";//这个名字要在nacos的服务列表中
            ServiceInstance choose = loadBalancerClient.choose(serviceId);
            String ip = choose.getHost();
            int port = choose.getPort();
            String url = String.format("http://%s:%s/provider/echo/%s", ip,port,appName);
            return restTemplate.getForObject(url,String.class);

        }

        /**
         * 负载均衡方式的调用3
         * http://localhost:8090/consumer/echo3
         * RestTemplate在发送请求的时候会被LoadBalancerInterceptor拦截,封装url地址
         * @return
         */
        @GetMapping("/consumer/echo3")
        public String doRestEcho3(){

            String serviceId = "sca-provider";//这个名字要在nacos的服务列表中
            String url = String.format("http://%s/provider/echo/%s",serviceId,appName);
            return loadBanlancerRestTemplate.getForObject(url,String.class);
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值