SpringCloud负载均衡-Ribbon-H版

什么是Ribbon

Ribbon是一个客户端的负载均衡工具,在SpringCloud Netflix中也集成了进来。需要主要的是Ribbon提供的是客户端负载均衡工具,与我们使用Nginx实现负载均衡的方式不同。Nginx的负载均衡是服务端的负载均衡,我们访问同一个资源路径,Nginx在后端将请求分发到其他服务上。而Ribbon是客户端的负载均衡,是本地服务调用同一服务的不同资源路径。Ribbon提供了很多种的不同的负载均衡算法,我们只需要简单配置即可使用。同样如果默认的配置无法满足我们的需求,我们也可以自己定义符合自己要求的负载均衡算法。

入门示例

之前我们已经有了两个服务,分别为「user-server」「shop-server」,在「shop-server」中调用「user-server」提供的服务。为了演示今天的示例,我们需要先修改我们的代码。

修改接口响应内容

@RestController
@RequestMapping("user")
public class UserController {
    @Autowired
    private UserService userService;
    @Value("${server.port}")
    private Integer serverPort;

    /**
     * 根据用户ID获取用户信息
     * @param id 用户ID
     * @return
     */

    @GetMapping()
    public JsonResponse<UserDto> getUser(@RequestParam("id")Integer id){
        UserDto user = userService.getUser(id);
        JsonResponse<UserDto> response = JsonResponse.ok(user);
        response.setMsg(response.getMsg()+":"+serverPort);
        return response;
    }

}

接口比较简单,我们在之前响应内容的基础上增加响应消息内的端口信息,这样有利于我们辨别是哪个端口的服务响应的内容。

增加profile

增加三个profile文件,文件中只添加端口设置:

# user-1
server:
  port: 8000
# user-2
server:
  port: 8001
# user-3
server:
  port: 8002

增加三个profile文件,当我们在启动时使用--spring.profiles.active=user-1指定即可。

服务调用方修改

上面修改的内容是「user-server」服务,需要注意的是上面的修改与Ribbon没有任何关系,只是为了展示效果而已,下面的修改才是关键的地方。

  • RestTemplate增加@LoadBalanced注解
    @LoadBalanced
    @Bean
    public RestTemplate restTemplate(){
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(5 * 1000);
        factory.setReadTimeout(5 * 1000);
        return new RestTemplate(factory);
    }
  • 修改服务调用。之前我们服务调用固定写的是服务的IP和端口,这种方式特别不好。如果我们的服务IP和端口变化之后,我们就需要修改客户端的代码。如果客户端数量少还好,如果数量很多那将会是一个噩梦。现在我们使用服务名称来代替,也就是我们配置文件中的「spring.application.name」
    @GetMapping()
    public JsonResponse<UserDto> getUserInfo(@RequestParam("id")Integer id){
        try {
            String body = restTemplate.getForObject("http://user-server/user?id={id}", String.classid);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonResponse<UserDto> jsonResponse = objectMapper.readValue(body, new TypeReference<JsonResponse<UserDto>>() {
            });
            if (!ResponseCode.OK.getCode().equals(jsonResponse.getCode())){
                throw new YsException(String.format("错误的响应码:[%s]",body));
            }
            return jsonResponse;
        } catch (Exception e) {
            log.error("调用user-server失败!",e);
        }
        return JsonResponse.error("获取用户信息失败",null);
    }

测试

启动所有服务,调用localhost:9000/user?id=1,多调用几次可以看到都能正常调用,并且每次调用的端口号也不一致。默认情况下,Ribbon的负载均衡算法为轮循,即每个服务调用一次,多试几次能发现规律。
整个过程我们并没有修改太多代码,核心的地方仅仅是在RestTemplate上增加了@LoadBalanced注解,然后服务调用时我们将固定IP+端口修改成服务的名称。

负载均衡算法的配置

通过前面我们知道了默认情况下的负载均衡算法是轮循,当然我们完全可以自己配置。

全局配置

下面示例我们配置一个随机算法,每次调用将会随机选择一个调用。配置很简单,只需要在配置类中增加注入一个IRule实现即可。

    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }

个性化配置

上面的方式全局化配置了负载均衡算法,但有时候对于某些服务我们想单独配置该如何呢?这时候我们可以使用@RibbonClient单独为某个服务设置一种负载均衡算法。下面我们单独将「user-server」服务设置成随机算法,一共需要以下几步:

  • 创建配置类
@Configuration
public class UserRibbonConfig {
    @Bean
    public IRule ribbonRule(){
        return new RandomRule();
    }
}
  • 使用@RibbonClient应用配置
@RibbonClient(name = "user-server",configuration = UserRibbonConfig.class)

这里面的name指的是服务的名称,也就是配置哪个服务。这里面需要特别注意一点,就是不能让SpringBoot扫描到这个配置,否则将会应用到全局,这个在官方文档上有特别说明。简单的说就是我们不能将这个配置类放在启动类的包名下,否则在启动的时候将会应用到全局。一般我们可以采取两种方式来解决这个问题,其一就是将这个配置类单独放在在一个包下,另外一种就是通过@ComponentScan排除掉这个包的扫描。下面我们使用@ComponentScan排除掉对com.yishu.shop.ribbon包的扫描:

@ComponentScan(basePackages = "com.yishu.shop",
        excludeFilters = {@ComponentScan.Filter(type = FilterType.REGEX,pattern = "com.yishu.shop.ribbon.*")})

这样我们就可以将RibbonClient的配置放在该包下面。

OpenFeign结合Ribbon使用

在上一篇服务调用中,我们使用OpenFeign来完成服务调用。我们在@FeignClient设置了url的值,让它调用我们设置好的URL。前面我们说过,写这种IP+端口的方式不好,既然我们已经使用Ribbon了,那我们就可以直接使用服务名称来代替url。修改代码如下:

@FeignClient(name = "user-server")
public interface UserService {
    /**
     * 根据用户ID获取用户信息
     * @param id 用户ID
     * @return
     */

    @GetMapping("/user")
    JsonResponse<UserDto> getUser(@RequestParam("id")Integer id);
}

整个代码修改很少,我们只是删除了url的配置就可以了,再次调用可以发现服务能正常使用。

总结

关于Ribbon的点就讲到这里,更多内容还请参考官网文档,文章长度有限只能带你快速了解如何使用。

  • 源码地址git下载:
git clone -b ribbon https://gitee.com/zengchao_workspace/ys.git


原文始发于微信公众号(一只菜鸟程序员):SpringCloud负载均衡-Ribbon-H版

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/73084.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!