前面已经使用Ribbon实现了路由,通过测试,也不难发现默认Ribbon使用的路由策略是轮询,可以看下源代码BaseLoadBalancer
1.全局路由配置
这种负载均衡的策略其实也是可以由用户来修改的,如果想要去修改,可以使用自定义的LoadBalance
【microcloud-consumer】 修改RestConfig
package cn.enjoy.config;
import com.netflix.loadbalancer.IRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.Base64;
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public HttpHeaders getHeaders() { // 要进行一个Http头信息配置
HttpHeaders headers = new HttpHeaders(); // 定义一个HTTP的头信息
String auth = “root:enjoy”; // 认证的原始信息
byte[] encodedAuth = Base64.getEncoder()
.encode(auth.getBytes(Charset.forName(“US-ASCII”))); // 进行一个加密的处理
String authHeader = “Basic “ + new String(encodedAuth);
headers.set(“Authorization”, authHeader);
return headers;
}
@Bean
public IRule ribbonRule() { // 其中IRule就是所有规则的标准
return new com.netflix.loadbalancer.RandomRule(); // 随机的访问策略
}
}
这个时候重启测试发现,默认的路由规则已经变成了随机
2.单独设置某个Ribbon的路由
有时候,某个消费者可能需要访问多个多个服务提供方,而希望每个服务提供方提供的路由规则并不相同,这个时候就不能让Spring扫描到IRULE,需要通过@RibbonClient 来指定服务于配置的关系
【microcloud-consumer】 修改RestConfig,删除IRULE
package cn.enjoy.config;
import com.netflix.loadbalancer.IRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.Base64;
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public HttpHeaders getHeaders() { // 要进行一个Http头信息配置
HttpHeaders headers = new HttpHeaders(); // 定义一个HTTP的头信息
String auth = “root:enjoy”; // 认证的原始信息
byte[] encodedAuth = Base64.getEncoder()
.encode(auth.getBytes(Charset.forName(“US-ASCII”))); // 进行一个加密的处理
String authHeader = “Basic “ + new String(encodedAuth);
headers.set(“Authorization”, authHeader);
return headers;
}
~~ @Bean public IRule ribbonRule() { // 其中IRule就是所有规则的标准 return new com.netflix.loadbalancer.RandomRule(); // 随机的访问策略 }~~
}
【microcloud-consumer】新增一个路由规则的配置类,注意这个类不应该放到SpringCloud扫描不到的位置,否则又回变成全局的IRULE,所以这个时候应该单独使用一个新的包,着个包和启动并不在同一个包下
package cn.xiangxue.config;
import com.netflix.loadbalancer.IRule;
import org.springframework.context.annotation.Bean;
public class RibbonConfig {
@Bean
public IRule ribbonRule() { // 其中IRule就是所有规则的标准
return new com.netflix.loadbalancer.RandomRule(); // 随机的访问策略
}
}
【microcloud-consumer】 修改启动类,使用@RibbonClient指定配置类
package cn.enjoy;
import cn.xiangxue.config.RibbonConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name =”MICROCLOUD-PROVIDER-PRODUCT” ,configuration = RibbonConfig.class)
public class ConsumerApp {
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class,args);
}
}
这里的name 只服务的名称,如果需要有多个服务提供方,这个时候可以使用@RibbonClients进行配置
3.服务提供方的信息获取
在服务的消费方,也是可以获取到服务提供方的具体信息
【microcloud-consumer】修改ConsumerProductController
package cn.enjoy.controller;
import cn.enjoy.vo.Product;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping(“/consumer”)
public class ConsumerProductController {
public static final String PRODUCT_GET_URL = “http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/get/“;
public static final String PRODUCT_LIST_URL=”http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/list/“;
public static final String PRODUCT_ADD_URL = “http://MICROCLOUD-PROVIDER-PRODUCT/prodcut/add/“;
@Resource
private RestTemplate restTemplate;
@Resource
private HttpHeaders httpHeaders;
@Resource
private LoadBalancerClient loadBalancerClient;
@RequestMapping(“/product/get”)
public Object getProduct(long id) {
Product product = restTemplate.exchange(PRODUCT_GET_URL + id,HttpMethod.GET,new HttpEntity