SpringCloud学习之Ribbon使用(四)

1、关于 Ribbon 

Spring Cloud Ribbon 是基于 Netflix Ribbon 实现的一套客户端负载均衡的工具。Ribbon 是 Netflix 发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将 Netflix 的中间层服务连接在一起。Ribbon 客户端组件提供一系列完善的配置项如连接超时、重试等。简单的说,就是在配置文件中列出 Load Balancer(简称LB)后面所有的机器,Ribbon 会自动的基于某种策略(如轮询连接、随机连接等)去连接这些服务器。也很容易使用 Ribbon 实现自定义的负载均衡算法来满足项目中常见的业务环境需求。

2、Ribbon 的作用

LB,即负载均衡(Load Balance),在微服务或分布式集群中经常用的一种应用。负载均衡简单的说就是将用户的请求平均分配到多个服务上,从而达到系统的 HA(也就是我们常说的高可用!!!)。常见的负载均衡有软件 Nginx,LVS,硬件 F5 等,话又说回来,一般没有实力的公司都用不起 F5。相应的在中间件,例如:Dubbo 和 Spring Cloud 中均给我们提供了负载均衡机制,其负载均衡算法都是可以自定义的。


上面说那么多其实就是利用ribbon可以将请求分配到多个服务器,分担每个系统的压力,现在我们开始动手实现一个Demo,程序员请记住这句金科玉律:Talk is cheap, show me the code;

先新建两个provider服务,这里叫service-provider-port(端口号)

贴出provider核心代码如下:

package com.xu.serviceprovider2.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

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

    @RequestMapping("/hi")
    public String home(@RequestParam String name) {

        return "hi " + name + ", i am from port: " + port;
    }

}

具体怎么创建我之前的文章说过了,这里不赘述,以后也不会做赘述,想学习SpringCloud的读者请务必自己动手搭建一个最简单的多模块Springcloud项目,随时备用作为模板修改,我相信你经过大量的修改和测试后,SpringCloud学习才会有乐趣和真的能达到事半功倍的效果,这里我直接贴出我的消费端代码和截图

package com.xu.serviceconsumer.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String hiService(String name)
    {
        return restTemplate.getForObject("http://SERVICE-HELLO/hi?name=" + name, String.class);
    }
}

接下来我们看看我们在启动类里做了什么配置:

可以看到,我们的RestTemplate在初始化时候加了一个注解@LoadBalanced,英文不差的同学应该知道这个单词的大概意思就是负载均衡的意思

package com.xu.serviceconsumer.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String hiService(String name)
    {
        return restTemplate.getForObject("http://SERVICE-HELLO/hi?name=" + name, String.class);
    }
}

Service部分我们已经定义好了,我们开始在Controller中调用试试看

下面贴出我的Controller代码,请只关注上图截图部分的代码即可

package com.xu.serviceconsumer.controller;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.xu.serviceconsumer.service.HelloService;
import com.xu.serviceconsumer.service.UserFeignClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@RestController
public class HelloControler {

    private static final Logger LOGGER = LoggerFactory.getLogger(HelloControler.class);

    @Autowired
    private HelloService helloService;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @RequestMapping(value = "/hi")
    public String hi(@RequestParam String name) {

        return helloService.hiService(name);
    }

    @RequestMapping(value = "/hello")
    public String hello(@RequestParam String name) {

        return userFeignClient.getName(name);
    }

    @RequestMapping(value = "/log-instance")
    public Object logInstance() {
        ServiceInstance serviceInstance = this.loadBalancerClient.choose("SERVICE-HELLO");
        LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(),
                serviceInstance.getHost(),serviceInstance.getPort());

        JSONObject object1 = new JSONObject();
        object1.put("ServiceId",serviceInstance.getServiceId());
        object1.put("Host",serviceInstance.getHost());
        object1.put("Port",serviceInstance.getPort());
        return object1.toJSONString();
    }

}
我们打开浏览器输入http://localhost:8767/hello?name=Ronnie访问一下我们的请求试试,看他到底调用了哪些服务

既然是负载均衡,那么我们肯定要多调用几次,看看他们是不是分别调用了不同的服务,刷新浏览器再次得到结果如下

端口8763和8764分别是我们的两个同名服务不同的端口,说明请求的确分别请求了两个同名的服务,实现了负载均衡

好了,这次的课程就到这里,有不清楚的读者请及时留言尽快答复,拜拜

猜你喜欢

转载自www.cnblogs.com/xulijun137/p/12209726.html