
1、引言
剛學習Java時,我們編寫的程序,運行時只有一個進程,這種程序就是我們常說的「單體架構」,最典型的單體架構圖如下:

單體架構的軟體,我們可以認為是沒有架構的。
軟體的架構,從單體架構,發展到垂直多程序架構、分散式架構、SOA架構,一路狂奔,到了現在的微服務架構。
雖然我們推崇微服務架構,但客觀地說,單體架構依然盛行,包括很多比較大的軟體,就是用單體架構來開發的,發布時也只有一個可執行程序。
單體架構之所以盛行,是因為採用其他架構時,我們除了實現業務功能,還要實現架構,例如模塊之間的相互調用,這些都很複雜。
當我們使用SpringCloud開發微服務架構的軟體時,會發現事情變得很輕鬆。我們可以方便地對軟體的處理能力擴容,可以用Eureka和Ribbon,實現模塊之間基於RESTful的相互調用。
說了這麼多理論,估計讀者都有點煩了,還是直接上代碼吧。
2、建立Eureka伺服器和Eureka客戶端
在上一講《Java第66講——微服務之Eureka》文章中,詳細介紹了如何建立Eureka伺服器和Eureka客戶端,大家可以參考,因此這裡不再贅述。
我們建立的Eureka伺服器的信息如下:
模塊名稱:register
監聽埠:8800
註冊url:http://localhost:8800/eureka/Eureka客戶端將會啟動三個實例,其信息如下:
模塊名稱:producer
監聽埠:三個實例監聽的埠分別為9901,9902,9903
應用名稱:service-producer這些信息與《Java第66講——微服務之Eureka》文章中實現的代碼完全一致。
從名稱來看,register是註冊中心,producer是生產者,此次開發,將增加一個消費者consumer,獲得producer提供的服務:

3、Ribbon功能介紹
Ribbon是一個用來實現負載均衡的組件。
當我們有多個producer處於運行狀態時,consumer可以根據負載情況,獲得其中一個producer,然後進行調用。
使用Ribbon,我們可以根據系統當前的負載情況,決定增加或者減少producer數量。
通過Ribbon,我們輕鬆地實現了集群的能力。
4、在producer中增加一個CallController類
在producer中增加一個CallController類,用於提供服務,該類的代碼如下:
package com.flying.producer.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class CallController {
@Value("${server.port}")
private int thePort;
@RequestMapping("/call_me")
private String callMe(@RequestParam(value = "name") String caller){
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("Service of port ").append(thePort).append(" is called by ").append(caller);
return stringBuffer.toString();
}
}5、新增一個模塊consumer
新增consumer模塊的過程如下:
第1步:建立consumer模塊,使用了Lombok、Spring Web、Eureka Discovery Client依賴:

第2步:修改consumer模塊的pom.xml文件,添加對Ribbon的依賴:
<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.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.7.RELEASE</version>
</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>第3步:編輯入口類ConsumerApplication,添加對Eureka的使用:
package com.flying.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}第4步:創建一個生成RestTemplate對象的類RestTemplateCreator,加上對Ribbon的使用:
package com.flying.consumer.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 RestTemplateCreator {
@LoadBalanced
@Bean
RestTemplate getRestTemplate(){
return new RestTemplate();
}
}第5步:創建一個業務類CallerService,使用RestTemplate實現對producer的調用:
package com.flying.consumer.biz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class CallerService {
@Autowired
RestTemplate restTemplate;
public String callProducer(){
return restTemplate.getForObject("http://SERVICE-PRODUCER/call_me?name=consumer", String.class);
}
}第6步:為了便於測試,添加一個測試類TestController:
package com.flying.consumer.controller;
import com.flying.consumer.biz.CallerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TestController {
@Autowired
private CallerService callerService;
@GetMapping("/call_test")
public String testByExplorer(){
return callerService.callProducer();
}
}第7步:修改application.properties文件,配置監聽埠為10000,以及Erueka伺服器的url:
server.port=10000
eureka.client.serviceUrl.defaultZone=http://localhost:8800/eureka/
spring.application.name=service-consumer代碼編寫完成了,現在準備進行測試。
6、執行測試
第1步:在Linux下建立consumer、producer1、producer2、producer3、register四個目錄;

第2步:將軟體傳入到對應的目錄,其中,producer軟體同時傳入producer1、producer2、producer3三個目錄:

第3步:修改application.properties發文件,修改producer的監聽埠:
producer1:監聽9901
producer2:監聽9902
producer3:監聽9903
第4步:啟動consumer、producer1、producer2、producer3、register;

第5步:查詢register的監控頁面,可以看到四個客戶端註冊進來了:

第6步:多次查看consumer提供的Web功能,會發現每次調用的producer並不是同一個。
這是第一次測試時顯示的web頁面:

刷新頁面,顯示的web頁面為:

刷新兩次頁面後,顯示了下面的web頁面:

不敢想像,沒有編寫多少代碼,藉助於Spring Cloud,竟然輕鬆地實現了集群功能,實現了負載均衡功能!

原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/280048.html
微信掃一掃
支付寶掃一掃