1. 上章節回顧
上一篇文章, 我們已經搭起來了註冊中心,和服務提供者, 現在就來講下消費者調用方法
與Dubbo的Rpc調用方式不同, Spring cloud有兩種服務調用方式,一種是ribbon+restTemplate,另一種是feign。
2. Ribbon
ribbon是一個負載均衡客戶端,可以很好的控制http和tcp的一些行爲。Feign默認集成了ribbon。
3. 建一個消費者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>
<packaging>jar</packaging>
<artifactId>service-ribbon</artifactId>
<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>
同樣的, 配置application.yml,以及SpringBoot的啓動類
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8085
spring:
application:
name: service-ribbon
這裏的defaultZone,是上篇文章創建的eurekaServer
的url地址
啓動類
這裏的
@EnableDiscoveryClient
表示client在eureka註冊中心註冊,其實@EnableEurekaClient
註解就包含了@EnableDiscoveryClient
的作用, 也就是當註冊中心爲Eureka時的一個特例情況下使用, 但是@EnableDiscoveryClient
在使用其他註冊中心也可以使用
package com.zgd.springcloud.eurekaClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* eureka client 客戶端
*/
@EnableDiscoveryClient
@EnableEurekaClient
@SpringBootApplication
public class RibbonApp {
public static void main(String[] args) {
SpringApplication.run(RibbonApp.class, args);
}
/**
* 使用restTemplate消費方法
* @return
* @LoadBalanced 負載均衡
*/
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
這裏再restTemplate的構造方法上增加一個@LoadBalanced
註解表示負載均衡
寫一個service
package com.zgd.springcloud.eurekaClient.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class HelloService {
/**
* 用來訪問其他mvc路由,獲得遠程方法執行後的值
*/
@Autowired
RestTemplate restTemplate;
public String hiService(String name) {
//eureka-client-01工程的applicationName
String client01Name = "client01";
//eureka-client-01工程的ProducerController的hello方法的路由
String prefix = "hello";
//訪問eureka-client-01的路由,遠程調用eureka-client-01的方法
return restTemplate.getForObject("http://" + client01Name + "/" + prefix + "?name=" + name, String.class);
}
}
寫一個controller調用service
package com.zgd.springcloud.eurekaClient.controller;
import com.zgd.springcloud.eurekaClient.service.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RibbonController {
@Autowired
HelloService helloService;
/**
* 通過service層,用restTemplate訪問Client01路由,間接調用了Client01工程的方法
* @param name
* @return
*/
@GetMapping(value = "/getHi")
public String getHello(@RequestParam String name) {
return helloService.hiService( name );
}
}
4. 啓動eurekaServer
5. 啓動eureka-client-01
啓動eureka-client-01, 然後在Idea的啓動配置edit Configurations…中的右上角,有一個Single instance only,把它的勾去掉,就可以一個工程啓動多個實例了
更改eureka-client-01的端口, 再啓動
這樣就相當於是一個集羣, 同樣的工程名和路由,有兩個端口服務
http://localhost:8085/getHi?name=zgd
重複點擊
負載均衡實現
5. 簡單總結
其實就是client先在eurekaServer上註冊,暴露的其實是controller層的路由地址
然後我們啓動消費者service-ribbon, 我們普通的調用service-ribbon的controlled的getHello
方法, 然後controller調用service層,service層通過restTemplate
調用 client的controller層的路由地址
,只不過這裏client的ip,換成了他在eurekaServer註冊的名字,也就是在application.yml中的spring.application.name
6. 源碼
https://github.com/zzzgd/SpringCloudDemo/tree/master/spring-cloud-part1