[toc]

作者:雨中散步撒哈拉
来源:https://liudongdong.top
公众号:雨中散步撒哈拉
备注:欢迎关注公众号,学习技术,一起成长!

本次实现,需以下模块,如没有搭建,请移步上一篇。
项目情况:

  1. 9001和9002为Eureka集群实现;
  2. 7001和7002为提供服务功能集群;
  3. 8001为服务消费端;

image.png

一、修改提供服务模块

服务模块7001和7002控制层添加返回接口如下:
image.png

package org.learn.cloud.controller;

import lombok.extern.slf4j.Slf4j;
import org.learn.cloud.entities.CommonResult;
import org.learn.cloud.entities.Payment;
import org.learn.cloud.service.PaymentService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@Slf4j
public class PaymentController {

    @Resource
    private PaymentService paymentService;

    @Value("${server.port}")
    private String portServer;

    @PostMapping(value = "/payment/create")
    public CommonResult create(@RequestBody Payment payment){
        int result = paymentService.create(payment);
        log.info("*****插入结果:"+result);
        if (result>0){  //成功
            return new CommonResult(200,"插入数据库成功" + "服务端口:" + portServer,result);
        }else {
            return new CommonResult(444,"插入数据库失败" + "服务端口:" + portServer,null);
        }
    }
    @GetMapping(value = "/payment/get/{id}")
    public CommonResult getPaymentById(@PathVariable("id") Long id){
        Payment payment = paymentService.getPaymentById(id);
        log.info("*****查询结果:"+payment);
        if (payment!=null){  //说明有数据,能查询成功
            return new CommonResult(200,"查询成功" + "服务端口:" + portServer,payment);
        }else {
            return new CommonResult(444,"没有对应记录,查询ID:"+id + "服务端口:" + portServer,null);
        }
    }

    @GetMapping(value = "/payment/lb")
    public String getPaymentLB(){
        return portServer;
    }
}

二、修改消费模块8001

1. ApplicationContextBean去掉@LoadBalanced

image.png

2. 定义LoadBalancer接口

package org.cloud.learn.lb;

import org.springframework.cloud.client.ServiceInstance;

import java.util.List;

public interface LoadBalancer {
     //收集服务器总共有多少台能够提供服务的机器,并放到list里面
    ServiceInstance instances(List<ServiceInstance> serviceInstances);

}

 

3. 实现自定义算法

为取余算法实现

package org.cloud.learn.lb;

import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class MyLB implements LoadBalancer {

    private AtomicInteger atomicInteger = new AtomicInteger(0);

    //坐标
    private final int getAndIncrement(){
        int current;
        int next;
        do {
            current = this.atomicInteger.get();
            next = current >= 2147483647 ? 0 : current + 1;
        }while (!this.atomicInteger.compareAndSet(current,next));  //第一个参数是期望值,第二个参数是修改值是
        System.out.println("*******第几次访问,次数next: "+next);
        return next;
    }

    @Override
    public ServiceInstance instances(List<ServiceInstance> serviceInstances) {  //得到机器的列表
       int index = getAndIncrement() % serviceInstances.size(); //得到服务器的下标位置
        return serviceInstances.get(index);
    }
}


4. 修改controller层

image.png

package org.cloud.learn.controller;

import lombok.extern.slf4j.Slf4j;
import org.cloud.learn.lb.LoadBalancer;
import org.learn.cloud.entities.CommonResult;
import org.learn.cloud.entities.Payment;
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.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.net.URI;
import java.util.List;

@RestController
@Slf4j
public class UsersController {

//  public static final String  HTTP_URL = "http://localhost:7001";
  public static final String  HTTP_URL = "http://cloud-payment-service";
  @Resource
  private RestTemplate restTemplate;

  @Resource
  private LoadBalancer loadBalancer;

  @Resource
  private DiscoveryClient discoveryClient;
  /**
   * 消费者调用第三方创建.
   * @param payment
   * @return
   */
  @GetMapping("/consume/payment/create")
  public CommonResult<Payment> create (@RequestBody Payment payment) {
    return restTemplate.postForObject(HTTP_URL + "/payment/create", payment, CommonResult.class);
  }

  /**
   * 消费者调用第三方查询.
   * @param id
   * @return
   */
  @GetMapping("/consume/payment/get/{id}")
  public CommonResult<Payment> getPayment (@PathVariable("id") String id) {
    return restTemplate.getForObject(HTTP_URL + "/payment/get/" + id, CommonResult.class);
  }


  @GetMapping(value = "/consumer/payment/lb")
  public String getPaymentLB(){
    List<ServiceInstance> instances = discoveryClient.getInstances("cloud-payment-service");
    if (instances == null || instances.size() <= 0){
      return null;
    }
    ServiceInstance serviceInstance = loadBalancer.instances(instances);
    URI uri = serviceInstance.getUri();
    return restTemplate.getForObject(uri+"/payment/lb",String.class);
  }


}

三、测试

  1. 请求地址:http://localhost:8001/consumer/payment/lb
  2. 请求类型:GET
  3. 请求参数:无
  4. 请求结果:发现返回服务端口为随机返回

image.png
image.png

获取源码

搜索并关注公众号:雨中散步撒哈拉
回复关键词:014

Q.E.D.


只有创造,才是真正的享受,只有拚搏,才是充实的生活。