上次介绍了《SpringCloud踩坑笔记 | 简单的注册中心集群》,今天在上一次的基础上来简单的看下服务消费,学习如何去消费服务提供者的接口。
服务提供者添加方法
服务提供者(eureka-client)的DcController添加一个接口:
@GetMapping("/test")
public String test() {
return "eureka-client8001 test ok.";
}
首先导入依赖
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-eureka
1.3.1.RELEASE
添加配置
spring.application.name=eureka-consumer
server.port=6001
#不注册自己
eureka.client.register-with-eureka=false
eureka.client.serviceUrl.defaultZone=http://localhost7001:7001/eureka/,http://localhost7002:7002/eureka/
创建测试类\配置类\启动类
@RestController
public class ServiceController {
private static String http_url = "http://localhost:8001";
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String consumer() {
String url = http_url + "/test";
System.out.println("eureka consumer --> "+ url);
return restTemplate.getForObject(url, String.class);
}
}
@Configuration
public class ConfigBean {
@Bean
public RestTemplate getRestTempalte(){
return new RestTemplate();
}
}
@SpringBootApplication
@EnableDiscoveryClient
public class Consumer01 {
public static void main(String[] args) {
SpringApplication.run(Consumer01.class, args);
}
}
依次运行eureka-server、eureka-client、eureka-consumer,浏览器中输入http://localhost:6001/consumer 即可看到调用了getService方法。
来看RestTemplate的源码,其实就是个HTTP远程调用:
我们可以看出来这样调用十分的繁琐,还需要手动拼接地址,不是特别好,我们来看看Ribbon是怎么做的
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP/TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。 Ribbon是进程式(LB)负载均衡,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。
导入Ribbon依赖
在上述工程中导入Ribbon依赖,不需要重新创建工程
org.springframework.cloud
spring-cloud-starter-ribbon
1.4.7.RELEASE
修改eureka-consumer中的ConfigBean
@Bean
@LoadBalanced //开启了负载均衡
public RestTemplate getRestTempalte(){
return new RestTemplate();
}
修改eureka-consumer中的ServiceController类:
@RestController
public class ServiceController {
private static String http_url = "http://eureka-client";
@Autowired
RestTemplate restTemplate;
@GetMapping("/consumer")
public String consumer2() {
String url = http_url + "/test";
System.out.println("eureka consumer --> "+ url);
return restTemplate.getForObject(url, String.class);
}
}
浏览器运行http://localhost:6001/consumer即可调用eureka-client中的方法。
可以看出只需要服务名称就可以,不需要域名和端口
此时负载均衡不明显,我们再创建一个服务提供者,和eureka-client8001一样的
DcController只保留test接口
@GetMapping("/test")
public String test() {
return "eureka-client8002 test ok.";
}
修改启动类和配置文件:
spring.application.name=eureka-client
server.port=8002
eureka.instance.instance-id=springcloud-client8002
eureka.client.service-url.defaultZone=http://localhost7001:7001/eureka/,http://localhost7002:7002/eureka/
info.compay.name=iFillDream
info.auth.name=RickSun
注意服务提供者的spring.application.name要一样
依次启动eureka-server7001、eureka-server7002、eureka-client8001、eureka-client8002、eureka-consumer
浏览器运行http://localhost:6001/consumer即可调用eureka-client中的方法。效果就是以下两种结果顺序出现即轮询
第一种结果:eureka-client8001 test ok.
第二种结果:eureka-client8002 test ok.
在消费者eureka-consumer中的CofingBean中开启了负载均衡即@LoadBalanced注解
从IRule接口源码中我们可以看到负载的几种方式:
1.RoundRobinRule-轮询(默认)
2.AvailabilityFilteringRule-根据服务是否死掉或者服务处于高并发来分配权重
3.RandomRule-随机访问
4.RetryRule-轮询后如果获取失败,则在指定时间内重试
……
那么如何更换负载均衡的规则呢?以随机规则举例
在eureka-consumer的ConfigBean中添加配置:
@Bean
public IRule myRule(){
return new RandomRule();
}
重启eureka-consumer后运行效果就是随机访问服务提供者了~
可以看出这里还是使用了自带的几种方式,那么如何自定义呢?
先删掉上述的myRule()配置;
自定义的不允许出现在主程序上下文@ComponentScan中,需要放在不重复的包中
在eureka-consumer主程序的上一级包目录中创建ruleconfig包,再创建MyRule配置类:
/**
* 自定义负载均衡规则
* 每个服务调用5次,5次后轮询下一个服务
* @author RickSun && iFillDream
*/
@Configuration
public class MyRule extends AbstractLoadBalancerRule {
private int count = 0;//调用次数
private int currentIndex = 0;//当前服务下标
@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
//所有存活的服务
List upList = lb.getReachableServers();
//所有服务
List allList = lb.getAllServers();
//所有服务的总数
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
if(count < 5){
count++;
server = upList.get(currentIndex);
}else {
count = 0;
currentIndex++;
if (currentIndex >= serverCount){
currentIndex = 0;
}
}
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
在eureka-consumer的main方法上添加以下注解:
@RibbonClient(name="eureka-client",configuration = MyRule.class)
重启eureka-consumer后运行效果就是自定义的负载均衡的规则了~
以上就是ribbon的基础教程了