1. 程式人生 > >Spring Cloud Ribbon--智慧路由

Spring Cloud Ribbon--智慧路由

一、Ribbon負載均衡

還是先通過一個demo直觀的體驗一下spring cloud Ribbon負載均衡技能

1、引入pom依賴

<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.3.5.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-ribbon</artifactId>
		</dependency>

	<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-hystrix</artifactId>
	</dependency>

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</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>
2、編寫服務消費業務類ConsumerController
@RestController
public class ConsumerController {

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping(value = "/add", method = RequestMethod.GET)
    public String add() {
        return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
    }
}
3、編寫啟動類
@SpringBootApplication
@EnableDiscoveryClient
public class RibbonApplication {

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
    }
}
4、新增properties配置檔案
spring.application.name=ribbon-consumer
server.port=3333

eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
啟動RibbonApplication main方法後,重新整理Eureka監控平臺,可見除去上文已註冊到Eureka上的兩個compute-service例項之外,還添加了當前ribbon-consumer服務。


5、演示Ribbon負載均衡功能

訪問http://localhost:3333/add ,呼叫compute-service服務的add方法,執行http://COMPUTE-SERVICE/add?a=10&b=20,訪問兩次,可見compute-service服務1控制檯打印出1次呼叫資訊,compute-service服務1打印出第二次呼叫資訊,表明兩次呼叫均發到了兩個不同的服務例項。這就是ribbon提供的服務智慧路由、負載均衡功能。

二、How does Ribbonwork?

在RibbonApplication類中,@LoadBalanced註解就是實現服務智慧路由的關鍵,通過檢視@LoadBalanced原始碼,發現該註解用於標記一個RestTemplate bean,並使用LoadBalancerClient來配置它。LoadBalancerClient便是Ribbon實現負載均衡的關鍵入口

/**
 * Annotation to mark a RestTemplate bean to be configured to use a LoadBalancerClient
 * @author Spencer Gibb
 */
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {
}
LoadBalancerClient介面原始碼如下
public interface LoadBalancerClient {
	/**
	 * Choose a ServiceInstance from the LoadBalancer for the specified service
	 * @param serviceId the service id to look up the LoadBalancer
	 * @return a ServiceInstance that matches the serviceId
	 */
	ServiceInstance choose(String serviceId);//根據傳入的服務名serviceId,從負載均衡器中挑選一個對應服務的例項。

	/**
	 * execute request using a ServiceInstance from the LoadBalancer for the specified
	 * service
	 * @param serviceId the service id to look up the LoadBalancer
	 * @param request allows implementations to execute pre and post actions such as
	 * incrementing metrics
	 * @return the result of the LoadBalancerRequest callback on the selected
	 * ServiceInstance
	 */
	<T> T execute(String serviceId, LoadBalancerRequest<T> request) throws IOException;
//使用從負載均衡器中挑選出的服務例項來執行請求內容。
	/**
	 * Create a proper URI with a real host and port for systems to utilize.
	 * Some systems use a URI with the logical serivce name as the host,
	 * such as http://myservice/path/to/service.  This will replace the
	 * service name with the host:port from the ServiceInstance.
	 * @param instance
	 * @param original a URI with the host as a logical service name
	 * @return a reconstructed URI
	 */
	URI reconstructURI(ServiceInstance instance, URI original);
//
}
大致流程如下:通過LoadBalancerInterceptor攔截器對RestTemplate的請求進行攔截,並利用Spring Cloud的負載均衡器LoadBalancerClient將以邏輯服務名為host的URI轉換成具體的服務例項的過程。

三、Ribbon負載均衡策略