之前的文章《SpringCloud搭建注冊中心與服務注冊》介紹了注冊中心的搭建和服務的注冊,本文將介紹下服務消費者通過Ribbon調用服務實現負載均衡的過程。
本文目錄
一、Ribbon服務調用流程二、搭建注冊中心三、服務提供者四、服務消費者五、服務調用實戰
一、Ribbon服務調用流程
Ribbon是一個客戶端負載均衡器,它有幾種負載均衡機制,默認是輪詢,我們也可以自定義規則,通過合理的分配網絡請求來減小服務器的壓力。
總體流程是首先啟動注冊中心,服務提供者提供服務並注冊到注冊中心,消費者從注冊中心中獲取服務並執行。
實現服務調用需要有三個角色:服務注冊中心、服務提供者和服務消費者。
二、搭建注冊中心
首先新建一個SpringBoot項目,命名spring-cloud-eureka,然后按照下面步驟編寫代碼即可。
- pom.xml代碼
添加eureka-server的依賴,代碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類代碼
啟動類添加注解@EnableEurekaServer即可,代碼如下:
@EnableEurekaServer
@SpringBootApplication
public class SpringCloudEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudEurekaApplication.class, args);
}
}
- 配置文件
使用yml的配置文件,application.yml配置如下:
server:
port: 9001 #服務端口
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false #是否將eureka自身作為應用注冊到eureka注冊中心
fetch-registry: false #為true時,可以啟動,但報異常:Cannot execute request on any known server
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
配置項說明:
1. server.port=9001表示設置該服務注冊中心的端口號
2. eureka.instance.hostname=localhost表示設置該服務注冊中心的hostname
3. eureka.client.register-with-eureka=false,由於我們目前創建的應用是一個服務注冊中心,而不是普通的應用。默認情況下,這個應用會向注冊中心(也是它自己)注冊它自己,設置為false表示禁止這種默認行為
4. eureka.client.fetch-registry=false,表示不去檢索其他的服務,因為服務注冊中心本身的職責就是維護服務實例,它也不需要去檢索其他服務
- 運行截圖
打開瀏覽器訪問http://localhost:9001/,可以看到注冊中心以及啟動,運行截圖如下:

注冊中心運行截圖
三、服務提供者
服務注冊中心有了之后,我們可以向這個服務注冊中心注冊一個服務提供者,新建一個SpringBoot項目,命名spring-cloud-user-service,提供用戶查詢服務,然后按照下面步驟編寫代碼即可。
- pom.xml代碼
添加eureka-client的依賴,代碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類代碼
啟動類添加注解@EnableEurekaClient即可,代碼如下:
@EnableEurekaClient
@SpringBootApplication
public class UserServiceDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceDemoApplication.class, args);
}
}
添加一個提供用戶服務的UserController,代碼如下:
/**
* 用戶服務
*/
@Slf4j
@RestController
@RequestMapping("/provider")
public class UserController {
static Map<Integer, User> userMap = new HashMap<>();
static {
//模擬數據庫
User user1 = new User(1, "張三", "123456");
userMap.put(1, user1);
User user2 = new User(2, "李四", "123123");
userMap.put(2, user2);
}
/**
* 根據id 查詢
*/
@RequestMapping("/getUser")
public String getUser(Integer id) {
log.info("調用getUser接口,id={}",id);
User user = userMap.get(id);
return JSON.toJSONString(user);
}
- 配置文件
使用yml的配置文件,application.yml配置如下:
server:
port: 8100 #服務端口
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9001/eureka/
spring:
application:
name: user-service
四、服務消費者
首先新建一個SpringBoot項目,命名spring-cloud-consumer-ribbon,然后按照下面步驟編寫代碼即可。
- pom.xml代碼
添加eureka-client的依賴,代碼如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RELEASE</version><!-- eureka版本 -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 啟動類代碼
配置RestTemplate時候添加@LoadBalanced注解,就代表啟動Ribbon,進行負載均衡。
啟動類添加注解@EnableEurekaClient,也注冊到注冊中心,代碼如下:
@EnableEurekaClient
@SpringBootApplication
public class RibbonConsumerApplication {
//當添加@LoadBalanced注解,就代表啟動Ribbon,進行負載均衡
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonConsumerApplication.class, args);
}
}
- Controller代碼
添加一個Controller,用於調用服務提供者。
/**
* 消費者Controller
*/
@Slf4j
@RestController
@RequestMapping("/consumer")
public class RibbonConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private LoadBalancerClient loadBalancerClient;
/**
* 調用 user微服務
*/
@GetMapping("getUser")
public String getUser(Integer id) {
String url = "http://user-service/provider/getUser?id=" + id;
return restTemplate.getForObject(url, String.class);
}
}
- 配置文件
使用yml的配置文件,application.yml配置如下:
server:
port: 8082 #服務端口
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9001/eureka/
spring:
application:
name: user-service-consumer-ribbon
五、服務調用實戰
- 啟動服務中心並注冊服務
代碼編寫之后,按順序啟動spring-cloud-eureka、spring-cloud-user-service和spring-cloud-consumer-ribbon,先訪問注冊中心http://localhost:9001/,出現下圖說明注冊中心和兩個服務已經注冊成功。

需要注意的是為了演示負載均衡,啟動spring-cloud-user-service時候啟動兩個服務8100和8200,啟動命令如下:
java -jar spring-cloud-user-service-0.0.1-SNAPSHOT.jar --server.port=8100
java -jar spring-cloud-user-service-0.0.1-SNAPSHOT.jar --server.port=8200
- 服務調用
打開瀏覽器訪問連續訪問幾次http://localhost:8082/consumer/getUser?id=1,我們可以看到每次處理請求的者user-service實例每次都是不一樣的,這里就是客戶端負載均衡策略的體現,我把調用過程做成了gif圖片,效果如下:

調用gif圖片
到此SpringCloud通過Ribbon調用服務實現負載均衡的過程已經全部實現,有問題歡迎留言溝通哦!
完整源碼地址: https://github.com/suisui2019/springboot-study
推薦閱讀
1.SpringCloud搭建注冊中心與服務注冊
2.SpringCloud實現服務間調用(RestTemplate方式)
3.別在 Java 代碼里亂打日志了,這才是正確的打日志姿勢!
4.編碼神器Lombok,學會后開發效率至少提高一倍!
5.利用Spring Boot+zxing,生成二維碼還能這么簡單
限時領取免費Java相關資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo/Kafka、Hadoop、Hbase、Flink等高並發分布式、大數據、機器學習等技術。
關注下方公眾號即可免費領取:
