Spring-Cloud-Ribbon學習筆記(一):入門
阿新 • • 發佈:2019-02-25
instance pub auto pom.xml forname 註冊 yml 中心 有一個
簡介
Spring Cloud Ribbon是一個基於Http和TCP的客戶端負載均衡工具,它是基於Netflix Ribbon實現的。它不像服務註冊中心、配置中心、API網關那樣獨立部署,但是它幾乎存在於每個微服務的基礎設施中。理解Ribbon對於我們使用Spring Cloud來講非常的重要,因為負載均衡是對系統的高可用、網絡壓力的緩解和處理能力擴容的重要手段之一。
在Spring Cloud中,有兩種服務調用方式,一種是Ribbon+RestTemplate,另一種是Feign。文本先講解下基於Ribbon+RestTemplate的用法。
當Ribbon與Eureka配合使用時,Ribbon可自動從Eureka Server獲取服務提供者地址列表,並基於負載均衡算法,請求其中一個服務提供者實例。
實現
新建服務spring-cloud-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.yan</groupId> <artifactId>spring-cloud-ribbon</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> <relativePath/> </parent> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>RELEASE</version> </dependency> </dependencies> </project>
配置
yml
server:
port: 8004
spring:
application:
name: spring-cloud-ribbon
cloud:
config:
discovery:
enabled: true
service-id: spring-cloud-config-server
profiles:
active: dev
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
啟動類
核心是配有註解@LoadBalanced
的RestTemplate的Bean配置
package com.yan;
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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
@Configuration
@EnableDiscoveryClient
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Controller
package com.yan.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.StringJoiner;
@RestController
@RequestMapping("/ribbon")
public class RibbonController {
private final RestTemplate template;
@Autowired
public RibbonController(RestTemplate template) {
this.template = template;
}
@GetMapping("/get")
public Object get(String svcName, String url, String className) {
Class<?> clazz = getResponseType(className);
String uri = getUrl(svcName, url);
return template.getForObject(uri, clazz);
}
@PostMapping("/post")
public Object post(@RequestParam String svcName, @RequestParam String url, @RequestParam String className, @RequestBody HttpEntity<Object> httpEntity) {
Class<?> clazz = getResponseType(className);
String url1 = getUrl(svcName, url);
return template.postForObject(url1, httpEntity, clazz);
}
private Class<?> getResponseType(@RequestParam String className) {
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
clazz = String.class;
}
return clazz;
}
private String getUrl(String svcName, String url) {
StringJoiner stringJoiner = new StringJoiner("/");
String uri = stringJoiner.add(svcName).add(url).toString().replaceAll("/+", "/");
return "http://" + uri;
}
}
測試
假如我有兩個名叫svcA的服務,同時註冊到同一個Eureka上,只是端口號不同,它們都有一個post接口定義如下:
@PostMapping("/post/{name}")
public String post(@PathVariable String name, @RequestBody String type) {
return “name:” + name + “\ntype:” + type;
}
打開Postman:
發送請求:http://localhost:8004/ribbon/post?svcName=SVCA&url=/post/xixi&className=java.lang.String
Header:{‘Content-Type‘: ‘application/json‘}
Body: {‘raw‘: {
{
"headers": {"Content-Type": ["application/json"]},
"body": "haha"
}
}}
此時正確返回結果:
name:xixi
type:haha
Spring-Cloud-Ribbon學習筆記(一):入門