使用前提及实现

1、搭建前环境(linux 安装 nacos )

2、实现功能

  • 1、alibaba-server(生产者), alibaba-client(消费者) 环境搭建
  • 2、生产者/消费者 把服务注册到nacos 注册中心
  • 3、通过RestTemplate 模块,消费者PRC 调用生产者
  • 4、手写 负载均衡器 LoadBalancer (不建议使用)
  • 5、使用 负载均衡器 Rabbit

本文模拟环境如下图:
在这里插入图片描述

一、创建springboot 项目 alibaba-server( 版本2.0.1)

生产者项目模拟

1、pom.xom 依赖

        <!--  springboot 整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- springboot 整合 alibaba-nacos-discovery 注册中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>

2、yml 配置

server:
  port: 8080
spring:
  application:
    ## 服务名称
    name: alibaba-server
  cloud:
    nacos:
      discovery:
        ## 服务注册地址
        server-addr: 192.168.177.128:8848

3、添加 getUserId 测试接口

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserService {

    @GetMapping("/getUserId")
    public String getUserId(String userId){
         return  "userId:"+userId;
    }
}

4、启动类(不需要任何配置)

alibaba-nacos-discovery 会自动把服务注入到 nacos

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
class AlibabaServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(AlibabaServerApplication.class, args);
    }
}

二、创建springboot 项目 alibaba-client( 版本2.0.1)

消费者项目模拟

1、pom.xom 依赖

        <!--  springboot 整合web组件-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- springboot 整合 alibaba-nacos-discovery 注册中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>0.2.2.RELEASE</version>
        </dependency>

2、yml 配置

server:
  port: 8081
spring:
  application:
    ## 服务名称
    name: alibaba-client
  cloud:
    nacos:
      discovery:
        ## 服务注册地址
        server-addr: 192.168.177.128:8848

3、添加消费者接口 -> 调用生产者接口

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class LoginService {

    /**
     * rpc 调用工具
     */
    @Autowired
    private RestTemplate restTemplate;
    /**
     * 获取注册中心数据对象
     */
    @Autowired
    private DiscoveryClient discoveryClient;


    @GetMapping("/login")
    public String login(){
       // 通过服务名获取到注册到nacos 的ip+端口地址信息(集群会获取多个)
        List<ServiceInstance> instances = discoveryClient.getInstances("alibaba-server");
        String ipAddr = instances.get(0).getUri().toString();
        String url  = ipAddr+"/getUserId?userId=123456789";
        // rpc 调用
        String result = restTemplate.getForObject(url, String.class);
        System.out.println("调用alibaba-server服务,result:" + result);
        return result;
    }
}

4、启动类注入RestTemplate 模块(rpc调用工具)

@SpringBootApplication
class AlibabaClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(AlibabaClientApplication.class, args);
    }


    /**
     * TODO   RestTemplate =  rest,http风格的,api调用工具
     *
     * @return org.springframework.web.client.RestTemplate
     * @date 2019/12/6 0006 12:02
     */
    @Bean              //注入springboot容器
    //@LoadBalanced//让RestTemplate在请求时拥有客户端负载均衡的能力
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

三、测试结果

1、启动项目后Nacos 查看注册的服务

在这里插入图片描述

2、URL 访问 alibaba-client 服务的/login 接口

http://127.0.0.1:8081/login
输出结果:
在这里插入图片描述

四、手写负载均衡(集群环境)

集群环境无非就是 spring.application 值相同,修改一下端口号,在次启动服务即可
获取地址如上方配置使用 String ipAddr = instances.get(0).getUri().toString();
那么集群环境下一直是采用的第一个节点,所以我们需要编写本地负载均衡算法

1、手写 LoadBalancer 负载均衡类(轮训机制)

public interface LoadBalancer {


    /**
     * 根据多个不同的地址 返回单个调用rpc地址
     *
     * @param serviceInstances
     * @return
     */
    ServiceInstance getSingleAddres(List<ServiceInstance> serviceInstances);
}


@Component
public class RotationLoadBalancer implements LoadBalancer {
    //原子类,从0开始计数
    private AtomicInteger atomicInteger = new AtomicInteger(0);

    @Override
    public ServiceInstance getSingleAddres(List<ServiceInstance> serviceInstances) {
        int index = atomicInteger.incrementAndGet() % 2;
        ServiceInstance serviceInstance = serviceInstances.get(index);
        return serviceInstance;
    }
}

2、手写 LoadBalancer 使用

大家可自行改造消费者逻辑

 @Autowired
 private LoadBalancer loadBalancer;

// 获取集群的ip+端口(轮训机制)
ServiceInstance serviceInstance = loadBalancer.getSingleAddres(serviceInstanceList);
URI rpcMemberUrl = serviceInstance.getUri();
// rpc调用
String result = restTemplate.getForObject(rpcMemberUrl + "/getUser", String.class);

大家自己测试一下即可!!!

3、springcloud 自带本地负载均衡器 LoadBalancerClient

LoadBalancerClient 等同与我们自己写的 LoadBalancer ,springcloud 已经帮我们实现了
直接使用即可,通过服务名称即可获得 ip+端口信息

 @Autowired
 private LoadBalancerClient loadBalancerClient;

@RequestMapping("/loadBalancerClient")
public Object loadBalancerClient() {
    return loadBalancerClient.choose("meitemayikt-member");
}

Rabbit 使用 springcloud 的负载均衡器,添加 @LoadBalanced 注解即可,(看步骤五)

五、使用自带 Rabbit 实现负载均衡

1、RestTemplate 配置添加 @LoadBalanced 注解

    @Bean              // 注入springboot容器
    @LoadBalanced      // 让RestTemplate在请求时拥有客户端负载均衡的能力(Ribbon)
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

在这里插入图片描述

2、RPC 调用

直接使用即可,如:http:// + 服务名 + / + 接口,如:http://alibaba-server/getUserId

alibaba-server = 服务名
getUserId = 调用接口

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/login2")
    public String login2(){
        //  http:// + 服务名称 + 接口  + ?参数
        String result = restTemplate.getForObject("http://alibaba-server"+"/getUserId"+"?userId=123456789", String.class);
        System.out.println("调用alibaba-server服务,result:" + result);
        return result;
    }

3、启动多个生产者服务(alibaba-server)

1、让服务可以多次启动,修改端口再次启动服务
在这里插入图片描述2、修改接口返回信息,添加返回端口号
在这里插入图片描述
3、查看集群状态
在这里插入图片描述4、查看详情
在这里插入图片描述

4、测试接口 /login2

http://127.0.0.1:8081/login2
第一次 8082,第二次 8083,第三次 8082,第四次 8083,以此类推
8082
在这里插入图片描述
8083
在这里插入图片描述
本文到此结束,感谢观看!!!!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐