Spring Cloud Ribbon--智慧路由
阿新 • • 發佈:2018-12-24
一、Ribbon負載均衡
還是先通過一個demo直觀的體驗一下spring cloud Ribbon負載均衡技能
1、引入pom依賴
2、編寫服務消費業務類ConsumerController<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>
3、編寫啟動類@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(); } }
4、新增properties配置檔案@SpringBootApplication @EnableDiscoveryClient public class RibbonApplication { @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } public static void main(String[] args) { SpringApplication.run(RibbonApplication.class, args); } }
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負載均衡策略