第八节 Ribbon负载策略配置

亮子 2021-06-09 00:51:47 17495 0 0 0

1、整理负载均衡代码

1)、增加RestTemplate配置类

package com.mazong.serverbloggood.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

2)、修改启动类

package com.mazong.serverbloggood;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableEurekaClient
public class ServerBlogGoodApplication {

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

}

3)、修改GoodController类

package com.mazong.serverbloggood.controller;

import com.mazong.serverbloguser.entity.TbUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

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

@Controller
public class GoodController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/getGood")
    @ResponseBody
    public Object getGood(@RequestParam("id") Integer id) {
        // http://localhost:8900/getGood?id=1

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("welcome", "hello,i am good service");

        String url = "http://server-blog-user/getUser?id=" + id;
        System.out.println(url);

        TbUser user = restTemplate.getForObject(url, TbUser.class);
        resultMap.put("user", user);

        return resultMap;
    }
}

4)、运行效果

图片alt

2、自定义负载均衡的策略

1)、注入IRule接口的Bean

package com.mazong.serverbloggood.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule ribbonRule() {
        // 随机策略
        return new RandomRule();
    }
}

2)、运行效果

图片alt

3、多服务的负载策略

1)、article服务增加新的接口

package com.mazong.serverblogarticle.controller;

import com.mazong.serverblogarticle.entity.TbArticle;
import com.mazong.serverblogarticle.mapper.IDbArticleMapper;
import com.mazong.serverbloguser.entity.TbUser;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/")
public class ArticleController {
    @Autowired
    private IDbArticleMapper iDbArticleMapper;

    @Autowired
    HttpServletRequest request;

    @Autowired
    RestTemplate restTemplate;

    @Qualifier("eurekaClient")
    @Autowired
    EurekaClient eurekaClient;

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

    @Value("${server.port}")
    private int serverPort;

    @RequestMapping(value = "/getArticle")
    @ResponseBody
    public Object getArticle(@RequestParam("id") Integer id) {
        // http://localhost:9000/getArticle?id=2

        Map<String, Object> resultMap = new HashMap<>();
        TbArticle article = iDbArticleMapper.getArticle(id);
        resultMap.put("article", article);
        if(article != null) {

            InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("server-blog-user", false);
            Map urlVariables = new HashMap();
            urlVariables.put("hostName", instanceInfo.getHostName());
            urlVariables.put("port", instanceInfo.getPort());
            System.out.println("server="+instanceInfo.getHostName()+",port="+instanceInfo.getPort());
            TbUser user = restTemplate.getForObject("http://{hostName}:{port}/getUser?id=" + article.getUid(), TbUser.class, urlVariables);

            resultMap.put("user", user);
        }

        return resultMap;
    }

    @RequestMapping(value = "/hello")
    @ResponseBody
    public String hello() {
        return String.format("name=%s,port=%d", serverName,serverPort);
    }
}

2)、删除IRule接口Bean

package com.mazong.serverbloggood.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3)、修改配置文件application.properties

## application.properties
spring.application.name=server-blog-good
server.port=8900

## MyBatis 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/db_article?autoReconnect=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456

# eureka client
eureka.client.service-url.defaultZone=http://localhost:6060/eureka/
eureka.instance.prefer-ip-address=true

## 自定义配置负载均衡策略
server-blog-user.ribbon.NFLoadBalancerRuleClassName= com.netflix.loadbalancer.RoundRobinRule
server-blog-article.ribbon.NFLoadBalancerRuleClassName= com.netflix.loadbalancer.RandomRule

4)、修改GoodController

    @RequestMapping(value = "/getGood")
    @ResponseBody
    public Object getGood(@RequestParam("id") Integer id) {
        // http://localhost:8900/getGood?id=1

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("welcome", "hello,i am good service");

        String url = "http://server-blog-user/getUser?id=" + id;
        System.out.println(url);

        TbUser user = restTemplate.getForObject(url, TbUser.class);
        resultMap.put("user", user);
        System.out.println(user);

        String hello = restTemplate.getForObject("http://server-blog-article/hello", String.class);
        resultMap.put("hello", hello);
        System.out.println(hello);

        return resultMap;
    }

5)、运行效果

图片alt

4、其他多服务策略配置方法

也可以通过注解的方式来实现多负载策略的配置,但不如在属性文件里面修改优雅。当然注解的方式也有他的优势,就可以更方便地实现自己算法的负载策略。

@RibbonClients(value = {
    @RibbonClient(name = "server1",configuration = RiddonRuleConfig_Productserver1.class),
    @RibbonClient(name = "server2",configuration = RiddonRuleConfig_Productserver2.class)})