轉載請標明出處:
blog.csdn.net/forezp/arti…
本文出自方誌朋的部落格
在上一篇文章,講了服務的註冊和發現。在服務架構中,業務都會被拆分成一個獨立的服務,服務與服務的通訊是基於http restful的。Spring cloud有兩種呼叫方式,一種是ribbon+restTemplate,另一種是feign。在這一篇文章首先講解下基於ribbon+rest。
一、ribbon簡介
Ribbon is a client side load balancer which gives you a lot of control over the behaviour of HTTP and TCP clients. Feign already uses Ribbon, so if you are using @FeignClient then this section also applies.
—–摘自官網
ribbon是一個負載均衡客戶端,可以很好的控制htt和tcp的一些行為。Feign也用到ribbon,當你使用@ FeignClient,ribbon自動被應用。
ribbon 已經預設實現了這些配置bean:
-
IClientConfig ribbonClientConfig: DefaultClientConfigImpl
-
IRule ribbonRule: ZoneAvoidanceRule
-
IPing ribbonPing: NoOpPing
-
ServerList
ribbonServerList: ConfigurationBasedServerList -
ServerListFilter
ribbonServerListFilter: ZonePreferenceServerListFilter -
ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer
二、準備工作
基於上一節的工程,啟動eureka-server 工程;啟動service-hi工程,它的埠為8762;將service-hi的配置檔案的埠改為8763,並啟動它,這時你會發現:service-hi在eureka-server註冊了2個,這就相當於一個小的叢集。訪問localhost:8761如圖所示:
三、建一個服務消費者
重新新建一個spring-boot工程,取名為:service-ribbon;
它的pom.xml檔案如下:
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.forezp</groupId>
<artifactId>service-ribbon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-ribbon</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>複製程式碼
向服務註冊中心註冊一個新的服務,這時service-ribbon既是服務提供者,也是服務消費者。配置檔案application.yml如下:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: service-ribbon複製程式碼
在工程的啟動類中,通過@EnableDiscoveryClient向服務中心註冊;並且註冊了一個bean: restTemplate;通過@ LoadBalanced登錄檔明,這個restRemplate是負載均衡的。
@SpringBootApplication
@EnableDiscoveryClient
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}複製程式碼
這時我們需要測試下,建一個service類:
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
public String hiService(String name) {
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
}複製程式碼
通過restTemplate.getForObject方法,service-ribbon 就可以呼叫service-hi的方法了。並且在呼叫的工程中並之需要寫服務的名,而不是具體的ip.
寫一個controller:
/**
* Created by fangzhipeng on 2017/4/6.
*/
@RestController
public class HelloControler {
@Autowired
HelloService helloService;
@RequestMapping(value = "/hi")
public String hi(@RequestParam String name){
return helloService.hiService(name);
}
}複製程式碼
訪問http://localhost:8764/hi?name=forezp,瀏覽器交替顯示:
hi forezp,i am from port:8762
hi forezp,i am from port:8763
這說明當我們通過呼叫restTemplate.getForObject(“http://SERVICE-HI/hi?name=”+name,String.class),獲取service-hi的方法時,已經做了負載均衡,訪問了不同的埠的服務。
四、此時的架構
- 一個服務註冊中心,eureka server,埠為8761
- service-hi工程跑了兩個副本,埠分別為8762,8763,分別向服務註冊中心註冊
- sercvice-ribbon埠為8764,向服務註冊中心註冊
- 當sercvice-ribbon通過restTemplate呼叫service-hi的hi介面時,因為用ribbon進行了負載均衡,會輪流的呼叫service-hi:8762和8763 兩個埠的hi介面;
原始碼下載:github.com/forezp/Spri…
五、參考資料
本文參考了以下:
springcloud ribbon with eureka