image.png
1.創建項目ribbon-consumer
2.添加pom依賴eureka、ribbon、boot
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-cloud-demo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<name>ribbon-consumer</name>
<artifactId>ribbon-consumer</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
4.創建啟動類
ribbon的精華在哪里?
package com.imooc.springcloud;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {
// 精華所在
@Bean
@LoadBalanced
public RestTemplate template() {
return new RestTemplate();
}
public static void main(String[] args) {
new SpringApplicationBuilder(RibbonConsumerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
5.創建Controller
沒有引入Ribbon前如何使用RestTemplate來發送請求?
- RestTemplate
- LoadBalancerClient
- client.choose("eureka-client")
啟動類:
package com.imooc.springcloud;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class EurekaConsumerApplication {
/*
* @Bean注解,spring會在初始化的時候會把這個方法加入到上下文,然后我們就可以在Controller里得到這個方法了
* */
@Bean
public RestTemplate register(){
return new RestTemplate();
}
public static void main(String[] args) {
new SpringApplicationBuilder(EurekaConsumerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
controller:
package com.imooc.springcloud;
import lombok.extern.slf4j.Slf4j;
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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@Slf4j
@RestController
public class Controller {
/*
* 負載均衡器,幫我們從注冊中心拉取的服務列表中挑選一個可用的serviceprovider
* */
@Autowired
private LoadBalancerClient client;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello")
public String hello(){
/*
* 1.拿到服務提供者的實例
* 2.借助RestTemplate發起真實的服務調用
* 3.單獨聲明RestTemplate
* */
ServiceInstance instance = client.choose("eureka-client");
/*
* 防疫性編程:假定所有的輸入都是不安全的,instance可能get到空
* */
if (instance == null) {
return "No aviliable instance";
}
String target = String.format("http://%s:%s/sayHi",instance.getHost(),instance.getPort());
log.info("url is {}",target);
return restTemplate.getForObject(target, String.class);
}
@PostMapping("/hello")
public Friend helloPost(){
/*
* 1.拿到服務提供者的實例
* 2.借助RestTemplate發起真實的服務調用
* 3.單獨聲明RestTemplate
* 4.啟動順序:啟動注冊中心->服務提供者->服務消費者
* */
ServiceInstance instance = client.choose("eureka-client");
/*
* 防疫性編程:假定所有的輸入都是不安全的,instance可能get到空
* */
if (instance == null) {
return null;
}
String target = String.format("http://%s:%s/sayHi",instance.getHost(),instance.getPort());
log.info("url is {}",target);
Friend friend = new Friend();
friend.setName("eureka-consumer");
return restTemplate.postForObject(target, friend,Friend.class);
}
}
引入Ribbon如何使用RestTemplate來發送請求?
啟動類:
package com.imooc.springcloud;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonConsumerApplication {
// 精華所在
@Bean
@LoadBalanced
public RestTemplate template() {
return new RestTemplate();
}
public static void main(String[] args) {
new SpringApplicationBuilder(RibbonConsumerApplication.class)
.web(WebApplicationType.SERVLET)
.run(args);
}
}
controller:
package com.imooc.springcloud;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class Controller {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/sayHi")
public String sayHi() {
return restTemplate.getForObject(
"http://eureka-client/sayHi",
String.class);
}
}
5.Ribbon application.properties的書寫步驟?
1.name
2.port
3.serviceUrl
6.要做幾件事情?
1.啟動eureka-server
2.啟動2個eureka-client
3.啟動ribbon-consumer
4.看3個服務是否都在注冊中心上
5.調用ribbon-consumer方法(或調用eureka-server的eureka-client方法?),看會不會輪訓調用eureka-client,看ribbon服務負載均衡是否生效了
6.遇到哪些問題?
負載均衡沒有起到作用
原因:2個eureka-client的name名稱不一致導致的
eureka-server報連接超時錯誤:
解決:pom加eureka.client.serviceUrl.defaultZone=http://localhost:20000/eureka/